commit 36d8a4108e1f0be382e56a30894f0355b9c36ed1
parent a7b1b356be396377b98cf8511a15ab2a82af6823
Author: Meg Viar <lmegviar@gmail.com>
Date: Tue, 30 Sep 2025 15:50:54 +0000
Bug 1990947 - Allow changes to any of a list of prefs to dismiss an infobar r=omc-reviewers,jprickett
Differential Revision: https://phabricator.services.mozilla.com/D266249
Diffstat:
4 files changed, 96 insertions(+), 20 deletions(-)
diff --git a/browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json b/browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json
@@ -646,8 +646,20 @@
"type": "boolean"
},
"dismissOnPrefChange": {
- "description": "If set, the name of a pref to observe. The infobar will automatically dismiss when this pref is set for the first time or when its value changes.",
- "type": "string"
+ "description": "If set, one or more prefs to observe. The infobar will automatically dismiss when any of these prefs is set for the first time or when its value changes.",
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ ]
},
"impression_action": {
"oneOf": [
diff --git a/browser/components/asrouter/content-src/templates/CFR/templates/InfoBar.schema.json b/browser/components/asrouter/content-src/templates/CFR/templates/InfoBar.schema.json
@@ -81,8 +81,16 @@
"type": "boolean"
},
"dismissOnPrefChange": {
- "description": "If set, the name of a pref to observe. The infobar will automatically dismiss when this pref is set for the first time or when its value changes.",
- "type": "string"
+ "description": "If set, one or more prefs to observe. The infobar will automatically dismiss when any of these prefs is set for the first time or when its value changes.",
+ "oneOf": [
+ { "type": "string" },
+ {
+ "type": "array",
+ "items": { "type": "string" },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ ]
},
"impression_action": {
"oneOf": [
diff --git a/browser/components/asrouter/modules/InfoBar.sys.mjs b/browser/components/asrouter/modules/InfoBar.sys.mjs
@@ -34,8 +34,15 @@ class InfoBarNotification {
this.infobarCallback = this.infobarCallback.bind(this);
this.message = message;
this.notification = null;
- // If set, this is the pref to watch for changes to auto-dismiss the infobar.
- this._dismissPref = message?.content?.dismissOnPrefChange || null;
+ const dismissPrefConfig = message?.content?.dismissOnPrefChange;
+ // If set, these are the prefs to watch for changes to auto-dismiss the infobar.
+ if (Array.isArray(dismissPrefConfig)) {
+ this._dismissPrefs = dismissPrefConfig;
+ } else if (dismissPrefConfig) {
+ this._dismissPrefs = [dismissPrefConfig];
+ } else {
+ this._dismissPrefs = [];
+ }
this._prefObserver = null;
}
@@ -397,11 +404,12 @@ class InfoBarNotification {
}
/**
- * If content.dismissOnPrefChange is set, observe that pref and dismiss the
- * infobar whenever it changes (including when it is set for the first time).
+ * If content.dismissOnPrefChange is set (string or array), observe those
+ * pref(s) and dismiss the infobar whenever any of them changes (including
+ * when it is set for the first time).
*/
_maybeAttachPrefObserver() {
- if (!this._dismissPref || this._prefObserver) {
+ if (!this._dismissPrefs?.length || this._prefObserver) {
return;
}
// Weak observer to avoid leaks.
@@ -411,7 +419,7 @@ class InfoBarNotification {
"nsISupportsWeakReference",
]),
observe: (subject, topic, data) => {
- if (topic === "nsPref:changed" && data === this._dismissPref) {
+ if (topic === "nsPref:changed" && this._dismissPrefs.includes(data)) {
try {
this.notification?.dismiss();
} catch (e) {
@@ -421,27 +429,32 @@ class InfoBarNotification {
},
};
try {
- // Hold weak so we don't retain the infobar if something goes wrong.
- Services.prefs.addObserver(this._dismissPref, this._prefObserver, true);
+ // Register each pref with a weak observer and ignore per-pref failures.
+ for (const pref of this._dismissPrefs) {
+ try {
+ Services.prefs.addObserver(pref, this._prefObserver, true);
+ } catch (_) {}
+ }
} catch (e) {
console.error(
- `Failed to add prefs observer for ${this._dismissPref}:`,
+ "Failed to add prefs observer(s) for dismissOnPrefChange:",
e
);
}
}
_removePrefObserver() {
- if (!this._dismissPref || !this._prefObserver) {
+ if (!this._dismissPrefs?.length || !this._prefObserver) {
return;
}
- try {
- Services.prefs.removeObserver(this._dismissPref, this._prefObserver);
- } catch (e) {
- // Ignore remove errors as observer might already be gone during shutdown.
- } finally {
- this._prefObserver = null;
+ for (const pref of this._dismissPrefs) {
+ try {
+ Services.prefs.removeObserver(pref, this._prefObserver);
+ } catch (_) {
+ // Ignore as the observer might already be removed during shutdown/teardown.
+ }
}
+ this._prefObserver = null;
}
/**
diff --git a/browser/components/asrouter/tests/browser/browser_asrouter_infobar.js b/browser/components/asrouter/tests/browser/browser_asrouter_infobar.js
@@ -1439,3 +1439,46 @@ add_task(async function replace_global_with_global_and_record_impressions() {
InfoBar._activeInfobar = null;
InfoBar._universalInfobars = [];
});
+
+add_task(async function dismiss_on_any_pref_in_array_change() {
+ const PREF1 = "messaging-system-action.dismissOnChange.array.one";
+ const PREF2 = "messaging-system-action.dismissOnChange.array.two";
+
+ const browser = BrowserWindowTracker.getTopWindow().gBrowser.selectedBrowser;
+ const message = {
+ id: "TEST_DISMISS_ON_ANY_PREF_IN_ARRAY",
+ content: {
+ type: "global",
+ text: "array pref change",
+ dismissable: true,
+ buttons: [],
+ dismissOnPrefChange: [PREF1, PREF2],
+ },
+ };
+
+ const dispatch = sinon.stub();
+ const infobar = await InfoBar.showInfoBarMessage(browser, message, dispatch);
+
+ // ignore initial impression
+ dispatch.resetHistory();
+
+ Services.prefs.setBoolPref(PREF2, true);
+
+ await BrowserTestUtils.waitForCondition(
+ () => !infobar.notification,
+ "Infobar dismissed when pref in the array changes"
+ );
+
+ Assert.ok(
+ dispatch.calledWith(
+ sinon.match({
+ type: "INFOBAR_TELEMETRY",
+ data: sinon.match.has("event", "DISMISSED"),
+ })
+ ),
+ "DISMISSED telemetry sent on array pref change"
+ );
+
+ Services.prefs.clearUserPref(PREF1);
+ Services.prefs.clearUserPref(PREF2);
+});