summaryrefslogtreecommitdiffstats
path: root/browser/components/customizableui/SearchWidgetTracker.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/customizableui/SearchWidgetTracker.jsm')
-rw-r--r--browser/components/customizableui/SearchWidgetTracker.jsm136
1 files changed, 136 insertions, 0 deletions
diff --git a/browser/components/customizableui/SearchWidgetTracker.jsm b/browser/components/customizableui/SearchWidgetTracker.jsm
new file mode 100644
index 0000000000..4819fd844b
--- /dev/null
+++ b/browser/components/customizableui/SearchWidgetTracker.jsm
@@ -0,0 +1,136 @@
+/* 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.
+ */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["SearchWidgetTracker"];
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { AppConstants } = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+
+ChromeUtils.defineModuleGetter(
+ this,
+ "CustomizableUI",
+ "resource:///modules/CustomizableUI.jsm"
+);
+ChromeUtils.defineModuleGetter(
+ this,
+ "BrowserUsageTelemetry",
+ "resource:///modules/BrowserUsageTelemetry.jsm"
+);
+
+const WIDGET_ID = "search-container";
+const PREF_NAME = "browser.search.widget.inNavBar";
+
+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()
+ );
+ },
+
+ 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
+ );
+ BrowserUsageTelemetry.recordWidgetChange(
+ WIDGET_ID,
+ CustomizableUI.AREA_NAVBAR,
+ "searchpref"
+ );
+ } else {
+ CustomizableUI.removeWidgetFromArea(WIDGET_ID);
+ BrowserUsageTelemetry.recordWidgetChange(WIDGET_ID, null, "searchpref");
+ }
+ },
+
+ removePersistedWidths() {
+ Services.xulStore.removeValue(
+ AppConstants.BROWSER_CHROME_URL,
+ "urlbar-container",
+ "width"
+ );
+ Services.xulStore.removeValue(
+ AppConstants.BROWSER_CHROME_URL,
+ this.WIDGET_ID,
+ "width"
+ );
+ for (let win of CustomizableUI.windows) {
+ let urlbar = win.document.getElementById("urlbar-container");
+ urlbar.removeAttribute("width");
+ win.document
+ .getElementById("nav-bar")
+ .querySelectorAll("toolbarspring")
+ .forEach(n => n.removeAttribute("width"));
+ win.PanelUI.overflowPanel
+ .querySelectorAll("toolbarspring")
+ .forEach(n => n.removeAttribute("width"));
+ let searchbar =
+ win.document.getElementById(WIDGET_ID) ||
+ win.gNavToolbox.palette.querySelector("#" + WIDGET_ID);
+ searchbar.removeAttribute("width");
+ }
+ },
+
+ get widgetIsInNavBar() {
+ let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID);
+ return placement ? placement.area == CustomizableUI.AREA_NAVBAR : false;
+ },
+};