diff options
Diffstat (limited to '')
-rw-r--r-- | browser/components/customizableui/SearchWidgetTracker.sys.mjs | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/browser/components/customizableui/SearchWidgetTracker.sys.mjs b/browser/components/customizableui/SearchWidgetTracker.sys.mjs new file mode 100644 index 0000000000..92f61d5b76 --- /dev/null +++ b/browser/components/customizableui/SearchWidgetTracker.sys.mjs @@ -0,0 +1,134 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Keeps the "browser.search.widget.inNavBar" preference synchronized, + * and ensures persisted widths are updated if the search bar is removed. + */ + +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; +import { CustomizableUI } from "resource:///modules/CustomizableUI.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.sys.mjs", +}); + +const WIDGET_ID = "search-container"; +const PREF_NAME = "browser.search.widget.inNavBar"; + +export const SearchWidgetTracker = { + init() { + this.onWidgetReset = this.onWidgetUndoMove = node => { + if (node.id == WIDGET_ID) { + this.syncPreferenceWithWidget(); + this.removePersistedWidths(); + } + }; + CustomizableUI.addListener(this); + Services.prefs.addObserver(PREF_NAME, () => + this.syncWidgetWithPreference() + ); + this._updateSearchBarVisibilityBasedOnUsage(); + }, + + onWidgetAdded(widgetId, area) { + if (widgetId == WIDGET_ID && area == CustomizableUI.AREA_NAVBAR) { + this.syncPreferenceWithWidget(); + } + }, + + onWidgetRemoved(aWidgetId, aArea) { + if (aWidgetId == WIDGET_ID && aArea == CustomizableUI.AREA_NAVBAR) { + this.syncPreferenceWithWidget(); + this.removePersistedWidths(); + } + }, + + onAreaNodeRegistered(aArea) { + // The placement of the widget always takes priority, and the preference + // should always match the actual placement when the browser starts up - i.e. + // once the navigation bar has been registered. + if (aArea == CustomizableUI.AREA_NAVBAR) { + this.syncPreferenceWithWidget(); + } + }, + + onCustomizeEnd() { + // onWidgetUndoMove does not fire when the search container is moved back to + // the customization palette as a result of an undo, so we sync again here. + this.syncPreferenceWithWidget(); + }, + + syncPreferenceWithWidget() { + Services.prefs.setBoolPref(PREF_NAME, this.widgetIsInNavBar); + }, + + syncWidgetWithPreference() { + let newValue = Services.prefs.getBoolPref(PREF_NAME); + if (newValue == this.widgetIsInNavBar) { + return; + } + + if (newValue) { + // The URL bar widget is always present in the navigation toolbar, so we + // can simply read its position to place the search bar right after it. + CustomizableUI.addWidgetToArea( + WIDGET_ID, + CustomizableUI.AREA_NAVBAR, + CustomizableUI.getPlacementOfWidget("urlbar-container").position + 1 + ); + lazy.BrowserUsageTelemetry.recordWidgetChange( + WIDGET_ID, + CustomizableUI.AREA_NAVBAR, + "searchpref" + ); + } else { + CustomizableUI.removeWidgetFromArea(WIDGET_ID); + lazy.BrowserUsageTelemetry.recordWidgetChange( + WIDGET_ID, + null, + "searchpref" + ); + } + }, + + _updateSearchBarVisibilityBasedOnUsage() { + let searchBarLastUsed = Services.prefs.getStringPref( + "browser.search.widget.lastUsed", + "" + ); + if (searchBarLastUsed) { + const removeAfterDaysUnused = Services.prefs.getIntPref( + "browser.search.widget.removeAfterDaysUnused" + ); + let saerchBarUnusedThreshold = + removeAfterDaysUnused * 24 * 60 * 60 * 1000; + if (new Date() - new Date(searchBarLastUsed) > saerchBarUnusedThreshold) { + Services.prefs.setBoolPref("browser.search.widget.inNavBar", false); + } + } + }, + + removePersistedWidths() { + Services.xulStore.removeValue( + AppConstants.BROWSER_CHROME_URL, + WIDGET_ID, + "width" + ); + for (let win of CustomizableUI.windows) { + let searchbar = + win.document.getElementById(WIDGET_ID) || + win.gNavToolbox.palette.querySelector("#" + WIDGET_ID); + searchbar.removeAttribute("width"); + searchbar.style.removeProperty("width"); + } + }, + + get widgetIsInNavBar() { + let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID); + return placement?.area == CustomizableUI.AREA_NAVBAR; + }, +}; |