Skip to content

Commit

Permalink
Bug 1657291 - Replace UrlbarPrefsObserver with an ordered list of wea…
Browse files Browse the repository at this point in the history
…k observers internal to UrlbarPrefs. r=harry

Differential Revision: https://phabricator.services.mozilla.com/D85971
  • Loading branch information
0c0w3 committed Aug 5, 2020
1 parent 534b2e3 commit 28aa9a4
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 64 deletions.
92 changes: 49 additions & 43 deletions browser/components/urlbar/UrlbarPrefs.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,16 @@ class Preferences {
*/
constructor() {
this._map = new Map();
this._observer = new UrlbarPrefsObserver(pref => this._onPrefChanged(pref));
this.QueryInterface = ChromeUtils.generateQI([
"nsIObserver",
"nsISupportsWeakReference",
]);
Services.prefs.addObserver(PREF_URLBAR_BRANCH, this, true);
for (let pref of PREF_OTHER_DEFAULTS.keys()) {
Services.prefs.addObserver(pref, this, true);
}
this._observerWeakRefs = [];
this.addObserver(this);
}

/**
Expand Down Expand Up @@ -271,14 +280,52 @@ class Preferences {
setter(pref, value);
}

/**
* Adds a preference observer. Observers are held weakly.
*
* @param {object} observer
* An object that must have a method named `onPrefChanged`, which will
* be called when a urlbar preference changes. It will be passed the
* pref name. For prefs in the `browser.urlbar.` branch, the name will
* be relative to the branch. For other prefs, the name will be the
* full name.
*/
addObserver(observer) {
this._observerWeakRefs.push(Cu.getWeakReference(observer));
}

/**
* Observes preference changes.
*
* @param {nsISupports} subject
* @param {string} topic
* @param {string} data
*/
observe(subject, topic, data) {
let pref = data.replace(PREF_URLBAR_BRANCH, "");
if (!PREF_URLBAR_DEFAULTS.has(pref) && !PREF_OTHER_DEFAULTS.has(pref)) {
return;
}
for (let i = 0; i < this._observerWeakRefs.length; ) {
let observer = this._observerWeakRefs[i].get();
if (!observer) {
// The observer has been GC'ed, so remove it from our list.
this._observerWeakRefs.splice(i, 1);
} else {
observer.onPrefChanged(pref);
++i;
}
}
}

/**
* Called when a pref tracked by UrlbarPrefs changes.
*
* @param {string} pref
* The name of the pref, relative to `browser.urlbar.` if the pref is
* in that branch.
*/
_onPrefChanged(pref) {
onPrefChanged(pref) {
this._map.delete(pref);
// Some prefs may influence others.
if (pref == "matchBuckets") {
Expand Down Expand Up @@ -403,45 +450,4 @@ class Preferences {
}
}

/**
* A weak preferences observer. You must hold on to instances of this class
* because otherwise they will be garbage collected.
*/
class UrlbarPrefsObserver {
/**
* Constructor.
*
* @param {function} callback
* Called when a urlbar preference changes. It will be passed the pref
* name. For prefs in the `browser.urlbar.` branch, the name will be
* relative to the branch. For other prefs, the name will be the full name.
*/
constructor(callback) {
this._callback = callback;
this.QueryInterface = ChromeUtils.generateQI([
"nsIObserver",
"nsISupportsWeakReference",
]);
Services.prefs.addObserver(PREF_URLBAR_BRANCH, this, true);
for (let pref of PREF_OTHER_DEFAULTS.keys()) {
Services.prefs.addObserver(pref, this, true);
}
}

/**
* Observes preference changes.
*
* @param {nsISupports} subject
* @param {string} topic
* @param {string} data
*/
observe(subject, topic, data) {
let pref = data.replace(PREF_URLBAR_BRANCH, "");
if (!PREF_URLBAR_DEFAULTS.has(pref) && !PREF_OTHER_DEFAULTS.has(pref)) {
return;
}
this._callback(pref);
}
}

var UrlbarPrefs = new Preferences();
39 changes: 18 additions & 21 deletions browser/components/urlbar/UrlbarSearchOneOffs.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const { XPCOMUtils } = ChromeUtils.import(
XPCOMUtils.defineLazyModuleGetters(this, {
SearchOneOffs: "resource:///modules/SearchOneOffs.jsm",
UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
UrlbarPrefsObserver: "resource:///modules/UrlbarPrefs.jsm",
UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
Expand Down Expand Up @@ -57,9 +56,7 @@ class UrlbarSearchOneOffs extends SearchOneOffs {
super(view.panel.querySelector(".search-one-offs"));
this.view = view;
this.input = view.input;
this._prefObserver = new UrlbarPrefsObserver(pref =>
this._onPrefChanged(pref)
);
UrlbarPrefs.addObserver(this);
}

/**
Expand Down Expand Up @@ -194,6 +191,23 @@ class UrlbarSearchOneOffs extends SearchOneOffs {
);
}

/**
* Called when a pref tracked by UrlbarPrefs changes.
*
* @param {string} changedPref
* The name of the pref, relative to `browser.urlbar.` if the pref is in
* that branch.
*/
onPrefChanged(changedPref) {
// Null out this._engines when the local-one-offs-related prefs change so
// that they rebuild themselves the next time the view opens.
let prefs = [...LOCAL_MODES.values()].map(({ pref }) => pref);
prefs.push("update2", "update2.localOneOffs", "update2.oneOffsRefresh");
if (prefs.includes(changedPref)) {
this._engines = null;
}
}

/**
* Overrides _rebuildEngineList to add the local one-offs.
*
Expand Down Expand Up @@ -251,21 +265,4 @@ class UrlbarSearchOneOffs extends SearchOneOffs {

this.handleSearchCommand(event, engineOrSource);
}

/**
* Called when a pref tracked by UrlbarPrefs changes.
*
* @param {string} changedPref
* The name of the pref, relative to `browser.urlbar.` if the pref is in
* that branch.
*/
_onPrefChanged(changedPref) {
// Null out this._engines when the local-one-offs-related prefs change so
// that they rebuild themselves the next time the view opens.
let prefs = [...LOCAL_MODES.values()].map(({ pref }) => pref);
prefs.push("update2", "update2.localOneOffs", "update2.oneOffsRefresh");
if (prefs.includes(changedPref)) {
this._engines = null;
}
}
}

0 comments on commit 28aa9a4

Please sign in to comment.