tor-browser

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

commit 68d1b36f5c567fcd1ce61f6c539b775552cb9156
parent 8262ad82b134b5ae6792b4d3fc6eb87dd47724c4
Author: Alexandru Marc <amarc@mozilla.com>
Date:   Tue, 11 Nov 2025 14:27:38 +0200

Revert (Bug 1997393, Bug 1971438, Bug 1997185) for causing bc failures @ browser_sanitizeDialog_v2.js

This reverts commit d08dee73fb25d0ed16b6d3d218f43447253065b5.

Revert "Bug 1971438 - Support setting 'disabled' and 'hidden' properties via 'option' config. r=hjones"

This reverts commit 0a681e6e150c451fec42f3be55c0499fd7571116.

Revert "Bug 1997393 - Support hidden options in moz-select. r=hjones"

This reverts commit fcf324e8a5310b0b6a27e176ebaac0230a522c70.

Revert "Bug 1997185 - Support disabled options in moz-select. r=hjones"

This reverts commit a85d406b833ea40b186e711ea2aeaec658bd3af4.

Revert "Bug 1971438 - Update tests for history preferences section. r=mconley"

This reverts commit 00e35ddfe9b0328755e868ea3b87e30c93adbf2e.

Revert "Bug 1971438 - Convert History to config-based prefs. r=fluent-reviewers,mconley,bolsson"

This reverts commit 8079415014df7d78a02fb1a8abab981e081b842c.

Diffstat:
Mbrowser/components/enterprisepolicies/tests/browser/browser_policy_privatebrowsingmodeavailability.js | 5++---
Mbrowser/components/preferences/main.js | 67-------------------------------------------------------------------
Mbrowser/components/preferences/privacy.inc.xhtml | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mbrowser/components/preferences/privacy.js | 576++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mbrowser/components/preferences/tests/browser_cookies_exceptions.js | 5+++--
Mbrowser/components/preferences/tests/browser_privacy_syncDataClearing.js | 15++++-----------
Mbrowser/components/preferences/tests/browser_privacy_syncDataClearing_v2.js | 16++++------------
Mbrowser/components/preferences/tests/browser_warning_permanent_private_browsing.js | 8+++-----
Mbrowser/components/preferences/tests/head.js | 66------------------------------------------------------------------
Mbrowser/components/preferences/tests/privacypane_tests_perwindow.js | 124++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mbrowser/components/preferences/widgets/setting-control/setting-control.mjs | 2--
Mbrowser/locales/en-US/browser/preferences/preferences.ftl | 10++--------
Dpython/l10n/fluent_migrations/bug_1971438_preferences_history.py | 26--------------------------
Mtoolkit/content/tests/widgets/test_moz_select.html | 74--------------------------------------------------------------------------
Mtoolkit/content/widgets/moz-select/moz-select.mjs | 14+-------------
Mtoolkit/content/widgets/moz-select/moz-select.stories.mjs | 18+-----------------
16 files changed, 507 insertions(+), 611 deletions(-)

diff --git a/browser/components/enterprisepolicies/tests/browser/browser_policy_privatebrowsingmodeavailability.js b/browser/components/enterprisepolicies/tests/browser/browser_policy_privatebrowsingmodeavailability.js @@ -27,9 +27,8 @@ add_task(async function test_privatebrowsing_disabled() { "about:preferences#privacy", async browser => { ok( - browser.contentDocument - .getElementById("historyMode") - .inputEl.querySelector("option[value='dontremember']").disabled, + browser.contentDocument.querySelector("menuitem[value='dontremember']") + .disabled, "Don't remember history should be disabled" ); } diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js @@ -1686,73 +1686,6 @@ let SETTINGS_CONFIG = { }, ], }, - history: { - items: [ - { - id: "historyMode", - control: "moz-select", - options: [ - { - value: "remember", - l10nId: "history-remember-option-all", - }, - { value: "dontremember", l10nId: "history-remember-option-never" }, - { value: "custom", l10nId: "history-remember-option-custom" }, - ], - controlAttrs: { - "search-l10n-ids": ` - history-remember-description2, - history-dontremember-description2, - history-private-browsing-permanent.label, - history-remember-browser-option.label, - history-remember-search-option.label, - history-clear-on-close-option.label, - history-clear-on-close-settings.label - `, - }, - }, - { - id: "privateBrowsingAutoStart", - l10nId: "history-private-browsing-permanent", - }, - { - id: "rememberHistory", - l10nId: "history-remember-browser-option", - }, - { - id: "rememberForms", - l10nId: "history-remember-search-option", - }, - { - id: "alwaysClear", - l10nId: "history-clear-on-close-option", - }, - { - id: "clearDataSettings", - l10nId: "history-clear-on-close-settings", - control: "moz-box-button", - controlAttrs: { - "search-l10n-ids": ` - clear-data-settings-label, - history-section-label, - item-history-and-downloads.label, - item-cookies.label, - item-active-logins.label, - item-cache.label, - item-form-search-history.label, - data-section-label, - item-site-settings.label, - item-offline-apps.label - `, - }, - }, - { - id: "clearHistoryButton", - l10nId: "history-clear-button", - control: "moz-box-button", - }, - ], - }, }; /** diff --git a/browser/components/preferences/privacy.inc.xhtml b/browser/components/preferences/privacy.inc.xhtml @@ -567,9 +567,97 @@ </groupbox> <!-- History --> -<groupbox id="historyGroup" data-category="panePrivacy" hidden="true" aria-describedby="totalSiteDataSize"> +<groupbox id="historyGroup" data-category="panePrivacy" hidden="true"> <label><html:h2 data-l10n-id="history-header"/></label> - <html:setting-group groupid="history"/> + <hbox align="center"> + <label id="historyModeLabel" + control="historyMode" + data-l10n-id="history-remember-label"/> + <menulist id="historyMode"> + <menupopup> + <menuitem data-l10n-id="history-remember-option-all" + value="remember" + search-l10n-ids="history-remember-description"/> + <menuitem data-l10n-id="history-remember-option-never" + value="dontremember" + search-l10n-ids="history-dontremember-description"/> + <menuitem data-l10n-id="history-remember-option-custom" + value="custom" + search-l10n-ids=" + history-private-browsing-permanent.label, + history-remember-browser-option.label, + history-remember-search-option.label, + history-clear-on-close-option.label, + history-clear-on-close-settings.label"/> + </menupopup> + </menulist> + </hbox> + <hbox> + <deck id="historyPane" flex="1"> + <vbox id="historyRememberPane"> + <hbox align="center" flex="1"> + <vbox flex="1"> + <description + class="description-with-side-element" + data-l10n-id="history-remember-description"/> + </vbox> + </hbox> + </vbox> + <vbox id="historyDontRememberPane"> + <hbox align="center" flex="1"> + <vbox flex="1"> + <description + class="description-with-side-element" + data-l10n-id="history-dontremember-description"/> + </vbox> + </hbox> + </vbox> + <vbox id="historyCustomPane"> + <vbox> + <checkbox id="privateBrowsingAutoStart" + data-l10n-id="history-private-browsing-permanent" + preference="browser.privatebrowsing.autostart"/> + <vbox class="indent"> + <checkbox id="rememberHistory" + data-l10n-id="history-remember-browser-option" + preference="places.history.enabled"/> + <checkbox id="rememberForms" + data-l10n-id="history-remember-search-option" + preference="browser.formfill.enable"/> + <hbox id="clearDataBox" + align="center"> + <checkbox id="alwaysClear" + preference="privacy.sanitize.sanitizeOnShutdown" + data-l10n-id="history-clear-on-close-option" + flex="1" /> + </hbox> + </vbox> + </vbox> + </vbox> + </deck> + <vbox id="historyButtons" align="end"> + <button id="clearHistoryButton" + is="highlightable-button" + class="accessory-button" + data-l10n-id="history-clear-button"/> + <button id="clearDataSettings" + is="highlightable-button" + class="accessory-button" + data-l10n-id="history-clear-on-close-settings" + search-l10n-ids=" + clear-data-settings-label, + history-section-label, + item-history-and-downloads.label, + item-cookies.label, + item-active-logins.label, + item-cache.label, + item-form-search-history.label, + data-section-label, + item-site-settings.label, + item-offline-apps.label + "/> + </vbox> + </hbox> </groupbox> <hbox id="permissionsCategory" diff --git a/browser/components/preferences/privacy.js b/browser/components/preferences/privacy.js @@ -1597,11 +1597,17 @@ Preferences.addSetting({ }, }); +// Register the setting for simpler access in settings that depend on this, but it hasn't been converted yet. +Preferences.addSetting({ + id: "privateBrowsingAutostart", + pref: "browser.privatebrowsing.autostart", +}); + Preferences.addSetting({ id: "deleteOnCloseInfo", - deps: ["privateBrowsingAutoStart"], - visible({ privateBrowsingAutoStart }) { - return privateBrowsingAutoStart.value; + deps: ["privateBrowsingAutostart"], + visible({ privateBrowsingAutostart }) { + return privateBrowsingAutostart.value; }, }); @@ -1775,9 +1781,9 @@ Preferences.addSetting({ "clearOnCloseCache", "clearOnCloseStorage", "sanitizeOnShutdown", - "privateBrowsingAutoStart", + "privateBrowsingAutostart", + "historyModeCustom", "cookieBehavior", - "alwaysClear", ], setup() { // Make sure to do the migration for the clear history dialog before implementing logic for delete on close @@ -1785,20 +1791,21 @@ Preferences.addSetting({ // overwriting prefs Sanitizer.maybeMigratePrefs("clearOnShutdown"); }, - disabled({ privateBrowsingAutoStart, cookieBehavior }) { + disabled({ privateBrowsingAutostart, cookieBehavior }) { return ( - privateBrowsingAutoStart.value || + privateBrowsingAutostart.value || cookieBehavior.value == Ci.nsICookieService.BEHAVIOR_REJECT ); }, - get(_, { privateBrowsingAutoStart }) { + get(_, { privateBrowsingAutostart }) { return ( - isCookiesAndStorageClearingOnShutdown() || privateBrowsingAutoStart.value + isCookiesAndStorageClearingOnShutdown() || privateBrowsingAutostart.value ); }, set( value, { + historyModeCustom, clearOnCloseCookies, clearOnCloseCache, clearOnCloseStorage, @@ -1819,240 +1826,14 @@ Preferences.addSetting({ // If no other cleaning category is selected, sanitizeOnShutdown gets synced with deleteOnClose sanitizeOnShutdown.value = gPrivacyPane._isCustomCleaningPrefPresent() || value; - }, -}); -Preferences.addSetting({ - id: "historyModeCustom", - pref: "privacy.history.custom", -}); -Preferences.addSetting({ - id: "historyEnabled", - pref: "places.history.enabled", -}); -Preferences.addSetting({ - id: "formFillEnabled", - pref: "browser.formfill.enable", -}); - -// Store this on the window so tests can suppress the prompt. -window._shouldPromptForRestartPBM = true; -async function onChangePrivateBrowsingAutoStart(value, revertFn) { - if (!window._shouldPromptForRestartPBM) { - return false; - } - - // The PBM autostart pref has changed so we need to prompt for restart. - let buttonIndex = await confirmRestartPrompt(value, 1, true, false); - - // User accepts, restart the browser. - if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) { - Services.startup.quit( - Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart - ); - return false; - } - - // Don't prompt for the revert operation itself. - window._shouldPromptForRestartPBM = false; - revertFn(); - window._shouldPromptForRestartPBM = true; - - // User cancels, do nothing. The caller will clean up the pref change. - return true; -} - -Preferences.addSetting({ - id: "historyMode", - deps: [ - "historyModeCustom", - "privateBrowsingAutoStart", - "historyEnabled", - "formFillEnabled", - "sanitizeOnShutdown", - ], - get( - _, - { - historyModeCustom, - privateBrowsingAutoStart, - historyEnabled, - formFillEnabled, - sanitizeOnShutdown, - } - ) { - if (historyModeCustom.value) { - return "custom"; - } - - if (privateBrowsingAutoStart.value) { - return "dontremember"; - } - - if ( - historyEnabled.value && - formFillEnabled.value && - !sanitizeOnShutdown.value - ) { - return "remember"; - } - - return "custom"; - }, - set( - value, - { - historyModeCustom, - privateBrowsingAutoStart, - historyEnabled, - formFillEnabled, - sanitizeOnShutdown, - } - ) { - let lastHistoryModeCustom = historyModeCustom.value; - let lastHistoryEnabled = historyEnabled.value; - let lastFormFillEnabled = formFillEnabled.value; - let lastSanitizeOnShutdown = sanitizeOnShutdown.value; - let lastPrivateBrowsingAutoStart = privateBrowsingAutoStart.value; - - historyModeCustom.value = value == "custom"; - - if (value == "remember") { - historyEnabled.value = true; - formFillEnabled.value = true; - sanitizeOnShutdown.value = false; - privateBrowsingAutoStart.value = false; - } else if (value == "dontremember") { - privateBrowsingAutoStart.value = true; - } - - if (privateBrowsingAutoStart.value !== lastPrivateBrowsingAutoStart) { - // The PBM autostart pref has changed so we need to prompt for restart. - onChangePrivateBrowsingAutoStart(privateBrowsingAutoStart.value, () => { - // User cancelled the action, revert the change. - // Simply reverting the setting value itself is not enough, because a - // state transition to "custom" does not override any of the sub-prefs. - // We need to update them all manually. - historyModeCustom.value = lastHistoryModeCustom; - historyEnabled.value = lastHistoryEnabled; - formFillEnabled.value = lastFormFillEnabled; - sanitizeOnShutdown.value = lastSanitizeOnShutdown; - privateBrowsingAutoStart.value = lastPrivateBrowsingAutoStart; - }); - } - }, - disabled({ privateBrowsingAutoStart }) { - // Disable history dropdown if PBM autostart is locked on. - return privateBrowsingAutoStart.locked && privateBrowsingAutoStart.value; - }, - getControlConfig(config, { privateBrowsingAutoStart }, setting) { - let l10nId = null; - if (setting.value == "remember") { - l10nId = "history-remember-description2"; - } else if (setting.value == "dontremember") { - l10nId = "history-dontremember-description2"; - } else if (setting.value == "custom") { - l10nId = "history-custom-description"; + // Update the view of the history settings + if (value && !historyModeCustom.value) { + historyModeCustom.value = true; + gPrivacyPane.initializeHistoryMode(); + gPrivacyPane.updateHistoryModePane(); + gPrivacyPane.updatePrivacyMicroControls(); } - - let dontRememberOption = config.options.find( - opt => opt.value == "dontremember" - ); - - // If PBM is unavailable hide the "Never remember history" option. - dontRememberOption.hidden = !PrivateBrowsingUtils.enabled; - - // If the PBM autostart pref is locked disable the "Never remember history" - // option. - dontRememberOption.disabled = - privateBrowsingAutoStart.locked && !privateBrowsingAutoStart.value; - - return { - ...config, - l10nId, - }; - }, -}); - -Preferences.addSetting({ - id: "privateBrowsingAutoStart", - pref: "browser.privatebrowsing.autostart", - deps: ["historyMode"], - onUserChange(value, _, setting) { - onChangePrivateBrowsingAutoStart(value, () => { - // User cancelled the action, revert the setting. - setting.value = !value; - }); - }, - visible({ historyMode }) { - return PrivateBrowsingUtils.enabled && historyMode.value == "custom"; - }, -}); -Preferences.addSetting({ - id: "rememberHistory", - pref: "places.history.enabled", - deps: ["historyMode", "privateBrowsingAutoStart"], - visible({ historyMode }) { - return historyMode.value == "custom"; - }, - disabled({ privateBrowsingAutoStart }) { - return privateBrowsingAutoStart.value; - }, -}); -Preferences.addSetting({ - id: "rememberForms", - pref: "browser.formfill.enable", - deps: ["historyMode", "privateBrowsingAutoStart"], - visible({ historyMode }) { - return historyMode.value == "custom"; - }, - disabled({ privateBrowsingAutoStart }) { - return privateBrowsingAutoStart.value; - }, -}); -Preferences.addSetting({ - id: "alwaysClear", - pref: "privacy.sanitize.sanitizeOnShutdown", - deps: ["historyMode", "privateBrowsingAutoStart"], - visible({ historyMode }) { - return historyMode.value == "custom"; - }, - disabled({ privateBrowsingAutoStart }) { - return privateBrowsingAutoStart.value; - }, -}); - -Preferences.addSetting({ - id: "clearDataSettings", - deps: ["historyMode", "alwaysClear"], - visible({ historyMode }) { - return historyMode.value == "custom"; - }, - disabled({ alwaysClear }) { - return !alwaysClear.value || alwaysClear.disabled; - }, - onUserClick() { - let dialogFile = useOldClearHistoryDialog - ? "chrome://browser/content/preferences/dialogs/sanitize.xhtml" - : "chrome://browser/content/sanitize_v2.xhtml"; - - gSubDialog.open( - dialogFile, - { - features: "resizable=no", - }, - { - mode: "clearOnShutdown", - } - ); - }, -}); - -Preferences.addSetting({ - id: "clearHistoryButton", - deps: ["historyMode"], - onUserClick(_, { historyMode }) { - gPrivacyPane.clearPrivateDataNow(historyMode.value == "dontremember"); }, }); @@ -2659,7 +2440,12 @@ var gPrivacyPane = { initSettingGroup("cookiesAndSiteData"); initSettingGroup("certificates"); initSettingGroup("ipprotection"); - initSettingGroup("history"); + + this._updateSanitizeSettingsButton(); + this.initializeHistoryMode(); + this.updateHistoryModePane(); + this.updatePrivacyMicroControls(); + this.initAutoStartPrivateBrowsingReverter(); /* Initialize Content Blocking */ this.initContentBlocking(); @@ -2709,12 +2495,42 @@ var gPrivacyPane = { gPrivacyPane.showTrackingProtectionExceptions ); + Preferences.get("privacy.sanitize.sanitizeOnShutdown").on( + "change", + gPrivacyPane._updateSanitizeSettingsButton.bind(gPrivacyPane) + ); + Preferences.get("browser.privatebrowsing.autostart").on( + "change", + gPrivacyPane.updatePrivacyMicroControls.bind(gPrivacyPane) + ); + setEventListener("historyMode", "command", function () { + gPrivacyPane.updateHistoryModePane(); + gPrivacyPane.updateHistoryModePrefs(); + gPrivacyPane.updatePrivacyMicroControls(); + gPrivacyPane.updateAutostart(); + }); + setEventListener("clearHistoryButton", "command", function () { + let historyMode = document.getElementById("historyMode"); + // Select "everything" in the clear history dialog if the + // user has set their history mode to never remember history. + gPrivacyPane.clearPrivateDataNow(historyMode.value == "dontremember"); + }); + setEventListener( + "privateBrowsingAutoStart", + "command", + gPrivacyPane.updateAutostart + ); setEventListener( "dohExceptionsButton", "command", gPrivacyPane.showDoHExceptions ); setEventListener( + "clearDataSettings", + "command", + gPrivacyPane.showClearPrivateDataSettings + ); + setEventListener( "passwordExceptions", "command", gPrivacyPane.showPasswordExceptions @@ -2818,6 +2634,12 @@ var gPrivacyPane = { setSyncFromPrefListener("savePasswords", () => this.readSavePasswords()); + let microControlHandler = el => + this.ensurePrivacyMicroControlUncheckedWhenDisabled(el); + setSyncFromPrefListener("rememberHistory", microControlHandler); + setSyncFromPrefListener("rememberForms", microControlHandler); + setSyncFromPrefListener("alwaysClear", microControlHandler); + setSyncFromPrefListener("popupPolicy", () => this.updateButtons("popupPolicyButton", "dom.disable_open_during_load") ); @@ -2867,6 +2689,26 @@ var gPrivacyPane = { appendSearchKeywords("showPasswords", [ signonBundle.getString("loginsDescriptionAll2"), ]); + if (!PrivateBrowsingUtils.enabled) { + document.getElementById("privateBrowsingAutoStart").hidden = true; + document.querySelector("menuitem[value='dontremember']").hidden = true; + } + + let privateBrowsingPref = Preferences.get( + "browser.privatebrowsing.autostart" + ); + + if (privateBrowsingPref.locked) { + // If permanent private browsing mode is locked to off, + // disable the "Never Remember History" option + document.querySelector("menuitem[value='dontremember']").disabled = + !privateBrowsingPref.value; + + // If we're locked in permanent private browsing mode, + // disable the dropdown menu completely + document.getElementById("historyMode").disabled = + privateBrowsingPref.value; + } setEventListener( "contentBlockingBaselineExceptionsStrict", @@ -3530,6 +3372,175 @@ var gPrivacyPane = { ); }, + // HISTORY MODE + + /** + * The list of preferences which affect the initial history mode settings. + * If the auto start private browsing mode pref is active, the initial + * history mode would be set to "Don't remember anything". + * If ALL of these preferences are set to the values that correspond + * to keeping some part of history, and the auto-start + * private browsing mode is not active, the initial history mode would be + * set to "Remember everything". + * Otherwise, the initial history mode would be set to "Custom". + * + * Extensions adding their own preferences can set values here if needed. + */ + prefsForKeepingHistory: { + "places.history.enabled": true, // History is enabled + "browser.formfill.enable": true, // Form information is saved + "privacy.sanitize.sanitizeOnShutdown": false, // Private date is NOT cleared on shutdown + }, + + /** + * The list of control IDs which are dependent on the auto-start private + * browsing setting, such that in "Custom" mode they would be disabled if + * the auto-start private browsing checkbox is checked, and enabled otherwise. + * + * Extensions adding their own controls can append their IDs to this array if needed. + */ + dependentControls: [ + "rememberHistory", + "rememberForms", + "alwaysClear", + "clearDataSettings", + ], + + /** + * Check whether preferences values are set to keep history + * + * @param aPrefs an array of pref names to check for + * @returns boolean true if all of the prefs are set to keep history, + * false otherwise + */ + _checkHistoryValues(aPrefs) { + for (let pref of Object.keys(aPrefs)) { + if (Preferences.get(pref).value != aPrefs[pref]) { + return false; + } + } + return true; + }, + + /** + * Initialize the history mode menulist based on the privacy preferences + */ + initializeHistoryMode() { + let mode; + let getVal = aPref => Preferences.get(aPref).value; + + if (getVal("privacy.history.custom")) { + mode = "custom"; + } else if (this._checkHistoryValues(this.prefsForKeepingHistory)) { + if (getVal("browser.privatebrowsing.autostart")) { + mode = "dontremember"; + } else { + mode = "remember"; + } + } else { + mode = "custom"; + } + + document.getElementById("historyMode").value = mode; + }, + + /** + * Update the selected pane based on the history mode menulist + */ + updateHistoryModePane() { + let selectedIndex = -1; + switch (document.getElementById("historyMode").value) { + case "remember": + selectedIndex = 0; + break; + case "dontremember": + selectedIndex = 1; + break; + case "custom": + selectedIndex = 2; + break; + } + document.getElementById("historyPane").selectedIndex = selectedIndex; + Preferences.get("privacy.history.custom").value = selectedIndex == 2; + }, + + /** + * Update the private browsing auto-start pref and the history mode + * micro-management prefs based on the history mode menulist + */ + updateHistoryModePrefs() { + let pref = Preferences.get("browser.privatebrowsing.autostart"); + switch (document.getElementById("historyMode").value) { + case "remember": + if (pref.value) { + pref.value = false; + } + + // select the remember history option if needed + Preferences.get("places.history.enabled").value = true; + + // select the remember forms history option + Preferences.get("browser.formfill.enable").value = true; + + // select the clear on close option + Preferences.get("privacy.sanitize.sanitizeOnShutdown").value = false; + break; + case "dontremember": + if (!pref.value) { + pref.value = true; + } + break; + } + }, + + /** + * Update the privacy micro-management controls based on the + * value of the private browsing auto-start preference. + */ + updatePrivacyMicroControls() { + let clearDataSettings = document.getElementById("clearDataSettings"); + + if (document.getElementById("historyMode").value == "custom") { + let disabled = Preferences.get("browser.privatebrowsing.autostart").value; + this.dependentControls.forEach(aElement => { + let control = document.getElementById(aElement); + let preferenceId = control.getAttribute("preference"); + if (!preferenceId) { + let dependentControlId = control.getAttribute("control"); + if (dependentControlId) { + let dependentControl = document.getElementById(dependentControlId); + preferenceId = dependentControl.getAttribute("preference"); + } + } + + let preference = preferenceId ? Preferences.get(preferenceId) : {}; + control.disabled = disabled || preference.locked; + if (control != clearDataSettings) { + this.ensurePrivacyMicroControlUncheckedWhenDisabled(control); + } + }); + + clearDataSettings.removeAttribute("hidden"); + + if (!disabled) { + // adjust the Settings button for sanitizeOnShutdown + this._updateSanitizeSettingsButton(); + } + } else { + clearDataSettings.hidden = true; + } + }, + + ensurePrivacyMicroControlUncheckedWhenDisabled(el) { + if (Preferences.get("browser.privatebrowsing.autostart").value) { + // Set checked to false when called from updatePrivacyMicroControls + el.checked = false; + // return false for the onsyncfrompreference case: + return false; + } + return undefined; // tell preferencesBindings to assign the 'right' value. + }, + // CLEAR PRIVATE DATA /* @@ -3602,10 +3613,91 @@ var gPrivacyPane = { ); }, + /** + * Enables or disables the "Settings..." button depending + * on the privacy.sanitize.sanitizeOnShutdown preference value + */ + _updateSanitizeSettingsButton() { + var settingsButton = document.getElementById("clearDataSettings"); + var sanitizeOnShutdownPref = Preferences.get( + "privacy.sanitize.sanitizeOnShutdown" + ); + + settingsButton.disabled = !sanitizeOnShutdownPref.value; + }, + toggleDoNotDisturbNotifications(event) { AlertsServiceDND.manualDoNotDisturb = event.target.checked; }, + // PRIVATE BROWSING + + /** + * Initialize the starting state for the auto-start private browsing mode pref reverter. + */ + initAutoStartPrivateBrowsingReverter() { + // We determine the mode in initializeHistoryMode, which is guaranteed to have been + // called before now, so this is up-to-date. + let mode = document.getElementById("historyMode"); + this._lastMode = mode.selectedIndex; + // The value of the autostart pref, on the other hand, is gotten from Preferences, + // which updates the DOM asynchronously, so we can't rely on the DOM. Get it directly + // from the prefs. + this._lastCheckState = Preferences.get( + "browser.privatebrowsing.autostart" + ).value; + }, + + _lastMode: null, + _lastCheckState: null, + async updateAutostart() { + let mode = document.getElementById("historyMode"); + let autoStart = document.getElementById("privateBrowsingAutoStart"); + let pref = Preferences.get("browser.privatebrowsing.autostart"); + if ( + (mode.value == "custom" && this._lastCheckState == autoStart.checked) || + (mode.value == "remember" && !this._lastCheckState) || + (mode.value == "dontremember" && this._lastCheckState) + ) { + // These are all no-op changes, so we don't need to prompt. + this._lastMode = mode.selectedIndex; + this._lastCheckState = autoStart.hasAttribute("checked"); + return; + } + + if (!this._shouldPromptForRestart) { + // We're performing a revert. Just let it happen. + return; + } + + let buttonIndex = await confirmRestartPrompt( + autoStart.checked, + 1, + true, + false + ); + if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) { + pref.value = autoStart.hasAttribute("checked"); + Services.startup.quit( + Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart + ); + return; + } + + this._shouldPromptForRestart = false; + + if (this._lastCheckState) { + autoStart.checked = "checked"; + } else { + autoStart.removeAttribute("checked"); + } + pref.value = autoStart.hasAttribute("checked"); + mode.selectedIndex = this._lastMode; + mode.doCommand(); + + this._shouldPromptForRestart = true; + }, + /** * Displays fine-grained, per-site preferences for tracking protection. */ diff --git a/browser/components/preferences/tests/browser_cookies_exceptions.js b/browser/components/preferences/tests/browser_cookies_exceptions.js @@ -530,8 +530,9 @@ async function runTest(test, getObservances) { }); let doc = gBrowser.contentDocument; - - await selectHistoryMode(gBrowser.contentWindow, "custom"); + let historyMode = doc.getElementById("historyMode"); + historyMode.value = "custom"; + historyMode.doCommand(); let promiseSubDialogLoaded = promiseLoadSubDialog( "chrome://browser/content/preferences/dialogs/permissions.xhtml" diff --git a/browser/components/preferences/tests/browser_privacy_syncDataClearing.js b/browser/components/preferences/tests/browser_privacy_syncDataClearing.js @@ -26,9 +26,6 @@ add_task(async function test_syncWithoutCustomPrefs() { deleteOnCloseBox.click(); - // Wait for UI to update. - await new Promise(resolve => requestAnimationFrame(resolve)); - ok(deleteOnCloseBox.checked, "DeleteOnClose is selected"); is( deleteOnCloseBox.checked, @@ -54,9 +51,6 @@ add_task(async function test_syncWithoutCustomPrefs() { deleteOnCloseBox.click(); - // Wait for UI to update. - await new Promise(resolve => requestAnimationFrame(resolve)); - ok(!deleteOnCloseBox.checked, "DeleteOnClose is deselected"); is( deleteOnCloseBox.checked, @@ -193,8 +187,6 @@ add_task(async function test_syncWithCustomPrefs() { ["privacy.clearOnShutdown.cache", true], ["privacy.clearOnShutdown.offlineApps", true], ["privacy.sanitize.sanitizeOnShutdown", true], - // Make sure custom is selected so the depending checkboxes are visible. - ["privacy.history.custom", true], ], }); @@ -296,8 +288,9 @@ add_task(async function test_initialState() { ); // Reset history mode - await SpecialPowers.popPrefEnv(); - gBrowser.contentWindow.Preferences.getSetting("historyMode").value = - "remember"; + let historyMode = document.getElementById("historyMode"); + historyMode.value = "remember"; + historyMode.doCommand(); BrowserTestUtils.removeTab(gBrowser.selectedTab); + await SpecialPowers.popPrefEnv(); }); diff --git a/browser/components/preferences/tests/browser_privacy_syncDataClearing_v2.js b/browser/components/preferences/tests/browser_privacy_syncDataClearing_v2.js @@ -29,9 +29,6 @@ add_task(async function test_syncWithoutCustomPrefs() { deleteOnCloseBox.click(); - // Wait for UI to update. - await new Promise(resolve => requestAnimationFrame(resolve)); - ok(deleteOnCloseBox.checked, "DeleteOnClose is selected"); is( deleteOnCloseBox.checked, @@ -67,9 +64,6 @@ add_task(async function test_syncWithoutCustomPrefs() { deleteOnCloseBox.click(); - // Wait for UI to update. - await new Promise(resolve => requestAnimationFrame(resolve)); - ok(!deleteOnCloseBox.checked, "DeleteOnClose is deselected"); is( deleteOnCloseBox.checked, @@ -167,9 +161,6 @@ add_task(async function test_syncWithCustomPrefs() { deleteOnCloseBox.click(); - // Wait for UI to update. - await new Promise(resolve => requestAnimationFrame(resolve)); - ok(!deleteOnCloseBox.checked, "DeleteOnClose is deselected"); is( !deleteOnCloseBox.checked, @@ -321,8 +312,9 @@ add_task(async function test_initialState() { ); // Reset history mode - await SpecialPowers.popPrefEnv(); - gBrowser.contentWindow.Preferences.getSetting("historyMode").value = - "remember"; + let historyMode = document.getElementById("historyMode"); + historyMode.value = "remember"; + historyMode.doCommand(); BrowserTestUtils.removeTab(gBrowser.selectedTab); + await SpecialPowers.popPrefEnv(); }); diff --git a/browser/components/preferences/tests/browser_warning_permanent_private_browsing.js b/browser/components/preferences/tests/browser_warning_permanent_private_browsing.js @@ -30,11 +30,9 @@ function checkForPrompt(prefVal) { return doc.defaultView.CONFIRM_RESTART_PROMPT_RESTART_NOW; }; // Tick the checkbox and pretend the user did it: - await updateCheckBox( - gBrowser.contentWindow, - "privateBrowsingAutoStart", - prefVal - ); + let checkbox = doc.getElementById("privateBrowsingAutoStart"); + checkbox.checked = prefVal; + checkbox.doCommand(); // Now the prompt should have shown. ok( diff --git a/browser/components/preferences/tests/head.js b/browser/components/preferences/tests/head.js @@ -637,69 +637,3 @@ async function clickCheckboxWithConfirmDialog( return checkbox; } - -/** - * Select the given history mode via dropdown in the privacy pane. - * @param {Window} win - The preferences window which contains the - * dropdown. - * @param {string} value - The history mode to select. - */ -async function selectHistoryMode(win, value) { - let historyMode = win.document.getElementById("historyMode").inputEl; - - // Find the index of the option with the given value. Do this before the first - // click so we can bail out early if the option does not exist. - let optionIndexStr = Array.from(historyMode.children) - .findIndex(option => option.value == value) - ?.toString(); - if (optionIndexStr == null) { - throw new Error( - "Could not find history mode option item for value: " + value - ); - } - - // Scroll into view for click to succeed. - historyMode.scrollIntoView(); - - let popupShownPromise = BrowserTestUtils.waitForSelectPopupShown(window); - - await EventUtils.synthesizeMouseAtCenter( - historyMode, - {}, - historyMode.ownerGlobal - ); - - let popup = await popupShownPromise; - let popupItems = Array.from(popup.children); - - let targetItem = popupItems.find(item => item.value == optionIndexStr); - - if (!targetItem) { - throw new Error( - "Could not find history mode popup item for value: " + value - ); - } - - let popupHiddenPromise = BrowserTestUtils.waitForPopupEvent(popup, "hidden"); - - EventUtils.synthesizeMouseAtCenter(targetItem, {}, targetItem.ownerGlobal); - - await popupHiddenPromise; -} - -async function updateCheckBox(win, id, value) { - let checkbox = win.document.getElementById(id); - ok(checkbox, "the " + id + " checkbox should exist"); - is_element_visible(checkbox, "the " + id + " checkbox should be visible"); - - // No need to click if we're already in the desired state. - if (checkbox.checked === value) { - return; - } - - // Scroll into view for click to succeed. - checkbox.scrollIntoView(); - - // Toggle the state. - await EventUtils.synthesizeMouseAtCenter(checkbox, {}, checkbox.ownerGlobal); -} diff --git a/browser/components/preferences/tests/privacypane_tests_perwindow.js b/browser/components/preferences/tests/privacypane_tests_perwindow.js @@ -22,43 +22,33 @@ function controlChanged(element) { } // We can only test the panes that don't trigger a preference update -async function test_pane_visibility(win) { - // Elements which should only be visible in history mode "custom". - let customElementIds = [ - "privateBrowsingAutoStart", - "rememberHistory", - "rememberForms", - "alwaysClear", - "clearDataSettings", - ]; +function test_pane_visibility(win) { + let modes = { + remember: "historyRememberPane", + custom: "historyCustomPane", + }; let historymode = win.document.getElementById("historyMode"); ok(historymode, "history mode menulist should exist"); + let historypane = win.document.getElementById("historyPane"); + ok(historypane, "history mode pane should exist"); - await selectHistoryMode(win, "custom"); - - for (let id of customElementIds) { - let element = win.document.getElementById(id); - ok(element, `the ${id} element should exist`); - is_element_visible( - element, - `the ${id} element should be visible in 'custom' mode` + for (let mode in modes) { + historymode.value = mode; + controlChanged(historymode); + is( + historypane.selectedPanel, + win.document.getElementById(modes[mode]), + "The correct pane should be selected for the " + mode + " mode" ); - } - - await selectHistoryMode(win, "remember"); - - for (let id of customElementIds) { - let element = win.document.getElementById(id); - ok(element, `the ${id} element should exist`); - is_element_hidden( - element, - `the ${id} element should be hidden in 'remember' mode` + is_element_visible( + historypane.selectedPanel, + "Correct pane should be visible for the " + mode + " mode" ); } } -async function test_dependent_elements(win) { +function test_dependent_elements(win) { let historymode = win.document.getElementById("historyMode"); ok(historymode, "history mode menulist should exist"); let pbautostart = win.document.getElementById("privateBrowsingAutoStart"); @@ -140,16 +130,16 @@ async function test_dependent_elements(win) { } // controls should only change in custom mode - await selectHistoryMode(win, "remember"); + historymode.value = "remember"; + controlChanged(historymode); expect_disabled(false); check_independents(false); // setting the mode to custom shouldn't change anything - await selectHistoryMode(win, "custom"); + historymode.value = "custom"; + controlChanged(historymode); expect_disabled(false); check_independents(false); - - await selectHistoryMode(win, "remember"); } async function test_dependent_cookie_elements(win) { @@ -213,12 +203,13 @@ async function test_dependent_cookie_elements(win) { await new Promise(resolve => requestAnimationFrame(resolve)); expect_disabled(false); + let historymode = win.document.getElementById("historyMode"); + // The History mode setting for "never remember history" should still // disable the "keep cookies until..." menu. - - // Suppress restart prompt, because we can't restart in a mochitest. - win._shouldPromptForRestartPBM = false; - await selectHistoryMode(win, "dontremember"); + historymode.value = "dontremember"; + controlChanged(historymode); + await new Promise(resolve => requestAnimationFrame(resolve)); expect_disabled(true, [deleteOnCloseCheckbox]); is_element_visible( deleteOnCloseNote, @@ -226,10 +217,9 @@ async function test_dependent_cookie_elements(win) { ); expect_disabled(false, [blockCookiesMenu]); - // Suppress restart prompt, because we can't restart in a mochitest. - win._shouldPromptForRestartPBM = false; - - await selectHistoryMode(win, "remember"); + historymode.value = "remember"; + controlChanged(historymode); + await new Promise(resolve => requestAnimationFrame(resolve)); expect_disabled(false); is_element_hidden( deleteOnCloseNote, @@ -237,7 +227,7 @@ async function test_dependent_cookie_elements(win) { ); } -async function test_dependent_clearonclose_elements(win) { +function test_dependent_clearonclose_elements(win) { let historymode = win.document.getElementById("historyMode"); ok(historymode, "history mode menulist should exist"); let pbautostart = win.document.getElementById("privateBrowsingAutoStart"); @@ -257,16 +247,20 @@ async function test_dependent_clearonclose_elements(win) { ); } - await selectHistoryMode(win, "custom"); - await updateCheckBox(win, "privateBrowsingAutoStart", false); - - await updateCheckBox(win, "alwaysClear", false); + historymode.value = "custom"; + controlChanged(historymode); + pbautostart.checked = false; + controlChanged(pbautostart); + alwaysclear.checked = false; + controlChanged(alwaysclear); expect_disabled(true); - await updateCheckBox(win, "alwaysClear", true); + alwaysclear.checked = true; + controlChanged(alwaysclear); expect_disabled(false); - await updateCheckBox(win, "alwaysClear", false); + alwaysclear.checked = false; + controlChanged(alwaysclear); expect_disabled(true); } @@ -295,24 +289,29 @@ async function test_dependent_prefs(win) { } // controls should be checked in remember mode - await selectHistoryMode(win, "remember"); + historymode.value = "remember"; + controlChanged(historymode); // Initial updates from prefs are not sync, so wait: - await TestUtils.waitForCondition(() => controls[0].checked); + await TestUtils.waitForCondition( + () => controls[0].getAttribute("checked") == "true" + ); expect_checked(true); // even if they're unchecked in custom mode - await selectHistoryMode(win, "custom"); - - for (let control of controls) { - await updateCheckBox(win, control.id, false); - } + historymode.value = "custom"; + controlChanged(historymode); + controls.forEach(function (control) { + control.checked = false; + controlChanged(control); + }); expect_checked(false); - await selectHistoryMode(win, "remember"); + historymode.value = "remember"; + controlChanged(historymode); expect_checked(true); } function test_historymode_retention(mode, expect) { - return async function test_historymode_retention_fn(win) { + return function test_historymode_retention_fn(win) { let historymode = win.document.getElementById("historyMode"); ok(historymode, "history mode menulist should exist"); @@ -332,12 +331,13 @@ function test_historymode_retention(mode, expect) { ); } - await selectHistoryMode(win, mode); + historymode.value = mode; + controlChanged(historymode); }; } function test_custom_retention(controlToChange, expect, valueIncrement) { - return async function test_custom_retention_fn(win) { + return function test_custom_retention_fn(win) { let historymode = win.document.getElementById("historyMode"); ok(historymode, "history mode menulist should exist"); @@ -349,18 +349,20 @@ function test_custom_retention(controlToChange, expect, valueIncrement) { ); } - await selectHistoryMode(win, "custom"); + historymode.value = "custom"; + controlChanged(historymode); controlToChange = win.document.getElementById(controlToChange); ok(controlToChange, "the control to change should exist"); switch (controlToChange.localName) { case "checkbox": - await updateCheckBox(win, controlToChange.id, !controlToChange.checked); + controlToChange.checked = !controlToChange.checked; break; case "menulist": - await selectHistoryMode(win, valueIncrement); + controlToChange.value = valueIncrement; break; } + controlChanged(controlToChange); }; } diff --git a/browser/components/preferences/widgets/setting-control/setting-control.mjs b/browser/components/preferences/widgets/setting-control/setting-control.mjs @@ -208,8 +208,6 @@ export class SettingControl extends SettingElement { getOptionPropertyMapping(config) { const props = this.getCommonPropertyMapping(config); props[".value"] = config.value; - props[".disabled"] = config.disabled; - props[".hidden"] = config.hidden; return props; } diff --git a/browser/locales/en-US/browser/preferences/preferences.ftl b/browser/locales/en-US/browser/preferences/preferences.ftl @@ -1227,14 +1227,8 @@ history-remember-option-never = history-remember-option-custom = .label = Use custom settings for history -history-remember-description2 = - .description ={ -brand-short-name } will remember your browsing, download, form, and search history. - -history-dontremember-description2 = - .description = { -brand-short-name } will use the same settings as private browsing, and will not remember any history as you browse the Web. - -history-custom-description = - .description = { -brand-short-name } will use custom settings for your browsing, download, form and search history. +history-remember-description = { -brand-short-name } will remember your browsing, download, form, and search history. +history-dontremember-description = { -brand-short-name } will use the same settings as private browsing, and will not remember any history as you browse the Web. history-private-browsing-permanent = .label = Always use private browsing mode diff --git a/python/l10n/fluent_migrations/bug_1971438_preferences_history.py b/python/l10n/fluent_migrations/bug_1971438_preferences_history.py @@ -1,26 +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 1971438 - Migrate strings for updated history preferences section, part {index}.""" - source = "browser/browser/preferences/preferences.ftl" - target = source - - ctx.add_transforms( - target, - source, - transforms_from( - """ -history-remember-description2 = - .description = {COPY_PATTERN(from_path, "history-remember-description")} - -history-dontremember-description2 = - .description = {COPY_PATTERN(from_path, "history-dontremember-description")} -""", - from_path=source, - ), - ) diff --git a/toolkit/content/tests/widgets/test_moz_select.html b/toolkit/content/tests/widgets/test_moz_select.html @@ -157,80 +157,6 @@ "Select displays the icon of the newly selected option" ); }); - - function openSelectAndGetMenuPopup(select) { - let topWindow = window.docShell.chromeEventHandler.ownerGlobal; - let pickerOpened = BrowserTestUtils.waitForSelectPopupShown(topWindow); - select.focus(); - synthesizeKey(" "); - return pickerOpened; - } - - /** - * Test that hidden and disabled moz-option are reflected in the popup menu. - */ - add_task(async function testMozSelectHiddenAndDisabledOptions() { - let target = await testHelpers.renderTemplate(); - let select = target.querySelector("moz-select"); - await select.updateComplete; - - let mozOptions = select.querySelectorAll("moz-option"); - - // Open select and verify all elements are visible and enabled. - let popup = await openSelectAndGetMenuPopup(select); - let popupItems = Array.from(popup.children); - - // Items that are hidden are not included in the popup's children. - is(popupItems.length, mozOptions.length, "All options are shown"); - for (let i = 0; i < popupItems.length; i++) { - ok(!popupItems[i].disabled, `Option ${i} is enabled`); - } - - // Close popup. - let hiddenPromise = BrowserTestUtils.waitForPopupEvent(popup, "hidden"); - popup.hidePopup(); - await hiddenPromise; - - await TestUtils.waitForTick(); - await select.updateComplete; - - // set first option to disabled and second option to hidden. - mozOptions[0].disabled = true; - mozOptions[1].hidden = true; - - await TestUtils.waitForTick(); - await select.updateComplete; - - // open select and verify first option is disabled and second option is hidden. - popup = await openSelectAndGetMenuPopup(select); - popupItems = Array.from(popup.children); - - is( - popupItems.length, - mozOptions.length - 1, - "All but one option shown" - ); - - ok(popupItems[0].disabled, "First option is disabled"); - is(popupItems[0].label, mozOptions[0].label, "First option is visible"); - ok(!popupItems[1].disabled, "Second option is enabled"); - is(popupItems[1].label, mozOptions[2].label, "Third option is visible"); - ok(!popupItems[2].disabled, "Third option is enabled"); - is( - popupItems[2].label, - mozOptions[3].label, - "Fourth option is visible" - ); - - // Close popup. - hiddenPromise = BrowserTestUtils.waitForPopupEvent(popup, "hidden"); - popup.hidePopup(); - await hiddenPromise; - - // Reset options - mozOptions[0].disabled = false; - mozOptions[1].hidden = false; - }); </script> </head> <body></body> diff --git a/toolkit/content/widgets/moz-select/moz-select.mjs b/toolkit/content/widgets/moz-select/moz-select.mjs @@ -48,7 +48,7 @@ export default class MozSelect extends MozBaseInputElement { firstUpdated(changedProperties) { super.firstUpdated(changedProperties); this.optionsMutationObserver.observe(this, { - attributeFilter: ["label", "value", "iconsrc", "disabled", "hidden"], + attributeFilter: ["label", "value", "iconsrc"], childList: true, subtree: true, }); @@ -82,14 +82,10 @@ export default class MozSelect extends MozBaseInputElement { const optionValue = node.getAttribute("value"); const optionLabel = node.getAttribute("label"); const optionIconSrc = node.getAttribute("iconsrc"); - const optionDisabled = node.getAttribute("disabled") !== null; - const optionHidden = node.getAttribute("hidden") !== null; this.options.push({ value: optionValue, label: optionLabel, iconSrc: optionIconSrc, - disabled: optionDisabled, - hidden: optionHidden, }); if (optionIconSrc) { @@ -158,8 +154,6 @@ export default class MozSelect extends MozBaseInputElement { <option value=${option.value} ?selected=${option.value == this.value} - ?disabled=${option.disabled} - ?hidden=${option.hidden} > ${option.label} </option> @@ -189,8 +183,6 @@ customElements.define("moz-select", MozSelect); * @property {string} value - The value of the option * @property {string} label - The label of the option * @property {string} iconSrc - The path to the icon of the the option - * @property {boolean} disabled - Whether the option is disabled - * @property {boolean} hidden - Whether the option is hidden */ export class MozOption extends MozLitElement { static properties = { @@ -199,8 +191,6 @@ export class MozOption extends MozLitElement { // Reflect the attribute so that moz-select can detect changes with a MutationObserver label: { type: String, reflect: true, fluent: true }, iconSrc: { type: String, reflect: true }, - disabled: { type: Boolean, reflect: true }, - hidden: { type: Boolean, reflect: true }, }; constructor() { @@ -208,8 +198,6 @@ export class MozOption extends MozLitElement { this.value = ""; this.label = ""; this.iconSrc = ""; - this.disabled = false; - this.hidden = false; } render() { diff --git a/toolkit/content/widgets/moz-select/moz-select.stories.mjs b/toolkit/content/widgets/moz-select/moz-select.stories.mjs @@ -109,8 +109,6 @@ const Template = ({ options = useOtherOptions ? OTHER_OPTIONS : DEFAULT_OPTIONS, hasSlottedSupportLink, ellipsized, - disabledOption, - hiddenOption, }) => html` <div style="width:300px"> <moz-select @@ -130,13 +128,11 @@ const Template = ({ ? html`<a slot="support-link" href="www.example.com">Click me!</a>` : ""} ${options.map( - (opt, i) => + opt => html`<moz-option value=${opt.value} data-l10n-id=${opt.l10nId} iconsrc=${opt.iconSrc} - ?disabled=${disabledOption && i == 1} - ?hidden=${hiddenOption && i == 2} ></moz-option>` )} </moz-select> @@ -229,15 +225,3 @@ WithEllipsizedLabel.args = { ellipsized: true, l10nId: "moz-select-long-label", }; - -export const WithDisabledOption = Template.bind({}); -WithDisabledOption.args = { - ...Default.args, - disabledOption: true, -}; - -export const WithHiddenOption = Template.bind({}); -WithHiddenOption.args = { - ...Default.args, - hiddenOption: true, -};