tor-browser

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

commit d738f8c352cccb0418238cef0adc98a1c890ac0a
parent 683d4f9f11276947c20861340f7944cdd58d06d9
Author: Cristina Horotan <chorotan@mozilla.com>
Date:   Wed, 12 Nov 2025 01:32:40 +0200

Revert "Bug 1971428, Bug 1972371 - Convert DoH to config-based prefs - r=valentin,fluent-reviewers,desktop-theme-reviewers,hjones,bolsson" for causing chrome failures on test_moz_message_bar.html

This reverts commit 483d918796d7b3db934b48da392643df22b3da13.

Revert "Bug 1972371 - Convert Website Permissions to config-based prefs - r=emz,fluent-reviewers,akulyk,bolsson"

This reverts commit dcfc64fe2d8dc6d64ab0dd7b5fb685d4e9f8d93d.

Diffstat:
Mbrowser/app/profile/firefox.js | 3---
Mbrowser/components/preferences/main.js | 224-------------------------------------------------------------------------------
Mbrowser/components/preferences/preferences.js | 5-----
Mbrowser/components/preferences/privacy.inc.xhtml | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mbrowser/components/preferences/privacy.js | 609+++++++++++++------------------------------------------------------------------
Mbrowser/components/preferences/tests/browser_notifications_do_not_disturb.js | 11+++++------
Mbrowser/components/preferences/tests/browser_permissions_dialog.js | 35++++++++++++-----------------------
Mbrowser/components/preferences/tests/browser_permissions_urlFieldHidden.js | 5+----
Mbrowser/components/preferences/tests/browser_security-1.js | 14++++++++++++++
Mbrowser/components/preferences/tests/browser_security-2.js | 14++++++++++++++
Mbrowser/components/preferences/tests/head.js | 14--------------
Mbrowser/components/preferences/widgets/setting-element/setting-element.mjs | 2+-
Mbrowser/components/storybook/component-status/components.json | 2+-
Mbrowser/locales-preview/privacyPreferences.ftl | 77-----------------------------------------------------------------------------
Mbrowser/locales/en-US/browser/preferences/preferences.ftl | 74++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mbrowser/themes/shared/preferences/preferences.css | 4----
Dpython/l10n/fluent_migrations/bug_1972371_preferences_permissions.py | 35-----------------------------------
Mtoolkit/content/tests/widgets/test_moz_message_bar.html | 40----------------------------------------
Mtoolkit/content/widgets/lit-select-control.mjs | 6++++++
Mtoolkit/content/widgets/moz-message-bar/moz-message-bar.mjs | 28++++++----------------------
20 files changed, 448 insertions(+), 1000 deletions(-)

diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js @@ -2829,9 +2829,6 @@ pref("browser.screenshots.dir", ""); // DoH Rollout: whether to clear the mode value at shutdown. pref("doh-rollout.clearModeOnShutdown", false); -// DoH UI: default the fallback checkbox to on. -pref("network.trr_ui.fallback_was_checked", true); - // Normandy client preferences pref("app.normandy.api_url", "https://normandy.cdn.mozilla.net/api/v1"); pref("app.normandy.dev_mode", false); diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js @@ -1686,230 +1686,6 @@ let SETTINGS_CONFIG = { }, ], }, - permissions: { - id: "permissions", - l10nId: "permissions-header2", - headingLevel: 2, - items: [ - { - id: "permissionBox", - control: "moz-box-group", - controlAttrs: { - type: "list", - }, - items: [ - { - id: "locationSettingsButton", - control: "moz-box-button", - l10nId: "permissions-location2", - controlAttrs: { - ".iconSrc": "chrome://browser/skin/notification-icons/geo.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-location-window2.title,permissions-site-location-desc,permissions-site-location-disable-label,permissions-site-location-disable-desc", - }, - }, - { - id: "cameraSettingsButton", - control: "moz-box-button", - l10nId: "permissions-camera2", - controlAttrs: { - ".iconSrc": "chrome://browser/skin/notification-icons/camera.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-camera-window2.title,permissions-site-camera-desc,permissions-site-camera-disable-label,permissions-site-camera-disable-desc,", - }, - }, - { - id: "localHostSettingsButton", - control: "moz-box-button", - l10nId: "permissions-localhost2", - controlAttrs: { - ".iconSrc": - "chrome://browser/skin/notification-icons/local-host.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-localhost-window.title,permissions-site-localhost-desc,permissions-site-localhost-disable-label,permissions-site-localhost-disable-desc,", - }, - }, - { - id: "localNetworkSettingsButton", - control: "moz-box-button", - l10nId: "permissions-local-network2", - controlAttrs: { - ".iconSrc": - "chrome://browser/skin/notification-icons/local-network.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-local-network-window.title,permissions-site-local-network-desc,permissions-site-local-network-disable-label,permissions-site-local-network-disable-desc,", - }, - }, - { - id: "microphoneSettingsButton", - control: "moz-box-button", - l10nId: "permissions-microphone2", - controlAttrs: { - ".iconSrc": - "chrome://browser/skin/notification-icons/microphone.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-microphone-window2.title,permissions-site-microphone-desc,permissions-site-microphone-disable-label,permissions-site-microphone-disable-desc,", - }, - }, - { - id: "speakerSettingsButton", - control: "moz-box-button", - l10nId: "permissions-speaker2", - controlAttrs: { - ".iconSrc": - "chrome://browser/skin/notification-icons/speaker.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-speaker-window.title,permissions-site-speaker-desc,", - }, - }, - { - id: "notificationSettingsButton", - control: "moz-box-button", - l10nId: "permissions-notification2", - controlAttrs: { - ".iconSrc": - "chrome://browser/skin/notification-icons/desktop-notification.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-notification-window2.title,permissions-site-notification-desc,permissions-site-notification-disable-label,permissions-site-notification-disable-desc,", - }, - }, - { - id: "autoplaySettingsButton", - control: "moz-box-button", - l10nId: "permissions-autoplay2", - controlAttrs: { - ".iconSrc": - "chrome://browser/skin/notification-icons/autoplay-media.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-autoplay-window2.title,permissions-site-autoplay-desc,", - }, - }, - { - id: "xrSettingsButton", - control: "moz-box-button", - l10nId: "permissions-xr2", - controlAttrs: { - ".iconSrc": "chrome://browser/skin/notification-icons/xr.svg", - "search-l10n-ids": - "permissions-remove.label,permissions-remove-all.label,permissions-site-xr-window2.title,permissions-site-xr-desc,permissions-site-xr-disable-label,permissions-site-xr-disable-desc,", - }, - }, - ], - }, - { - id: "popupPolicy", - l10nId: "permissions-block-popups2", - items: [ - { - id: "popupPolicyButton", - l10nId: "permissions-block-popups-exceptions-button2", - control: "moz-box-button", - controlAttrs: { - "search-l10n-ids": - "permissions-address,permissions-exceptions-popup-window3.title,permissions-exceptions-popup-desc2", - }, - }, - ], - }, - { - id: "warnAddonInstall", - l10nId: "permissions-addon-install-warning2", - items: [ - { - id: "addonExceptions", - l10nId: "permissions-addon-exceptions2", - control: "moz-box-button", - controlAttrs: { - "search-l10n-ids": - "permissions-address,permissions-allow.label,permissions-remove.label,permissions-remove-all.label,permissions-exceptions-addons-window2.title,permissions-exceptions-addons-desc", - }, - }, - ], - }, - { - id: "notificationsDoNotDisturb", - l10nId: "permissions-notification-pause", - }, - ], - }, - dnsOverHttps: { - inProgress: true, - items: [ - { - id: "dohBox", - control: "moz-box-group", - items: [ - { - id: "dohModeBoxItem", - control: "moz-box-item", - }, - { - id: "dohAdvancedButton", - l10nId: "preferences-doh-advanced-button", - control: "moz-box-button", - }, - ], - }, - ], - }, - dnsOverHttpsAdvanced: { - inProgress: true, - l10nId: "preferences-doh-advanced-section", - supportPage: "dns-over-https", - headingLevel: 2, - items: [ - { - id: "dohStatusBox", - control: "moz-message-bar", - }, - { - id: "dohRadioGroup", - control: "moz-radio-group", - options: [ - { - id: "dohRadioDefault", - value: "default", - l10nId: "preferences-doh-radio-default", - }, - { - id: "dohRadioCustom", - value: "custom", - l10nId: "preferences-doh-radio-custom", - items: [ - { - id: "dohFallbackIfCustom", - l10nId: "preferences-doh-fallback-label", - }, - { - id: "dohProviderSelect", - l10nId: "preferences-doh-select-resolver-label", - control: "moz-select", - }, - { - id: "dohCustomProvider", - control: "moz-input-text", - l10nId: "preferences-doh-custom-provider-label", - }, - ], - }, - { - id: "dohRadioOff", - value: "off", - l10nId: "preferences-doh-radio-off", - }, - ], - }, - { - id: "dohExceptionsButton", - l10nId: "preferences-doh-manage-exceptions2", - control: "moz-box-button", - controlAttrs: { - "search-l10n-ids": - "permissions-doh-entry-field,permissions-doh-add-exception.label,permissions-doh-remove.label,permissions-doh-remove-all.label,permissions-exceptions-doh-window.title,permissions-exceptions-manage-doh-desc,", - }, - }, - ], - }, }; /** diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js @@ -172,11 +172,6 @@ const CONFIG_PANES = { l10nId: "containers-section-header", groupIds: ["containers"], }, - dnsOverHttps: { - parent: "privacy", - l10nId: "preferences-doh-header2", - groupIds: ["dnsOverHttpsAdvanced"], - }, }; var gLastCategory = { category: undefined, subcategory: undefined }; diff --git a/browser/components/preferences/privacy.inc.xhtml b/browser/components/preferences/privacy.inc.xhtml @@ -664,12 +664,251 @@ class="subcategory" hidden="true" data-category="panePrivacy"> - <html:h1 data-l10n-id="permissions-header2"/> + <html:h1 data-l10n-id="permissions-header"/> </hbox> <!-- Permissions --> <groupbox id="permissionsGroup" data-category="panePrivacy" hidden="true" data-subcategory="permissions"> - <html:setting-group groupid="permissions"></html:setting-group> + <label class="search-header" hidden="true"><html:h2 data-l10n-id="permissions-header"/></label> + + <!-- The hbox around the buttons is to compute the search tooltip position properly --> + <vbox> + <hbox id="locationSettingsRow" align="center" role="group" aria-labelledby="locationPermissionsLabel"> + <hbox flex="1"> + <image class="geo-icon permission-icon" /> + <label id="locationPermissionsLabel" data-l10n-id="permissions-location"/> + </hbox> + <hbox pack="end"> + <button id="locationSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-location-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-location-window2.title, + permissions-site-location-desc, + permissions-site-location-disable-label, + permissions-site-location-disable-desc, + " /> + </hbox> + </hbox> + + <hbox id="cameraSettingsRow" align="center" role="group" aria-labelledby="cameraPermissionsLabel"> + <hbox flex="1"> + <image class="camera-icon permission-icon" /> + <label id="cameraPermissionsLabel" data-l10n-id="permissions-camera"/> + </hbox> + <hbox pack="end"> + <button id="cameraSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-camera-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-camera-window2.title, + permissions-site-camera-desc, + permissions-site-camera-disable-label, + permissions-site-camera-disable-desc, + " /> + </hbox> + </hbox> + + <hbox id="localHostSettingsRow" align="center" role="group" aria-labelledby="localHostPermissionsLabel"> + <hbox flex="1"> + <image class="localhost-icon permission-icon" /> + <label id="localHostPermissionsLabel" data-l10n-id="permissions-localhost"/> + </hbox> + <hbox pack="end"> + <button id="localHostSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-localhost-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-localhost-window.title, + permissions-site-localhost-desc, + permissions-site-localhost-disable-label, + permissions-site-localhost-disable-desc, + " /> + </hbox> + </hbox> + + <hbox id="localNetworkSettingsRow" align="center" role="group" aria-labelledby="localNetworkPermissionsLabel"> + <hbox flex="1"> + <image class="local-network-icon permission-icon" /> + <label id="localNetworkPermissionsLabel" data-l10n-id="permissions-local-network"/> + </hbox> + <hbox pack="end"> + <button id="localNetworkSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-local-network-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-local-network-window.title, + permissions-site-local-network-desc, + permissions-site-local-network-disable-label, + permissions-site-local-network-disable-desc, + " /> + </hbox> + </hbox> + + <hbox id="microphoneSettingsRow" align="center" role="group" aria-labelledby="microphonePermissionsLabel"> + <hbox flex="1"> + <image class="microphone-icon permission-icon" /> + <label id="microphonePermissionsLabel" data-l10n-id="permissions-microphone"/> + </hbox> + <hbox pack="end"> + <button id="microphoneSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-microphone-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-microphone-window2.title, + permissions-site-microphone-desc, + permissions-site-microphone-disable-label, + permissions-site-microphone-disable-desc, + " /> + </hbox> + </hbox> + + <hbox id="speakerSettingsRow" align="center" role="group" aria-labelledby="speakerPermissionsLabel"> + <hbox flex="1"> + <image class="speaker-icon permission-icon" /> + <label id="speakerPermissionsLabel" data-l10n-id="permissions-speaker"/> + </hbox> + <hbox pack="end"> + <button id="speakerSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-speaker-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-speaker-window.title, + permissions-site-speaker-desc, + " /> + </hbox> + </hbox> + + <hbox id="notificationSettingsRow" align="center" role="group" aria-labelledby="notificationPermissionsLabel"> + <hbox flex="1"> + <image class="desktop-notification-icon permission-icon" /> + <label id="notificationPermissionsLabel" + class="tail-with-learn-more" + data-l10n-id="permissions-notification"/> + <html:a is="moz-support-link" + id="notificationPermissionsLearnMore" + class="learnMore" + data-l10n-id="permissions-notification-link" + support-page="push" + /> + </hbox> + <hbox pack="end"> + <button id="notificationSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-notification-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-notification-window2.title, + permissions-site-notification-desc, + permissions-site-notification-disable-label, + permissions-site-notification-disable-desc, + " /> + </hbox> + </hbox> + + <vbox id="notificationsDoNotDisturbBox" hidden="true"> + <checkbox id="notificationsDoNotDisturb" class="indent"/> + </vbox> + + <hbox id="autoplaySettingsRow" align="center" role="group" aria-labelledby="autoplayPermissionsLabel"> + <hbox flex="1"> + <image class="autoplay-icon permission-icon" /> + <label id="autoplayPermissionsLabel" + data-l10n-id="permissions-autoplay"/> + </hbox> + <hbox pack="end"> + <button id="autoplaySettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-autoplay-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-autoplay-window2.title, + permissions-site-autoplay-desc, + " /> + </hbox> + </hbox> + + <hbox id="xrSettingsRow" align="center" role="group" aria-labelledby="xrPermissionsLabel"> + <hbox flex="1"> + <image class="xr-icon permission-icon" /> + <label id="xrPermissionsLabel" data-l10n-id="permissions-xr"/> + </hbox> + <hbox pack="end"> + <button id="xrSettingsButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-xr-settings" + search-l10n-ids=" + permissions-remove.label, + permissions-remove-all.label, + permissions-site-xr-window2.title, + permissions-site-xr-desc, + permissions-site-xr-disable-label, + permissions-site-xr-disable-desc, + " /> + </hbox> + </hbox> + </vbox> + + <separator /> + + <hbox data-subcategory="permissions-block-popups"> + <checkbox id="popupPolicy" preference="dom.disable_open_during_load" + data-l10n-id="permissions-block-popups2" + flex="1" /> + <button id="popupPolicyButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-block-popups-exceptions-button" + data-l10n-attrs="searchkeywords" + search-l10n-ids=" + permissions-address, + permissions-exceptions-popup-window3.title, + permissions-exceptions-popup-desc2, + " /> + </hbox> + + <hbox id="addonInstallBox"> + <checkbox id="warnAddonInstall" + data-l10n-id="permissions-addon-install-warning" + preference="xpinstall.whitelist.required" + flex="1" /> + <button id="addonExceptions" + is="highlightable-button" + class="accessory-button" + data-l10n-id="permissions-addon-exceptions" + search-l10n-ids=" + permissions-address, + permissions-allow.label, + permissions-remove.label, + permissions-remove-all.label, + permissions-exceptions-addons-window2.title, + permissions-exceptions-addons-desc, + " /> + </hbox> + </groupbox> <!-- Firefox Data Collection and Use --> @@ -828,8 +1067,7 @@ <html:h1 data-l10n-id="preferences-doh-header"/> </hbox> -<html:setting-group hidden="true" data-category="panePrivacy" groupid="dnsOverHttps" /> -<groupbox id="dohBox" data-category="panePrivacy" data-subcategory="doh" hidden="true" class="highlighting-group" data-srd-groupid="dnsOverHttps"> +<groupbox id="dohBox" data-category="panePrivacy" data-subcategory="doh" hidden="true" class="highlighting-group"> <label class="search-header" searchkeywords="doh trr" hidden="true"><html:h2 data-l10n-id="preferences-doh-header"/></label> <vbox flex="1"> <description id="dohDescription" class="tail-with-learn-more description-deemphasized" data-l10n-id="preferences-doh-description2"></description> diff --git a/browser/components/preferences/privacy.js b/browser/components/preferences/privacy.js @@ -279,14 +279,10 @@ Preferences.addAll([ { id: "network.trr.uri", type: "string" }, { id: "network.trr.default_provider_uri", type: "string" }, { id: "network.trr.custom_uri", type: "string" }, - { id: "network.trr_ui.fallback_was_checked", type: "bool" }, { id: "doh-rollout.disable-heuristics", type: "bool" }, // Local Network Access { id: "network.lna.blocking", type: "bool" }, - - // Permissions - { id: "media.setsinkid.enabled", type: "bool" }, ]); if (Services.prefs.getBoolPref("privacy.ui.status_card", false)) { @@ -1887,508 +1883,6 @@ Preferences.addSetting({ }, }); -Preferences.addSetting({ - id: "permissionBox", -}); -Preferences.addSetting({ - id: "popupPolicy", - pref: "dom.disable_open_during_load", -}); -Preferences.addSetting({ - id: "popupPolicyButton", - deps: ["popupPolicy"], - onUserClick: () => gPrivacyPane.showPopupExceptions(), - disabled: ({ popupPolicy }) => { - return !popupPolicy.value || popupPolicy.locked; - }, -}); -Preferences.addSetting({ - id: "warnAddonInstall", - pref: "xpinstall.whitelist.required", -}); -Preferences.addSetting({ - id: "addonExceptions", - deps: ["warnAddonInstall"], - onUserClick: () => gPrivacyPane.showAddonExceptions(), - disabled: ({ warnAddonInstall }) => { - return !warnAddonInstall.value || warnAddonInstall.locked; - }, -}); -Preferences.addSetting({ - id: "notificationsDoNotDisturb", - get: () => { - return AlertsServiceDND?.manualDoNotDisturb ?? false; - }, - set: value => { - if (AlertsServiceDND) { - AlertsServiceDND.manualDoNotDisturb = value; - } - }, - visible: () => { - return AlertsServiceDND != undefined; - }, -}); -Preferences.addSetting({ - id: "locationSettingsButton", - onUserClick: () => gPrivacyPane.showLocationExceptions(), -}); -Preferences.addSetting({ - id: "cameraSettingsButton", - onUserClick: () => gPrivacyPane.showCameraExceptions(), -}); -Preferences.addSetting({ - id: "enabledLNA", - pref: "network.lna.blocking", -}); -Preferences.addSetting({ - id: "localNetworkSettingsButton", - onUserClick: () => gPrivacyPane.showLocalNetworkExceptions(), - deps: ["enabledLNA"], - visible: deps => { - return deps.enabledLNA.value; - }, -}); -Preferences.addSetting({ - id: "localHostSettingsButton", - onUserClick: () => gPrivacyPane.showLocalHostExceptions(), - deps: ["enabledLNA"], - visible: deps => { - return deps.enabledLNA.value; - }, -}); -Preferences.addSetting({ - id: "microphoneSettingsButton", - onUserClick: () => gPrivacyPane.showMicrophoneExceptions(), -}); -Preferences.addSetting({ - id: "enabledSpeakerControl", - pref: "media.setsinkid.enabled", -}); -Preferences.addSetting({ - id: "speakerSettingsButton", - onUserClick: () => gPrivacyPane.showSpeakerExceptions(), - deps: ["enabledSpeakerControl"], - visible: ({ enabledSpeakerControl }) => { - return enabledSpeakerControl.value; - }, -}); -Preferences.addSetting({ - id: "notificationSettingsButton", - onUserClick: () => gPrivacyPane.showNotificationExceptions(), -}); -Preferences.addSetting({ - id: "autoplaySettingsButton", - onUserClick: () => gPrivacyPane.showAutoplayMediaExceptions(), -}); -Preferences.addSetting({ - id: "xrSettingsButton", - onUserClick: () => gPrivacyPane.showXRExceptions(), -}); - -Preferences.addSetting({ - id: "dohBox", -}); - -Preferences.addSetting({ - id: "dohAdvancedButton", - onUserClick(e) { - e.preventDefault(); - gotoPref("paneDnsOverHttps"); - }, -}); - -Preferences.addSetting({ - id: "dohExceptionsButton", - onUserClick: () => gPrivacyPane.showDoHExceptions(), -}); - -Preferences.addSetting({ - id: "dohMode", - pref: "network.trr.mode", - setup(emitChange) { - Services.obs.addObserver(emitChange, "network:trr-mode-changed"); - Services.obs.addObserver(emitChange, "network:trr-confirmation"); - return () => { - Services.obs.removeObserver(emitChange, "network:trr-mode-changed"); - Services.obs.removeObserver(emitChange, "network:trr-confirmation"); - }; - }, -}); - -Preferences.addSetting({ - id: "dohURL", - pref: "network.trr.uri", - setup(emitChange) { - Services.obs.addObserver(emitChange, "network:trr-uri-changed"); - Services.obs.addObserver(emitChange, "network:trr-confirmation"); - return () => { - Services.obs.removeObserver(emitChange, "network:trr-uri-changed"); - Services.obs.removeObserver(emitChange, "network:trr-confirmation"); - }; - }, -}); - -Preferences.addSetting({ - id: "dohDefaultURL", - pref: "network.trr.default_provider_uri", -}); - -Preferences.addSetting({ - id: "dohDisableHeuristics", - pref: "doh-rollout.disable-heuristics", -}); - -Preferences.addSetting({ - id: "dohModeBoxItem", - deps: ["dohMode"], - getControlConfig: (config, deps) => { - let l10nId = "preferences-doh-overview-off"; - if (deps.dohMode.value == Ci.nsIDNSService.MODE_NATIVEONLY) { - l10nId = "preferences-doh-overview-default"; - } else if ( - deps.dohMode.value == Ci.nsIDNSService.MODE_TRRFIRST || - deps.dohMode.value == Ci.nsIDNSService.MODE_TRRONLY - ) { - l10nId = "preferences-doh-overview-custom"; - } - return { - ...config, - l10nId, - }; - }, -}); - -Preferences.addSetting({ - id: "dohStatusBox", - deps: ["dohMode", "dohURL"], - getControlConfig: config => { - let l10nId = "preferences-doh-status-item-off"; - let l10nArgs = {}; - let supportPage = ""; - let controlAttrs = { type: "info" }; - - let trrURI = Services.dns.currentTrrURI; - let hostname = URL.parse(trrURI)?.hostname; - - let name = hostname || trrURI; - let nameFound = false; - let steering = false; - for (let resolver of DoHConfigController.currentConfig.providerList) { - if (resolver.uri == trrURI) { - name = resolver.UIName || name; - nameFound = true; - break; - } - } - if (!nameFound) { - for (let resolver of DoHConfigController.currentConfig.providerSteering - .providerList) { - if (resolver.uri == trrURI) { - steering = true; - name = resolver.UIName || name; - break; - } - } - } - - let mode = Services.dns.currentTrrMode; - if ( - (mode == Ci.nsIDNSService.MODE_TRRFIRST || - mode == Ci.nsIDNSService.MODE_TRRONLY) && - lazy.gParentalControlsService?.parentalControlsEnabled - ) { - l10nId = "preferences-doh-status-item-not-active"; - supportPage = "doh-status"; - l10nArgs = { - reason: Services.dns.getTRRSkipReasonName( - Ci.nsITRRSkipReason.TRR_PARENTAL_CONTROL - ), - name, - }; - } else { - let confirmationState = Services.dns.currentTrrConfirmationState; - if ( - mode != Ci.nsIDNSService.MODE_TRRFIRST && - mode != Ci.nsIDNSService.MODE_TRRONLY - ) { - l10nId = "preferences-doh-status-item-off"; - } else if ( - confirmationState == Ci.nsIDNSService.CONFIRM_TRYING_OK || - confirmationState == Ci.nsIDNSService.CONFIRM_OK || - confirmationState == Ci.nsIDNSService.CONFIRM_DISABLED - ) { - if (steering) { - l10nId = "preferences-doh-status-item-active-local"; - controlAttrs = { type: "success" }; - } else { - l10nId = "preferences-doh-status-item-active"; - controlAttrs = { type: "success" }; - } - } else if (steering) { - l10nId = "preferences-doh-status-item-not-active-local"; - supportPage = "doh-status"; - controlAttrs = { type: "warning" }; - } else { - l10nId = "preferences-doh-status-item-not-active"; - supportPage = "doh-status"; - controlAttrs = { type: "warning" }; - } - - let confirmationStatus = Services.dns.lastConfirmationStatus; - if (confirmationStatus != Cr.NS_OK) { - l10nArgs = { - reason: ChromeUtils.getXPCOMErrorName(confirmationStatus), - name, - }; - } else { - l10nArgs = { - reason: Services.dns.getTRRSkipReasonName( - Services.dns.lastConfirmationSkipReason - ), - name, - }; - if ( - Services.dns.lastConfirmationSkipReason == - Ci.nsITRRSkipReason.TRR_BAD_URL || - !name - ) { - l10nId = "preferences-doh-status-item-not-active-bad-url"; - supportPage = "doh-status"; - controlAttrs = { type: "warning" }; - } - } - } - - return { - ...config, - l10nId, - l10nArgs, - supportPage, - controlAttrs, - }; - }, -}); - -Preferences.addSetting({ - id: "dohRadioGroup", - // These deps are complicated: - // this radio group, along with dohFallbackIfCustom controls the mode and URL. - // Therefore, we set dohMode and dohURL as deps here. This is a smell, but needed - // for the mismatch of control-to-pref. - deps: ["dohFallbackIfCustom", "dohMode", "dohURL"], - onUserChange: (val, deps) => { - let value = null; - if (val == "default") { - value = "dohDefaultRadio"; - } else if (val == "off") { - value = "dohOffRadio"; - } else if (val == "custom" && deps.dohFallbackIfCustom.value) { - value = "dohEnabledRadio"; - } else if (val == "custom" && !deps.dohFallbackIfCustom.value) { - value = "dohStrictRadio"; - } - if (value) { - Glean.securityDohSettings.modeChangedButton.record({ - value, - }); - } - }, - get: (_val, deps) => { - switch (deps.dohMode.value) { - case Ci.nsIDNSService.MODE_NATIVEONLY: - return "default"; - case Ci.nsIDNSService.MODE_TRRFIRST: - case Ci.nsIDNSService.MODE_TRRONLY: - return "custom"; - case Ci.nsIDNSService.MODE_TRROFF: - case Ci.nsIDNSService.MODE_RESERVED1: - case Ci.nsIDNSService.MODE_RESERVED4: - default: - return "off"; - } - }, - set: (val, deps) => { - if (val == "custom") { - if (deps.dohFallbackIfCustom.value) { - deps.dohMode.value = Ci.nsIDNSService.MODE_TRRFIRST; - } else { - deps.dohMode.value = Ci.nsIDNSService.MODE_TRRONLY; - } - } else if (val == "off") { - deps.dohMode.value = Ci.nsIDNSService.MODE_TRROFF; - } else { - deps.dohMode.value = Ci.nsIDNSService.MODE_NATIVEONLY; - } - - // When the mode is set to 0 we need to clear the URI so - // doh-rollout can kick in. - if (deps.dohMode.value == Ci.nsIDNSService.MODE_NATIVEONLY) { - deps.dohURL.pref.value = undefined; - Services.prefs.clearUserPref("doh-rollout.disable-heuristics"); - } - - // Bug 1861285 - // When the mode is set to 2 or 3, we need to check if network.trr.uri is a empty string. - // In this case, we need to update network.trr.uri to default to fallbackProviderURI. - // This occurs when the mode is previously set to 0 (Default Protection). - if ( - deps.dohMode.value == Ci.nsIDNSService.MODE_TRRFIRST || - deps.dohMode.value == Ci.nsIDNSService.MODE_TRRONLY - ) { - if (!deps.dohURL.value) { - deps.dohURL.value = - DoHConfigController.currentConfig.fallbackProviderURI; - } - } - - // Bug 1900672 - // When the mode is set to 5, clear the pref to ensure that - // network.trr.uri is set to fallbackProviderURIwhen the mode is set to 2 or 3 afterwards - if (deps.dohMode.value == Ci.nsIDNSService.MODE_TRROFF) { - deps.dohURL.pref.value = undefined; - } - }, -}); - -Preferences.addSetting({ - id: "dohFallbackIfCustom", - pref: "network.trr_ui.fallback_was_checked", - // These deps are complicated: - // this checkbox, along with dohRadioGroup controls the mode and URL. - // Therefore, we set dohMode as a dep here. This is a smell, but needed - // for the mismatch of control-to-pref. - deps: ["dohMode"], - onUserChange: val => { - if (val) { - Glean.securityDohSettings.modeChangedButton.record({ - value: "dohEnabledRadio", - }); - } else { - Glean.securityDohSettings.modeChangedButton.record({ - value: "dohStrictRadio", - }); - } - }, - get: (val, deps) => { - // If we are in a custom mode, we need to get the value from the Setting - if (deps.dohMode.value == Ci.nsIDNSService.MODE_TRRFIRST) { - return true; - } - if (deps.dohMode.value == Ci.nsIDNSService.MODE_TRRONLY) { - return false; - } - - // Propagate the preference otherwise - return val; - }, - set: (val, deps) => { - // Toggle the preference that controls the setting if are in a custom mode - // This should be the only case where the checkbox is enabled, but we can be - // careful and test. - if (deps.dohMode.value == Ci.nsIDNSService.MODE_TRRFIRST && !val) { - deps.dohMode.value = Ci.nsIDNSService.MODE_TRRONLY; - } else if (deps.dohMode.value == Ci.nsIDNSService.MODE_TRRONLY && val) { - deps.dohMode.value = Ci.nsIDNSService.MODE_TRRFIRST; - } - // Propagate to the real preference - return val; - }, -}); - -Preferences.addSetting({ - id: "dohCustomProvider", - deps: ["dohProviderSelect", "dohURL"], - _value: null, - visible: deps => { - return deps.dohProviderSelect.value == "custom"; - }, - get(_val, deps) { - if (this._value === null) { - return deps.dohURL.value; - } - return this._value; - }, - set(val, deps) { - this._value = val; - if (val == "") { - val = " "; - } - deps.dohURL.value = val; - }, -}); - -Preferences.addSetting({ - id: "dohProviderSelect", - deps: ["dohURL", "dohDefaultURL"], - _custom: false, - onUserChange: value => { - Glean.securityDohSettings.providerChoiceValue.record({ - value, - }); - }, - getControlConfig(config, deps) { - let options = []; - - let resolvers = DoHConfigController.currentConfig.providerList; - // if there's no default, we'll hold its position with an empty string - let defaultURI = DoHConfigController.currentConfig.fallbackProviderURI; - let defaultFound = resolvers.some(p => p.uri == defaultURI); - if (!defaultFound && defaultURI) { - // the default value for the pref isn't included in the resolvers list - // so we'll make a stub for it. Without an id, we'll have to use the url as the label - resolvers.unshift({ uri: defaultURI }); - } - let currentURI = deps.dohURL.value; - if (currentURI && !resolvers.some(p => p.uri == currentURI)) { - this._custom = true; - } - - options = resolvers.map(resolver => { - let option = { - value: resolver.uri, - l10nArgs: { - name: resolver.UIName || resolver.uri, - }, - }; - if (resolver.uri == defaultURI) { - option.l10nId = "connection-dns-over-https-url-item-default"; - } else { - option.l10nId = "connection-dns-over-https-url-item"; - } - return option; - }); - options.push({ - value: "custom", - l10nId: "connection-dns-over-https-url-custom", - }); - - return { - options, - ...config, - }; - }, - get(_val, deps) { - if (this._custom) { - return "custom"; - } - let currentURI = deps.dohURL.value; - if (!currentURI) { - currentURI = deps.dohDefaultURL.value; - } - return currentURI; - }, - set(val, deps, setting) { - if (val != "custom") { - this._custom = false; - deps.dohURL.value = val; - } else { - this._custom = true; - } - setting.emit("change"); - return val; - }, -}); - function setEventListener(aId, aEventType, aCallback) { document .getElementById(aId) @@ -2946,9 +2440,6 @@ var gPrivacyPane = { initSettingGroup("cookiesAndSiteData"); initSettingGroup("certificates"); initSettingGroup("ipprotection"); - initSettingGroup("permissions"); - initSettingGroup("dnsOverHttps"); - initSettingGroup("dnsOverHttpsAdvanced"); this._updateSanitizeSettingsButton(); this.initializeHistoryMode(); @@ -3055,6 +2546,11 @@ var gPrivacyPane = { gPrivacyPane.changeMasterPassword ); setEventListener("showPasswords", "command", gPrivacyPane.showPasswords); + setEventListener( + "addonExceptions", + "command", + gPrivacyPane.showAddonExceptions + ); this._pane = document.getElementById("panePrivacy"); @@ -3065,6 +2561,64 @@ var gPrivacyPane = { this.initListenersForExtensionControllingPasswordManager(); + setEventListener( + "autoplaySettingsButton", + "command", + gPrivacyPane.showAutoplayMediaExceptions + ); + setEventListener( + "notificationSettingsButton", + "command", + gPrivacyPane.showNotificationExceptions + ); + setEventListener( + "locationSettingsButton", + "command", + gPrivacyPane.showLocationExceptions + ); + setEventListener( + "localHostSettingsButton", + "command", + gPrivacyPane.showLocalHostExceptions + ); + setEventListener( + "localNetworkSettingsButton", + "command", + gPrivacyPane.showLocalNetworkExceptions + ); + setEventListener( + "xrSettingsButton", + "command", + gPrivacyPane.showXRExceptions + ); + setEventListener( + "cameraSettingsButton", + "command", + gPrivacyPane.showCameraExceptions + ); + setEventListener( + "microphoneSettingsButton", + "command", + gPrivacyPane.showMicrophoneExceptions + ); + document.getElementById("speakerSettingsRow").hidden = + !Services.prefs.getBoolPref("media.setsinkid.enabled", false); + setEventListener( + "speakerSettingsButton", + "command", + gPrivacyPane.showSpeakerExceptions + ); + setEventListener( + "popupPolicyButton", + "command", + gPrivacyPane.showPopupExceptions + ); + setEventListener( + "notificationsDoNotDisturb", + "command", + gPrivacyPane.toggleDoNotDisturbNotifications + ); + setSyncFromPrefListener("contentBlockingBlockCookiesCheckbox", () => this.readBlockCookies() ); @@ -3086,6 +2640,13 @@ var gPrivacyPane = { setSyncFromPrefListener("rememberForms", microControlHandler); setSyncFromPrefListener("alwaysClear", microControlHandler); + setSyncFromPrefListener("popupPolicy", () => + this.updateButtons("popupPolicyButton", "dom.disable_open_during_load") + ); + setSyncFromPrefListener("warnAddonInstall", () => + this.readWarnAddonInstall() + ); + if (AlertsServiceDND) { let notificationsDoNotDisturbBox = document.getElementById( "notificationsDoNotDisturbBox" @@ -3177,6 +2738,12 @@ var gPrivacyPane = { this.initWebAuthn(); + Preferences.get("network.lna.blocking").on( + "change", + this.setUpLocalNetworkAccessPermissionUI + ); + this.setUpLocalNetworkAccessPermissionUI(); + // Notify observers that the UI is now ready Services.obs.notifyObservers(window, "privacy-pane-loaded"); }, @@ -4059,6 +3626,10 @@ var gPrivacyPane = { settingsButton.disabled = !sanitizeOnShutdownPref.value; }, + toggleDoNotDisturbNotifications(event) { + AlertsServiceDND.manualDoNotDisturb = event.target.checked; + }, + // PRIVATE BROWSING /** @@ -4859,6 +4430,20 @@ var gPrivacyPane = { }, /** + * Enables/disables the add-ons Exceptions button depending on whether + * or not add-on installation warnings are displayed. + */ + readWarnAddonInstall() { + var warn = Preferences.get("xpinstall.whitelist.required"); + var exceptions = document.getElementById("addonExceptions"); + + exceptions.disabled = !warn.value || warn.locked; + + // don't override the preference value + return undefined; + }, + + /** * Displays the exceptions lists for add-on installation warnings. */ showAddonExceptions() { @@ -5068,6 +4653,12 @@ var gPrivacyPane = { this.updateProfilesPrivacyInfo(); }, + setUpLocalNetworkAccessPermissionUI() { + const isLNADisabled = !Preferences.get("network.lna.blocking").value; + document.getElementById("localHostSettingsRow").hidden = isLNADisabled; + document.getElementById("localNetworkSettingsRow").hidden = isLNADisabled; + }, + updateProfilesPrivacyInfo() { let profilesInfo = document.getElementById("preferences-privacy-profiles"); profilesInfo.hidden = !SelectableProfileService.isEnabled; diff --git a/browser/components/preferences/tests/browser_notifications_do_not_disturb.js b/browser/components/preferences/tests/browser_notifications_do_not_disturb.js @@ -15,8 +15,8 @@ add_task(async function () { let doc = gBrowser.contentDocument; let notificationsDoNotDisturbBox = doc.getElementById( - "notificationsDoNotDisturb" - ).control; + "notificationsDoNotDisturbBox" + ); if (notificationsDoNotDisturbBox.hidden) { todo(false, "Do not disturb is not available on this platform"); return; @@ -32,15 +32,14 @@ add_task(async function () { return; } - let checkbox = doc.getElementById("notificationsDoNotDisturb").control - .controlEl; + let checkbox = doc.getElementById("notificationsDoNotDisturb"); ok(!checkbox.checked, "Checkbox should not be checked by default"); ok( !alertService.manualDoNotDisturb, "Do not disturb should be off by default" ); - let checkboxChanged = BrowserTestUtils.waitForEvent(checkbox, "change"); + let checkboxChanged = BrowserTestUtils.waitForEvent(checkbox, "command"); checkbox.click(); await checkboxChanged; ok( @@ -48,7 +47,7 @@ add_task(async function () { "Do not disturb should be enabled when checked" ); - checkboxChanged = BrowserTestUtils.waitForEvent(checkbox, "change"); + checkboxChanged = BrowserTestUtils.waitForEvent(checkbox, "command"); checkbox.click(); await checkboxChanged; ok( diff --git a/browser/components/preferences/tests/browser_permissions_dialog.js b/browser/components/preferences/tests/browser_permissions_dialog.js @@ -586,13 +586,12 @@ add_task(async function testTabBehaviour() { add_task(async function addSpeakerPermission() { let enabled = Services.prefs.getBoolPref("media.setsinkid.enabled", false); - let speakerButton = gBrowser.contentDocument.getElementById( - "speakerSettingsButton" - ); + let speakerRow = + gBrowser.contentDocument.getElementById("speakerSettingsRow"); Assert.equal( - BrowserTestUtils.isVisible(speakerButton), + BrowserTestUtils.isVisible(speakerRow), enabled, - "speakerButton visible" + "speakerRow visible" ); if (!enabled) { return; @@ -639,45 +638,35 @@ add_task(async function addSpeakerPermission() { add_task(async function testLocalNetworkAccessPermissionVisibility() { let enabled = Services.prefs.getBoolPref("network.lna.blocking", false); - let localHostSettingsButton = gBrowser.contentDocument.getElementById( - "localHostSettingsButton" + let localHostSettingsRow = gBrowser.contentDocument.getElementById( + "localHostSettingsRow" ); - let localNetworkSettingsButton = gBrowser.contentDocument.getElementById( - "localNetworkSettingsButton" + let localNetworkSettingsRow = gBrowser.contentDocument.getElementById( + "localNetworkSettingsRow" ); Assert.equal( - BrowserTestUtils.isVisible(localNetworkSettingsButton), + BrowserTestUtils.isVisible(localNetworkSettingsRow), enabled, "localhost permissions visible" ); Assert.equal( - BrowserTestUtils.isVisible(localHostSettingsButton), + BrowserTestUtils.isVisible(localHostSettingsRow), enabled, "localhost permissions visible" ); - let changeLocalHostButton = waitForSettingControlChange( - localHostSettingsButton - ); - let changeLocalNetworkButton = waitForSettingControlChange( - localNetworkSettingsButton - ); - enabled = !enabled; Services.prefs.setBoolPref("network.lna.blocking", enabled); - await changeLocalHostButton; - await changeLocalNetworkButton; - Assert.equal( - BrowserTestUtils.isVisible(localHostSettingsButton), + BrowserTestUtils.isVisible(localHostSettingsRow), enabled, "localhost permissions toggle" ); Assert.equal( - BrowserTestUtils.isVisible(localNetworkSettingsButton), + BrowserTestUtils.isVisible(localNetworkSettingsRow), enabled, "localhost permissions toggle" ); diff --git a/browser/components/preferences/tests/browser_permissions_urlFieldHidden.js b/browser/components/preferences/tests/browser_permissions_urlFieldHidden.js @@ -14,12 +14,9 @@ add_task(async function urlFieldVisibleForPopupPermissions() { !popupPolicyCheckbox.checked, "popupPolicyCheckbox should be unchecked by default" ); + popupPolicyCheckbox.click(); let popupPolicyButton = doc.getElementById("popupPolicyButton"); ok(popupPolicyButton, "popupPolicyButton found"); - let popupPolicyButtonAvailable = - waitForSettingControlChange(popupPolicyButton); - popupPolicyCheckbox.click(); - await popupPolicyButtonAvailable; let dialogPromise = promiseLoadSubDialog(PERMISSIONS_URL); popupPolicyButton.click(); let dialog = await dialogPromise; diff --git a/browser/components/preferences/tests/browser_security-1.js b/browser/components/preferences/tests/browser_security-1.js @@ -20,6 +20,20 @@ registerCleanupFunction(function () { ); }); +function waitForSettingChange(setting) { + return new Promise(resolve => { + setting.on("change", function handler() { + setting.off("change", handler); + resolve(); + }); + }); +} + +async function waitForSettingControlChange(control) { + await waitForSettingChange(control.setting); + await new Promise(resolve => requestAnimationFrame(resolve)); +} + // This test only opens the Preferences once, and then reloads the page // each time that it wants to test various preference combinations. We // only use one tab (instead of opening/closing for each test) for all diff --git a/browser/components/preferences/tests/browser_security-2.js b/browser/components/preferences/tests/browser_security-2.js @@ -20,6 +20,20 @@ registerCleanupFunction(function () { ); }); +function waitForSettingChange(setting) { + return new Promise(resolve => { + setting.on("change", function handler() { + setting.off("change", handler); + resolve(); + }); + }); +} + +async function waitForSettingControlChange(control) { + await waitForSettingChange(control.setting); + await new Promise(resolve => requestAnimationFrame(resolve)); +} + // This test only opens the Preferences once, and then reloads the page // each time that it wants to test various preference combinations. We // only use one tab (instead of opening/closing for each test) for all diff --git a/browser/components/preferences/tests/head.js b/browser/components/preferences/tests/head.js @@ -637,17 +637,3 @@ async function clickCheckboxWithConfirmDialog( return checkbox; } - -function waitForSettingChange(setting) { - return new Promise(resolve => { - setting.on("change", function handler() { - setting.off("change", handler); - resolve(); - }); - }); -} - -async function waitForSettingControlChange(control) { - await waitForSettingChange(control.setting); - await new Promise(resolve => requestAnimationFrame(resolve)); -} diff --git a/browser/components/preferences/widgets/setting-element/setting-element.mjs b/browser/components/preferences/widgets/setting-element/setting-element.mjs @@ -114,7 +114,7 @@ export class SettingElement extends MozLitElement { "data-subcategory": config.subcategory, ...config.controlAttrs, }; - if (config.supportPage != undefined) { + if (config.supportPage) { result[".supportPage"] = config.supportPage; } if (config.l10nId) { diff --git a/browser/components/storybook/component-status/components.json b/browser/components/storybook/component-status/components.json @@ -1,5 +1,5 @@ { - "generatedAt": "2025-10-29T17:19:39.854Z", + "generatedAt": "2025-10-15T13:18:04.980Z", "count": 28, "items": [ { diff --git a/browser/locales-preview/privacyPreferences.ftl b/browser/locales-preview/privacyPreferences.ftl @@ -131,80 +131,3 @@ security-privacy-issue-warning-inner-html-ltgt = security-privacy-issue-warning-file-uri-origin = .label = File URI strict origin policy is disabled .description = Files loaded in { -brand-short-name } should be cross-origin from files in the same folder - -## DNS-Over-HTTPS - -preferences-doh-overview-default = - .label = Default - .description = Use secure DNS in regions where it’s available - -preferences-doh-overview-custom = - .label = Custom - .description = You control when to use secure DNS and choose your provider. - -preferences-doh-overview-off = - .label = Off - .description = Use your default DNS resolver - -preferences-doh-advanced-button = - .label = Advanced settings - -preferences-doh-advanced-section = - .label = Advanced settings - .description = Domain Name System (DNS) over HTTPS sends your request for a domain name through an encrypted connection, providing a secure DNS and making it harder for others to see which website you’re about to access. - -preferences-doh-manage-exceptions2 = - .label = Manage exceptions - .accesskey = x - -preferences-doh-radio-default = - .label = Default (when available) - .description = Use secure DNS in regions where it’s available - -preferences-doh-radio-custom = - .label = Custom (always on) - -preferences-doh-radio-off = - .label = Off - .description = Use your default DNS resolver - -preferences-doh-fallback-label = - .label = Always fallback to default DNS - .description = Fall back to your default DNS resolver if there is a problem with secure DNS - -preferences-doh-status-item-off = - .message = DNS-over-HTTPS is off - -## Variables: -## $reason (string) - A string representation of the reason DoH is not active. For example NS_ERROR_UNKNOWN_HOST or TRR_RCODE_FAIL. -## $name (string) - The name of the DNS over HTTPS resolver. If a custom resolver is used, the name will be the domain of the URL. - -preferences-doh-status-item-not-active = - .message = DNS-over-HTTPS is not working because we encountered an error ({ $reason }) while trying to use the provider { $name } - -preferences-doh-status-item-not-active-bad-url = - .message = DNS-over-HTTPS is not working because we received an invalid URL ({ $reason }) - -preferences-doh-status-item-active = - .message = DNS-over-HTTPS is using the provider { $name } - -preferences-doh-status-item-not-active-local = - .message = DNS-over-HTTPS is not working because we encountered an error ({ $reason }) while trying to use the local provider { $name } - -preferences-doh-status-item-active-local = - .message = DNS-over-HTTPS is using the local provider { $name } - -preferences-doh-select-resolver-label = - .label = Choose provider - -# Variables: -# $name (String) - Display name or URL for the DNS over HTTPS provider -connection-dns-over-https-url-item = - .label = { $name } - .tooltiptext = Use this provider for resolving DNS over HTTPS - -preferences-doh-custom-provider-label = - .aria-label = Enter a custom provider URL - -preferences-doh-header2 = - .heading = DNS over HTTPS diff --git a/browser/locales/en-US/browser/preferences/preferences.ftl b/browser/locales/en-US/browser/preferences/preferences.ftl @@ -1514,41 +1514,59 @@ tracking-manage-exceptions = ## Privacy Section - Permissions -permissions-header2 = - .label = Permissions - .description = Permissions you give to websites you browse. +permissions-header = Permissions -permissions-location2 = - .label = Location +permissions-location = Location +permissions-location-settings = + .label = Settings… + .accesskey = t -permissions-localhost2 = - .label = Device apps and services +permissions-localhost = Device apps and services +permissions-localhost-settings = + .label = Settings… + .accesskey = t -permissions-local-network2 = - .label = Local network devices +permissions-local-network = Local Network Devices +permissions-local-network-settings = + .label = Settings… + .accesskey = t -permissions-xr2 = - .label = Virtual reality +permissions-xr = Virtual Reality +permissions-xr-settings = + .label = Settings… + .accesskey = t -permissions-camera2 = - .label = Camera +permissions-camera = Camera +permissions-camera-settings = + .label = Settings… + .accesskey = t -permissions-microphone2 = - .label = Microphone +permissions-microphone = Microphone +permissions-microphone-settings = + .label = Settings… + .accesskey = t -# Privacy permission for sound output devices. -permissions-speaker2 = - .label = Speaker +# Short form for "the act of choosing sound output devices and redirecting audio to the chosen devices". +permissions-speaker = Speaker Selection +permissions-speaker-settings = + .label = Settings… + .accesskey = t -permissions-notification2 = - .label = Notifications +permissions-notification = Notifications +permissions-notification-settings = + .label = Settings… + .accesskey = t +permissions-notification-link = Learn more permissions-notification-pause = .label = Pause notifications until { -brand-short-name } restarts .accesskey = n -permissions-autoplay2 = - .label = Autoplay +permissions-autoplay = Autoplay + +permissions-autoplay-settings = + .label = Settings… + .accesskey = t permissions-block-popups2 = .label = Block pop-ups and third-party redirects @@ -1556,17 +1574,17 @@ permissions-block-popups2 = # "popup" is a misspelling that is more popular than the correct spelling of # "pop-up" so it's included as a search keyword, not displayed in the UI. -permissions-block-popups-exceptions-button2 = - .label = Manage pop-up and third-party redirect exceptions +permissions-block-popups-exceptions-button = + .label = Exceptions… .accesskey = E .searchkeywords = popups -permissions-addon-install-warning2 = - .label = Warn when websites try to install extensions +permissions-addon-install-warning = + .label = Warn you when websites try to install add-ons .accesskey = W -permissions-addon-exceptions2 = - .label = Choose which websites can install extensions +permissions-addon-exceptions = + .label = Exceptions… .accesskey = E ## Privacy Section - Data Collection diff --git a/browser/themes/shared/preferences/preferences.css b/browser/themes/shared/preferences/preferences.css @@ -1479,7 +1479,3 @@ richlistitem .text-link:hover { font-size: var(--font-size-small); } } - -#dohProviderSelect { - --select-max-width: 235px; -} diff --git a/python/l10n/fluent_migrations/bug_1972371_preferences_permissions.py b/python/l10n/fluent_migrations/bug_1972371_preferences_permissions.py @@ -1,35 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ - -from fluent.migrate import COPY_PATTERN -from fluent.migrate.helpers import transforms_from - - -def migrate(ctx): - """Bug 1972371 - Migrate permissions settings content for the settings redesign part {index}.""" - path = "browser/browser/preferences/preferences.ftl" - ctx.add_transforms( - path, - path, - transforms_from( - """ -permissions-location2 = - .label = {COPY_PATTERN(from_path, "permissions-location")} -permissions-localhost2 = - .label = {COPY_PATTERN(from_path, "permissions-localhost")} -permissions-local-network2 = - .label = {COPY_PATTERN(from_path, "permissions-local-network")} -permissions-xr2 = - .label = {COPY_PATTERN(from_path, "permissions-xr")} -permissions-camera2 = - .label = {COPY_PATTERN(from_path, "permissions-camera")} -permissions-microphone2 = - .label = {COPY_PATTERN(from_path, "permissions-microphone")} -permissions-notification2 = - .label = {COPY_PATTERN(from_path, "permissions-notification")} -permissions-autoplay2 = - .label = {COPY_PATTERN(from_path, "permissions-autoplay")} -""", - from_path=path, - ), - ) diff --git a/toolkit/content/tests/widgets/test_moz_message_bar.html b/toolkit/content/tests/widgets/test_moz_message_bar.html @@ -46,12 +46,6 @@ <moz-message-bar id="messageWithLink" message="Test message"> <a slot="support-link" href="#learn-less">Learn less</a> </moz-message-bar> - <moz-message-bar - id="messageWithSupportPage" - message="Test message" - support-page="support-test" - > - </moz-message-bar> <moz-message-bar id="slottedMessage"> <span slot="message" >Here is a message with a nested @@ -163,40 +157,6 @@ is(iconAlt, "Error", "Alternate text for the error icon is present."); }); - add_task(async function test_support_page_attribute() { - const mozMessageBar = document.querySelector("#messageWithSupportPage"); - const link = mozMessageBar.querySelector("[is='moz-support-link']"); - const msgEl = mozMessageBar.messageEl; - is(mozMessageBar.supportLinkEls[0], link, "Link is assigned"); - // Inspect internal class name - this is relied upon to toggle the - // visibility of the gap between the message and link (bug 1938906). - is(msgEl.className, "message has-link-after", "Expected class list"); - - link.remove(); - await mozMessageBar.updateComplete; - is(msgEl.className, "message", "has-link-after class should be gone"); - - mozMessageBar.append(link); - await mozMessageBar.updateComplete; - is(msgEl.className, "message has-link-after", "class should be back"); - - mozMessageBar.message = "Different test message"; - await mozMessageBar.updateComplete; - is( - msgEl.className, - "message has-link-after", - "class should not change" - ); - - mozMessageBar.message = "Test message"; - await mozMessageBar.updateComplete; - is( - msgEl.className, - "message has-link-after", - "class should not change" - ); - }); - add_task(async function test_support_link_slot() { const mozMessageBar = document.querySelector("#messageWithLink"); const link = mozMessageBar.querySelector("[href='#learn-less']"); diff --git a/toolkit/content/widgets/lit-select-control.mjs b/toolkit/content/widgets/lit-select-control.mjs @@ -271,6 +271,12 @@ export class SelectControlBaseElement extends MozLitElement { }); } + // Re-dispatch change event so it's re-targeted to the custom element. + handleChange(event) { + event.stopPropagation(); + this.dispatchEvent(new Event(event.type, event)); + } + handleSlotChange() { this.#childElements = null; this.#focusedIndex = undefined; diff --git a/toolkit/content/widgets/moz-message-bar/moz-message-bar.mjs b/toolkit/content/widgets/moz-message-bar/moz-message-bar.mjs @@ -54,7 +54,6 @@ export default class MozMessageBar extends MozLitElement { closeButton: "moz-button.close", messageEl: ".message", supportLinkSlot: "slot[name=support-link]", - supportLinkHolder: ".link", }; static properties = { @@ -62,7 +61,6 @@ export default class MozMessageBar extends MozLitElement { heading: { type: String, fluent: true }, message: { type: String, fluent: true }, dismissable: { type: Boolean }, - supportPage: { type: String }, messageL10nId: { type: String }, messageL10nArgs: { type: String }, }; @@ -136,27 +134,9 @@ export default class MozMessageBar extends MozLitElement { } get supportLinkEls() { - if (this.supportPage) { - return this.supportLinkHolder.childElements(); - } return this.supportLinkSlot.assignedElements(); } - supportLinkTemplate() { - if (this.supportPage) { - return html`<a - is="moz-support-link" - support-page=${this.supportPage} - part="support-link" - aria-describedby="heading message" - ></a>`; - } - return html`<slot - name="support-link" - @slotchange=${this.onLinkSlotChange} - ></slot>`; - } - iconTemplate() { let iconData = messageTypeToIconData[this.type]; if (iconData) { @@ -212,7 +192,6 @@ export default class MozMessageBar extends MozLitElement { <div> <slot name="message"> <span - id="message" class="message" data-l10n-id=${ifDefined(this.messageL10nId)} data-l10n-args=${ifDefined( @@ -222,7 +201,12 @@ export default class MozMessageBar extends MozLitElement { ${this.message} </span> </slot> - <span class="link"> ${this.supportLinkTemplate()} </span> + <span class="link"> + <slot + name="support-link" + @slotchange=${this.onLinkSlotChange} + ></slot> + </span> </div> </div> </div>