tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 58ed15784f96aedbc4ad142fd8a80aa29bca759e
parent 4a2678f54a405910732cd40e734e02e9a0e38285
Author: hannajones <hjones@mozilla.com>
Date:   Thu, 20 Nov 2025 18:48:07 +0000

Bug 1972074 - Part 3: ensure extension controlled message bar is shown when an extension is added r=mstriemer,akulyk

Differential Revision: https://phabricator.services.mozilla.com/D270907

Diffstat:
Mbrowser/components/preferences/tests/chrome/test_setting_control_extension_controlled.html | 46++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/content/preferences/Setting.mjs | 25++++++-------------------
2 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/browser/components/preferences/tests/chrome/test_setting_control_extension_controlled.html b/browser/components/preferences/tests/chrome/test_setting_control_extension_controlled.html @@ -77,6 +77,15 @@ await synthesizeMouseAtCenter(elem, {}); } + function waitForSettingChange(setting) { + return new Promise(resolve => { + setting.on("change", function handler() { + setting.off("change", handler); + resolve(); + }); + }); + } + const getExtensionControlledMessageBar = control => control.querySelector(".extension-controlled-message-bar"); const getReenableExtensionMessageBar = control => @@ -614,11 +623,14 @@ await secondExtension.unload(); control.remove(); }); + add_task(async function test_no_initial_controlling_extension() { // Setup pre-test items: extension, Preferences, ExtensionSettingStore const SETTING_ID = "extension-controlled-setting"; const STORE_ID = "privacy.containers"; const TEST_FLUENT_ID = "test-fluent-id"; + const ADDON_ID = "ext-controlled@mochi.test"; + const ADDON_NAME = "Ext Controlled"; // Assert there is no markup that is generated by pre-test setup since we // don't have a setting that is being controlled by the STORE_ID @@ -650,6 +662,7 @@ // Wait for setting-control element to be rendered let setting = Preferences.getSetting(SETTING_ID); let control = await renderTemplate(itemConfig, setting); + ok(await control.updateComplete, "No pending updates"); // Assert checkbox control is created and NOT disabled due to // no extension controlling the pref. @@ -674,6 +687,39 @@ "There should be no rendered message bar elements" ); + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + browser_specific_settings: { gecko: { id: ADDON_ID } }, + name: ADDON_NAME, + permissions: ["contextualIdentities", "cookies"], + }, + // We need to be able to find the extension using AddonManager. + useAddonManager: "temporary", + }); + + let settingChanged = waitForSettingChange(setting); + await extension.startup(); + await settingChanged; + await control.updateComplete; + + is( + control.controlEl.disabled, + true, + "Control is now disabled due to extension" + ); + + let messageBar = control.querySelector("moz-message-bar"); + ok(messageBar, "Message bar was rendered"); + + settingChanged = waitForSettingChange(setting); + await extension.unload(); + await settingChanged; + await control.updateComplete; + + is(control.controlEl.disabled, false, "Control is enabled again"); + messageBar = control.querySelector("moz-message-bar"); + ok(!messageBar, "Message bar was removed"); + control.remove(); }); diff --git a/toolkit/content/preferences/Setting.mjs b/toolkit/content/preferences/Setting.mjs @@ -352,20 +352,7 @@ export class Setting extends EventEmitter { } } - /** - * @param {any} _ - * @param {{ key: string, type: string }} setting ExtensionSettingsStore setting - */ - _observeExtensionSettingChanged = (_, setting) => { - if ( - setting.key == this.config.controllingExtensionInfo.storeId && - setting.type == "prefs" - ) { - this._checkForControllingExtension(); - } - }; - - async _checkForControllingExtension() { + _checkForControllingExtension = async () => { // Make sure all settings API modules are loaded // and the extension controlling settings metadata // loaded from the ExtensionSettingsStore backend. @@ -387,7 +374,7 @@ export class Setting extends EventEmitter { } } this._clearControllingExtensionInfo(); - } + }; _clearControllingExtensionInfo() { delete this.controllingExtensionInfo.id; @@ -399,8 +386,8 @@ export class Setting extends EventEmitter { watchExtensionPrefChange() { lazy.Management.on( - "extension-setting-changed", - this._observeExtensionSettingChanged + `extension-setting-changed:${this.config.controllingExtensionInfo?.storeId}`, + this._checkForControllingExtension ); } @@ -412,8 +399,8 @@ export class Setting extends EventEmitter { if (this.config.controllingExtensionInfo?.storeId) { lazy.Management.off( - "extension-setting-changed", - this._observeExtensionSettingChanged + `extension-setting-changed:${this.config.controllingExtensionInfo?.storeId}`, + this._checkForControllingExtension ); } }