summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/URLDecorationAnnotationsService.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/antitracking/URLDecorationAnnotationsService.sys.mjs')
-rw-r--r--toolkit/components/antitracking/URLDecorationAnnotationsService.sys.mjs70
1 files changed, 70 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/URLDecorationAnnotationsService.sys.mjs b/toolkit/components/antitracking/URLDecorationAnnotationsService.sys.mjs
new file mode 100644
index 0000000000..ca285e972d
--- /dev/null
+++ b/toolkit/components/antitracking/URLDecorationAnnotationsService.sys.mjs
@@ -0,0 +1,70 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+export function URLDecorationAnnotationsService() {}
+
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
+});
+
+const COLLECTION_NAME = "anti-tracking-url-decoration";
+const PREF_NAME = "privacy.restrict3rdpartystorage.url_decorations";
+
+URLDecorationAnnotationsService.prototype = {
+ classID: Components.ID("{5874af6d-5719-4e1b-b155-ef4eae7fcb32}"),
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIObserver",
+ "nsIURLDecorationAnnotationsService",
+ ]),
+
+ _initialized: false,
+ _prefBranch: null,
+
+ onDataAvailable(entries) {
+ // Use this technique in order to ensure the pref cannot be changed by the
+ // user e.g. through about:config. This preferences is only intended as a
+ // mechanism for reflecting this data to content processes.
+ if (this._prefBranch === null) {
+ this._prefBranch = Services.prefs.getDefaultBranch("");
+ }
+
+ const branch = this._prefBranch;
+ branch.unlockPref(PREF_NAME);
+ branch.setStringPref(
+ PREF_NAME,
+ entries.map(x => x.token.replace(/ /, "%20")).join(" ")
+ );
+ branch.lockPref(PREF_NAME);
+ },
+
+ observe(aSubject, aTopic, aData) {
+ if (aTopic == "profile-after-change") {
+ this.ensureUpdated();
+ }
+ },
+
+ ensureUpdated() {
+ if (this._initialized) {
+ return Promise.resolve();
+ }
+ this._initialized = true;
+
+ const client = lazy.RemoteSettings(COLLECTION_NAME);
+ client.on("sync", event => {
+ let {
+ data: { current },
+ } = event;
+ this.onDataAvailable(current);
+ });
+
+ // Now trigger an update from the server if necessary to get a fresh copy
+ // of the data
+ return client.get({}).then(entries => {
+ this.onDataAvailable(entries);
+ return undefined;
+ });
+ },
+};