Bug 694291 - Add a preference mirroring the presence of the search widget in the navigation toolbar. r=past
MozReview-Commit-ID: 9UmowyRTTMK
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -399,16 +399,22 @@ pref("browser.search.order.US.3",
pref("browser.search.openintab", false);
// context menu searches open in the foreground
pref("browser.search.context.loadInBackground", false);
// comma seperated list of of engines to hide in the search panel.
pref("browser.search.hiddenOneOffs", "");
+// Mirrors whether the search-container widget is in the navigation toolbar. The
+// default value of this preference must match the DEFAULT_AREA_PLACEMENTS of
+// UITelemetry.jsm, the navbarPlacements of CustomizableUI.jsm, and the
+// position and attributes of the search-container element in browser.xul.
+pref("browser.search.widget.inNavBar", true);
+
#ifndef RELEASE_OR_BETA
pref("browser.search.reset.enabled", true);
#endif
pref("browser.sessionhistory.max_entries", 50);
// Built-in default permissions.
pref("permissions.manager.defaultsUrl", "resource://app/defaults/permissions");
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -8,16 +8,18 @@ this.EXPORTED_SYMBOLS = ["CustomizableUI
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PanelWideWidgetTracker",
"resource:///modules/PanelWideWidgetTracker.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "SearchWidgetTracker",
+ "resource:///modules/SearchWidgetTracker.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableWidgets",
"resource:///modules/CustomizableWidgets.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
"resource://gre/modules/DeferredTask.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "gWidgetsBundle", function() {
const kUrl = "chrome://browser/locale/customizableui/customizableWidgets.properties";
@@ -294,16 +296,18 @@ var CustomizableUIInternal = {
}, true);
this.registerArea(CustomizableUI.AREA_ADDONBAR, {
type: CustomizableUI.TYPE_TOOLBAR,
legacy: true,
defaultPlacements: ["addonbar-closebutton", "status-bar"],
defaultCollapsed: false,
}, true);
+
+ SearchWidgetTracker.init();
},
_updateAreasForPhoton() {
if (gPhotonStructure) {
if (gAreas.has(CustomizableUI.AREA_PANEL)) {
this.unregisterArea(CustomizableUI.AREA_PANEL, true);
}
this.registerArea(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, {
new file mode 100644
--- /dev/null
+++ b/browser/components/customizableui/SearchWidgetTracker.jsm
@@ -0,0 +1,71 @@
+/* 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.
+ */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["SearchWidgetTracker"];
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
+ "resource:///modules/CustomizableUI.jsm");
+
+const WIDGET_ID = "search-container";
+const PREF_NAME = "browser.search.widget.inNavBar";
+
+const SearchWidgetTracker = {
+ init() {
+ this.onWidgetAdded = this.onWidgetRemoved = (widgetId, area) => {
+ if (widgetId == WIDGET_ID && area == CustomizableUI.AREA_NAVBAR) {
+ this.syncPreferenceWithWidget();
+ }
+ };
+ this.onWidgetReset = this.onWidgetUndoMove = node => {
+ if (node.id == WIDGET_ID) {
+ this.syncPreferenceWithWidget();
+ }
+ };
+ CustomizableUI.addListener(this);
+ Services.prefs.addObserver(PREF_NAME,
+ () => this.syncWidgetWithPreference());
+ },
+
+ 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);
+ } else {
+ CustomizableUI.removeWidgetFromArea(WIDGET_ID);
+ }
+ },
+
+ get widgetIsInNavBar() {
+ let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID);
+ return placement ? placement.area == CustomizableUI.AREA_NAVBAR : false;
+ },
+};
--- a/browser/components/customizableui/moz.build
+++ b/browser/components/customizableui/moz.build
@@ -13,15 +13,16 @@ BROWSER_CHROME_MANIFESTS += ['test/brows
EXTRA_JS_MODULES += [
'CustomizableUI.jsm',
'CustomizableWidgets.jsm',
'CustomizeMode.jsm',
'DragPositionManager.jsm',
'PanelMultiView.jsm',
'PanelWideWidgetTracker.jsm',
'ScrollbarSampler.jsm',
+ 'SearchWidgetTracker.jsm',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Toolbars and Customization')
--- a/browser/components/customizableui/test/browser.ini
+++ b/browser/components/customizableui/test/browser.ini
@@ -1,15 +1,16 @@
[DEFAULT]
support-files =
head.js
support/test_967000_charEncoding_page.html
support/feeds_test_page.html
support/test-feed.xml
+[browser_694291_searchbar_preference.js]
[browser_873501_handle_specials.js]
[browser_876926_customize_mode_wrapping.js]
[browser_876944_customize_mode_create_destroy.js]
[browser_877006_missing_view.js]
[browser_877178_unregisterArea.js]
[browser_877447_skip_missing_ids.js]
[browser_878452_drag_to_panel.js]
[browser_880164_customization_context_menus.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/customizableui/test/browser_694291_searchbar_preference.js
@@ -0,0 +1,49 @@
+/* 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/. */
+
+"use strict";
+
+const WIDGET_ID = "search-container";
+const PREF_NAME = "browser.search.widget.inNavBar";
+
+function checkDefaults() {
+ // If the following defaults change, then the DEFAULT_AREA_PLACEMENTS of
+ // UITelemetry.jsm, the navbarPlacements of CustomizableUI.jsm, and the
+ // position and attributes of the search-container element in browser.xul
+ // should also change at the same time.
+ ok(Services.prefs.getBoolPref(PREF_NAME));
+ let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID);
+ is(placement.area, CustomizableUI.AREA_NAVBAR);
+ is(placement.position,
+ CustomizableUI.getPlacementOfWidget("urlbar-container").position + 1);
+}
+
+add_task(async function test_defaults() {
+ await SpecialPowers.pushPrefEnv({set: [["browser.photon.structure.enabled", false]]});
+
+ // Verify the default state before the first test.
+ checkDefaults();
+});
+
+add_task(async function test_syncPreferenceWithWidget() {
+ // Moving the widget to any position outside of the navigation toolbar should
+ // turn the preference to false.
+ CustomizableUI.addWidgetToArea(WIDGET_ID, CustomizableUI.AREA_PANEL);
+ ok(!Services.prefs.getBoolPref(PREF_NAME));
+
+ // Moving the widget back to any position in the navigation toolbar should
+ // turn the preference to true again.
+ CustomizableUI.addWidgetToArea(WIDGET_ID, CustomizableUI.AREA_NAVBAR);
+ ok(Services.prefs.getBoolPref(PREF_NAME));
+});
+
+add_task(async function test_syncWidgetWithPreference() {
+ // This should move the widget the customization palette.
+ Services.prefs.setBoolPref(PREF_NAME, false);
+ is(CustomizableUI.getPlacementOfWidget(WIDGET_ID), null);
+
+ // This should return the widget to its default placement.
+ Services.prefs.setBoolPref(PREF_NAME, true);
+ checkDefaults();
+});