Bug 1348122 - Share code between the customizable zoom control and the location bar's zoom indicator. r=Gijs a=gchang
authorDão Gottwald <dao+bmo>
Tue, 28 Mar 2017 02:36:00 +0200
changeset 395617 0032f065b456fef31bc6deb4ead372dd8faa9611
parent 395616 6f295b1cb01fea18d05429610363c735e6c1f671
child 395618 e9e6146c820b389b6c31c11062cf831954b37998
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, gchang
bugs1348122
milestone54.0a2
Bug 1348122 - Share code between the customizable zoom control and the location bar's zoom indicator. r=Gijs a=gchang
browser/base/content/browser.js
browser/components/customizableui/CustomizableWidgets.jsm
browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
browser/modules/FullZoomUI.jsm
browser/modules/URLBarZoom.jsm
browser/modules/moz.build
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -23,17 +23,17 @@ Cu.import("resource://gre/modules/Notifi
           LoginManagerParent:false, NewTabUtils:false, PageThumbs:false,
           PluralForm:false, Preferences:false, PrivateBrowsingUtils:false,
           ProcessHangMonitor:false, PromiseUtils:false, ReaderMode:false,
           ReaderParent:false, RecentWindow:false, SessionStore:false,
           ShortcutUtils:false, SimpleServiceDiscovery:false, SitePermissions:false,
           Social:false, TabCrashHandler:false, Task:false, TelemetryStopwatch:false,
           Translation:false, UITour:false, UpdateUtils:false, Weave:false,
           fxAccounts:false, gDevTools:false, gDevToolsBrowser:false, webrtcUI:false,
-          URLBarZoom:false
+          FullZoomUI:false
  */
 
 /**
  * IF YOU ADD OR REMOVE FROM THIS LIST, PLEASE UPDATE THE LIST ABOVE AS WELL.
  * XXX Bug 1325373 is for making eslint detect these automatically.
  */
 [
   ["AboutHome", "resource:///modules/AboutHome.jsm"],
@@ -45,16 +45,17 @@ Cu.import("resource://gre/modules/Notifi
   ["CastingApps", "resource:///modules/CastingApps.jsm"],
   ["CharsetMenu", "resource://gre/modules/CharsetMenu.jsm"],
   ["Color", "resource://gre/modules/Color.jsm"],
   ["ContentSearch", "resource:///modules/ContentSearch.jsm"],
   ["Deprecated", "resource://gre/modules/Deprecated.jsm"],
   ["E10SUtils", "resource:///modules/E10SUtils.jsm"],
   ["ExtensionsUI", "resource:///modules/ExtensionsUI.jsm"],
   ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"],
+  ["FullZoomUI", "resource:///modules/FullZoomUI.jsm"],
   ["GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm"],
   ["LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm"],
   ["Log", "resource://gre/modules/Log.jsm"],
   ["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"],
   ["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"],
   ["PageThumbs", "resource://gre/modules/PageThumbs.jsm"],
   ["PluralForm", "resource://gre/modules/PluralForm.jsm"],
   ["Preferences", "resource://gre/modules/Preferences.jsm"],
@@ -70,17 +71,16 @@ Cu.import("resource://gre/modules/Notifi
   ["SitePermissions", "resource:///modules/SitePermissions.jsm"],
   ["Social", "resource:///modules/Social.jsm"],
   ["TabCrashHandler", "resource:///modules/ContentCrashHandlers.jsm"],
   ["Task", "resource://gre/modules/Task.jsm"],
   ["TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm"],
   ["Translation", "resource:///modules/translation/Translation.jsm"],
   ["UITour", "resource:///modules/UITour.jsm"],
   ["UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"],
-  ["URLBarZoom", "resource:///modules/URLBarZoom.jsm"],
   ["Weave", "resource://services-sync/main.js"],
   ["fxAccounts", "resource://gre/modules/FxAccounts.jsm"],
   ["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"],
   ["gDevToolsBrowser", "resource://devtools/client/framework/gDevTools.jsm"],
   ["webrtcUI", "resource:///modules/webrtcUI.jsm"],
 ].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
 
 XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
@@ -1133,17 +1133,17 @@ var gBrowserInit = {
     LanguageDetectionListener.init();
     BrowserOnClick.init();
     FeedHandler.init();
     CompactTheme.init();
     AboutPrivateBrowsingListener.init();
     TrackingProtection.init();
     RefreshBlocker.init();
     CaptivePortalWatcher.init();
-    URLBarZoom.init(window);
+    FullZoomUI.init(window);
 
     let mm = window.getGroupMessageManager("browsers");
     mm.loadFrameScript("chrome://browser/content/tab-content.js", true);
     mm.loadFrameScript("chrome://browser/content/content.js", true);
     mm.loadFrameScript("chrome://browser/content/content-UITour.js", true);
     mm.loadFrameScript("chrome://global/content/manifestMessages.js", true);
 
     // initialize observers and listeners
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -661,21 +661,16 @@ const CustomizableWidgets = [
       win.BrowserOpenAddonsMgr();
     }
   }, {
     id: "zoom-controls",
     type: "custom",
     tooltiptext: "zoom-controls.tooltiptext2",
     defaultArea: CustomizableUI.AREA_PANEL,
     onBuild(aDocument) {
-      const kPanelId = "PanelUI-popup";
-      let areaType = CustomizableUI.getAreaType(this.currentArea);
-      let inPanel = areaType == CustomizableUI.TYPE_MENU_PANEL;
-      let inToolbar = areaType == CustomizableUI.TYPE_TOOLBAR;
-
       let buttons = [{
         id: "zoom-out-button",
         command: "cmd_fullZoomReduce",
         label: true,
         tooltiptext: "tooltiptext2",
         shortcutId: "key_fullZoomReduce",
       }, {
         id: "zoom-reset-button",
@@ -703,135 +698,60 @@ const CustomizableWidgets = [
       buttons.forEach(function(aButton, aIndex) {
         if (aIndex != 0)
           node.appendChild(aDocument.createElementNS(kNSXUL, "separator"));
         let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
         setAttributes(btnNode, aButton);
         node.appendChild(btnNode);
       });
 
-      // The middle node is the 'Reset Zoom' button.
-      let zoomResetButton = node.childNodes[2];
-      let window = aDocument.defaultView;
-      function updateZoomResetButton() {
-        let updateDisplay = true;
-        // Label should always show 100% in customize mode, so don't update:
-        if (aDocument.documentElement.hasAttribute("customizing")) {
-          updateDisplay = false;
-        }
-        // XXXgijs in some tests we get called very early, and there's no docShell on the
-        // tabbrowser. This breaks the zoom toolkit code (see bug 897410). Don't let that happen:
-        let zoomFactor = 100;
-        try {
-          zoomFactor = Math.round(window.ZoomManager.zoom * 100);
-        } catch (e) {}
-        zoomResetButton.setAttribute("label", CustomizableUI.getLocalizedProperty(
-          buttons[1], "label", [updateDisplay ? zoomFactor : 100]
-        ));
-      }
-
-      // Register ourselves with the service so we know when the zoom prefs change.
-      Services.obs.addObserver(updateZoomResetButton, "browser-fullZoom:location-change", false);
-      window.addEventListener("FullZoomChange", updateZoomResetButton);
-
-      if (inPanel) {
-        let panel = aDocument.getElementById(kPanelId);
-        panel.addEventListener("popupshowing", updateZoomResetButton);
-      } else {
-        if (inToolbar) {
-          let container = window.gBrowser.tabContainer;
-          container.addEventListener("TabSelect", updateZoomResetButton);
-        }
-        updateZoomResetButton();
-      }
       updateCombinedWidgetStyle(node, this.currentArea, true);
 
       let listener = {
         onWidgetAdded: function(aWidgetId, aArea, aPosition) {
           if (aWidgetId != this.id)
             return;
 
           updateCombinedWidgetStyle(node, aArea, true);
-          updateZoomResetButton();
-
-          let newAreaType = CustomizableUI.getAreaType(aArea);
-          if (newAreaType == CustomizableUI.TYPE_MENU_PANEL) {
-            let panel = aDocument.getElementById(kPanelId);
-            panel.addEventListener("popupshowing", updateZoomResetButton);
-          } else if (newAreaType == CustomizableUI.TYPE_TOOLBAR) {
-            let container = window.gBrowser.tabContainer;
-            container.addEventListener("TabSelect", updateZoomResetButton);
-          }
         }.bind(this),
 
         onWidgetRemoved: function(aWidgetId, aPrevArea) {
           if (aWidgetId != this.id)
             return;
 
-          let formerAreaType = CustomizableUI.getAreaType(aPrevArea);
-          if (formerAreaType == CustomizableUI.TYPE_MENU_PANEL) {
-            let panel = aDocument.getElementById(kPanelId);
-            panel.removeEventListener("popupshowing", updateZoomResetButton);
-          } else if (formerAreaType == CustomizableUI.TYPE_TOOLBAR) {
-            let container = window.gBrowser.tabContainer;
-            container.removeEventListener("TabSelect", updateZoomResetButton);
-          }
-
           // When a widget is demoted to the palette ('removed'), it's visual
           // style should change.
           updateCombinedWidgetStyle(node, null, true);
-          updateZoomResetButton();
         }.bind(this),
 
         onWidgetReset: function(aWidgetNode) {
           if (aWidgetNode != node)
             return;
           updateCombinedWidgetStyle(node, this.currentArea, true);
-          updateZoomResetButton();
         }.bind(this),
 
         onWidgetUndoMove: function(aWidgetNode) {
           if (aWidgetNode != node)
             return;
           updateCombinedWidgetStyle(node, this.currentArea, true);
-          updateZoomResetButton();
         }.bind(this),
 
         onWidgetMoved: function(aWidgetId, aArea) {
           if (aWidgetId != this.id)
             return;
           updateCombinedWidgetStyle(node, aArea, true);
-          updateZoomResetButton();
         }.bind(this),
 
         onWidgetInstanceRemoved: function(aWidgetId, aDoc) {
           if (aWidgetId != this.id || aDoc != aDocument)
             return;
 
           CustomizableUI.removeListener(listener);
-          Services.obs.removeObserver(updateZoomResetButton, "browser-fullZoom:location-change");
-          window.removeEventListener("FullZoomChange", updateZoomResetButton);
-          let panel = aDoc.getElementById(kPanelId);
-          panel.removeEventListener("popupshowing", updateZoomResetButton);
-          let container = aDoc.defaultView.gBrowser.tabContainer;
-          container.removeEventListener("TabSelect", updateZoomResetButton);
         }.bind(this),
 
-        onCustomizeStart(aWindow) {
-          if (aWindow.document == aDocument) {
-            updateZoomResetButton();
-          }
-        },
-
-        onCustomizeEnd(aWindow) {
-          if (aWindow.document == aDocument) {
-            updateZoomResetButton();
-          }
-        },
-
         onWidgetDrag: function(aWidgetId, aArea) {
           if (aWidgetId != this.id)
             return;
           aArea = aArea || this.currentArea;
           updateCombinedWidgetStyle(node, aArea, true);
         }.bind(this)
       };
       CustomizableUI.addListener(listener);
--- a/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
+++ b/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
@@ -24,19 +24,20 @@ add_task(function*() {
   });
 
   is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla");
   let zoomChangePromise = promiseObserverNotification("browser-fullZoom:zoomChange");
   FullZoom.enlarge();
   yield zoomChangePromise;
   is(parseInt(zoomResetButton.label, 10), 110, "Zoom is changed to 110% for about:mozilla");
 
-  let tabSelectPromise = promiseTabSelect();
+  let tabSelectPromise = promiseObserverNotification("browser-fullZoom:location-change");
   gBrowser.selectedTab = tab2;
   yield tabSelectPromise;
+  yield new Promise(resolve => executeSoon(resolve));
   is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:robots");
 
   gBrowser.selectedTab = tab1;
   let zoomResetPromise = promiseObserverNotification("browser-fullZoom:zoomReset");
   FullZoom.reset();
   yield zoomResetPromise;
   is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla");
 
rename from browser/modules/URLBarZoom.jsm
rename to browser/modules/FullZoomUI.jsm
--- a/browser/modules/URLBarZoom.jsm
+++ b/browser/modules/FullZoomUI.jsm
@@ -1,20 +1,20 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
 /* 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";
 
-this.EXPORTED_SYMBOLS = [ "URLBarZoom" ];
+this.EXPORTED_SYMBOLS = [ "FullZoomUI" ];
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
-var URLBarZoom = {
+var FullZoomUI = {
   init(aWindow) {
     aWindow.addEventListener("EndSwapDocShells", onEndSwapDocShells, true);
     aWindow.addEventListener("FullZoomChange", onFullZoomChange);
     aWindow.addEventListener("unload", () => {
       aWindow.removeEventListener("EndSwapDocShells", onEndSwapDocShells, true);
       aWindow.removeEventListener("FullZoomChange", onFullZoomChange);
     }, {once: true});
   },
@@ -22,70 +22,95 @@ var URLBarZoom = {
 
 function fullZoomLocationChangeObserver(aSubject, aTopic) {
   // If the tab was the last one in its window and has been dragged to another
   // window, the original browser's window will be unavailable here. Since that
   // window is closing, we can just ignore this notification.
   if (!aSubject.ownerGlobal) {
     return;
   }
-
-  updateZoomButton(aSubject, false);
+  updateZoomUI(aSubject, false);
 }
+Services.obs.addObserver(fullZoomLocationChangeObserver, "browser-fullZoom:location-change", false);
 
 function onEndSwapDocShells(event) {
-  updateZoomButton(event.originalTarget);
+  updateZoomUI(event.originalTarget);
 }
 
 function onFullZoomChange(event) {
   let browser;
   if (event.target.nodeType == event.target.DOCUMENT_NODE) {
     // In non-e10s, the event is dispatched on the contentDocument
     // so we need to jump through some hoops to get to the <xul:browser>.
     let gBrowser = event.currentTarget.gBrowser;
     let topDoc = event.target.defaultView.top.document;
     browser = gBrowser.getBrowserForDocument(topDoc);
   } else {
     browser = event.originalTarget;
   }
-  updateZoomButton(browser, true);
+  updateZoomUI(browser, true);
 }
 
-  /**
-   * Updates the zoom button in the location bar.
-   *
-   * @param {object} aBrowser The browser that the zoomed content resides in.
-   * @param {boolean} aAnimate Should be True for all cases unless the zoom
-   *   change is related to tab switching. Optional
-   */
-function updateZoomButton(aBrowser, aAnimate = false) {
+/**
+ * Updates zoom controls.
+ *
+ * @param {object} aBrowser The browser that the zoomed content resides in.
+ * @param {boolean} aAnimate Should be True for all cases unless the zoom
+ *   change is related to tab switching. Optional
+ */
+function updateZoomUI(aBrowser, aAnimate = false) {
   let win = aBrowser.ownerGlobal;
   if (aBrowser != win.gBrowser.selectedBrowser) {
     return;
   }
 
   let customizableZoomControls = win.document.getElementById("zoom-controls");
-  let zoomResetButton = win.document.getElementById("urlbar-zoom-button");
-
-  // Ensure that zoom controls haven't already been added to browser in Customize Mode
-  if (customizableZoomControls &&
-      customizableZoomControls.getAttribute("cui-areatype") == "toolbar") {
-    zoomResetButton.hidden = true;
-    return;
-  }
-
+  let customizableZoomReset = win.document.getElementById("zoom-reset-button");
+  let urlbarZoomButton = win.document.getElementById("urlbar-zoom-button");
   let zoomFactor = Math.round(win.ZoomManager.zoom * 100);
-  if (zoomFactor != 100) {
-    zoomResetButton.hidden = false;
+
+  // Hide urlbar zoom button if zoom is at 100% or the customizable control is
+  // in the toolbar.
+  urlbarZoomButton.hidden =
+    (zoomFactor == 100 ||
+     (customizableZoomControls &&
+      customizableZoomControls.getAttribute("cui-areatype") == "toolbar"));
+
+  let label = win.gNavigatorBundle.getFormattedString("urlbar-zoom-button.label", [zoomFactor]);
+  if (customizableZoomReset) {
+    customizableZoomReset.setAttribute("label", label);
+  }
+  if (!urlbarZoomButton.hidden) {
     if (aAnimate) {
-      zoomResetButton.setAttribute("animate", "true");
+      urlbarZoomButton.setAttribute("animate", "true");
     } else {
-      zoomResetButton.removeAttribute("animate");
+      urlbarZoomButton.removeAttribute("animate");
     }
-    zoomResetButton.setAttribute("label",
-        win.gNavigatorBundle.getFormattedString("urlbar-zoom-button.label", [zoomFactor]));
-  } else {
-    // Hide button if zoom is at 100%
-    zoomResetButton.hidden = true;
+    urlbarZoomButton.setAttribute("label", label);
   }
 }
 
-Services.obs.addObserver(fullZoomLocationChangeObserver, "browser-fullZoom:location-change", false);
+Components.utils.import("resource:///modules/CustomizableUI.jsm");
+let customizationListener = {
+  onAreaNodeRegistered(aAreaType, aAreaNode) {
+    if (aAreaType == CustomizableUI.AREA_PANEL) {
+      updateZoomUI(aAreaNode.ownerGlobal.gBrowser.selectedBrowser);
+    }
+  }
+};
+customizationListener.onWidgetAdded =
+customizationListener.onWidgetRemoved =
+customizationListener.onWidgetMoved =
+customizationListener.onWidgetInstanceRemoved = function(aWidgetId) {
+  if (aWidgetId == "zoom-controls") {
+    for (let window of CustomizableUI.windows) {
+      updateZoomUI(window.gBrowser.selectedBrowser);
+    }
+  }
+};
+customizationListener.onWidgetReset =
+customizationListener.onWidgetUndoMove = function(aWidgetNode) {
+  if (aWidgetNode.id == "zoom-controls") {
+    updateZoomUI(aWidgetNode.ownerGlobal.gBrowser.selectedBrowser);
+  }
+};
+CustomizableUI.addListener(customizationListener);
+
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -24,33 +24,33 @@ EXTRA_JS_MODULES += [
     'ContentSearch.jsm',
     'ContentWebRTC.jsm',
     'DirectoryLinksProvider.jsm',
     'E10SUtils.jsm',
     'ExtensionsUI.jsm',
     'Feeds.jsm',
     'FormSubmitObserver.jsm',
     'FormValidationHandler.jsm',
+    'FullZoomUI.jsm',
     'HiddenFrame.jsm',
     'LaterRun.jsm',
     'NetworkPrioritizer.jsm',
     'offlineAppCache.jsm',
     'PermissionUI.jsm',
     'PluginContent.jsm',
     'ProcessHangMonitor.jsm',
     'ReaderParent.jsm',
     'RecentWindow.jsm',
     'RemotePrompt.jsm',
     'Sanitizer.jsm',
     'SelfSupportBackend.jsm',
     'SitePermissions.jsm',
     'Social.jsm',
     'SocialService.jsm',
     'TransientPrefs.jsm',
-    'URLBarZoom.jsm',
     'webrtcUI.jsm',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     EXTRA_JS_MODULES += [
         'Windows8WindowFrameColor.jsm',
         'WindowsJumpLists.jsm',
         'WindowsPreviewPerTab.jsm',