Bug 1161810 - UITour: Allow opening the Pocket panel via showMenu("pocket"). r=jaws
☠☠ backed out by cf1c3e838ac1 ☠ ☠
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Mon, 11 May 2015 22:03:45 -0700
changeset 243487 9068caa791d14a505942650f326bb7972bacbe0a
parent 243486 c1edd2c11b6e83c32d053b7652e9beb6c168de07
child 243488 a6b952b85bc6b79e277667048bf1d59da9bbc473
push id28740
push userkwierso@gmail.com
push dateTue, 12 May 2015 23:04:57 +0000
treeherdermozilla-central@de1fd9d0682a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1161810
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1161810 - UITour: Allow opening the Pocket panel via showMenu("pocket"). r=jaws
browser/components/customizableui/CustomizableUI.jsm
browser/components/uitour/UITour.jsm
browser/components/uitour/test/browser.ini
browser/components/uitour/test/browser_UITour_pocket.js
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -3643,17 +3643,17 @@ Object.freeze(this.CustomizableUI.window
  * widget group - AKA, all instances of a widget across a series of windows.
  * This particular wrapper is only used for widgets created via the provider
  * API.
  */
 function WidgetGroupWrapper(aWidget) {
   this.isGroup = true;
 
   const kBareProps = ["id", "source", "type", "disabled", "label", "tooltiptext",
-                      "showInPrivateBrowsing"];
+                      "showInPrivateBrowsing", "viewId"];
   for (let prop of kBareProps) {
     let propertyName = prop;
     this.__defineGetter__(propertyName, function() aWidget[propertyName]);
   }
 
   this.__defineGetter__("provider", function() CustomizableUI.PROVIDER_API);
 
   this.__defineSetter__("disabled", function(aValue) {
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -186,17 +186,21 @@ this.UITour = {
       query: (aDocument) => {
         let loopBrowser = aDocument.defaultView.LoopUI.browser;
         if (!loopBrowser) {
           return null;
         }
         return loopBrowser.contentDocument.querySelector(".signin-link");
       },
     }],
-    ["pocket", {query: "#pocket-button"}],
+    ["pocket", {
+      allowAdd: true,
+      query: "#pocket-button",
+      widgetName: "pocket-button",
+    }],
     ["privateWindow",  {query: "#privatebrowsing-button"}],
     ["quit",        {query: "#PanelUI-quit"}],
     ["readerMode-urlBar", {query: "#reader-mode-button"}],
     ["search",      {
       infoPanelOffsetX: 18,
       infoPanelPosition: "after_start",
       query: "#searchbar",
       widgetName: "search-container",
@@ -1545,16 +1549,56 @@ this.UITour = {
         }
       });
       panel.addEventListener("popuphidden", this.onPanelHidden);
       panel.addEventListener("popuphiding", this.hideLoopPanelAnnotations);
     } else if (aMenuName == "searchEngines") {
       this.getTarget(aWindow, "searchProvider").then(target => {
         openMenuButton(target.node);
       }).catch(log.error);
+    } else if (aMenuName == "pocket") {
+      this.getTarget(aWindow, "pocket").then(Task.async(function* onPocketTarget(target) {
+        let widgetGroupWrapper = CustomizableUI.getWidget(target.widgetName);
+        if (widgetGroupWrapper.type != "view" || !widgetGroupWrapper.viewId) {
+          log.error("Can't open the pocket menu without a view");
+          return;
+        }
+        let placement = CustomizableUI.getPlacementOfWidget(target.widgetName);
+        if (!placement || !placement.area) {
+          log.error("Can't open the pocket menu without a placement");
+          return;
+        }
+
+        if (placement.area == CustomizableUI.AREA_PANEL) {
+          // Open the appMenu and wait for it if it's not already opened or showing a subview.
+          yield new Promise((resolve, reject) => {
+            if (aWindow.PanelUI.panel.state != "closed") {
+              if (aWindow.PanelUI.multiView.showingSubView) {
+                reject("A subview is already showing");
+                return;
+              }
+
+              resolve();
+              return;
+            }
+
+            aWindow.PanelUI.panel.addEventListener("popupshown", function onShown() {
+              aWindow.PanelUI.panel.removeEventListener("popupshown", onShown);
+              resolve();
+            });
+
+            aWindow.PanelUI.show();
+          });
+        }
+
+        let widgetWrapper = widgetGroupWrapper.forWindow(aWindow);
+        aWindow.PanelUI.showSubView(widgetGroupWrapper.viewId,
+                                    widgetWrapper.anchor,
+                                    placement.area);
+      })).catch(log.error);
     }
   },
 
   hideMenu: function(aWindow, aMenuName) {
     log.debug("hideMenu:", aMenuName);
     function closeMenuButton(aMenuBtn) {
       if (aMenuBtn && aMenuBtn.boxObject)
         aMenuBtn.boxObject.openMenu(false);
--- a/browser/components/uitour/test/browser.ini
+++ b/browser/components/uitour/test/browser.ini
@@ -29,14 +29,16 @@ skip-if = e10s # Bug 1073247 - UITour.js
 [browser_UITour_loop.js]
 skip-if = os == "linux" || e10s # Bug 1073247 - UITour.jsm not e10s friendly.
 [browser_UITour_modalDialog.js]
 skip-if = os != "mac" || e10s # modal dialog disabling only working on OS X.Bug 1073247 - UITour.jsm not e10s friendly
 [browser_UITour_observe.js]
 skip-if = e10s # Bug 1073247 - UITour.jsm not e10s friendly.
 [browser_UITour_panel_close_annotation.js]
 skip-if = true # Disabled due to frequent failures, bugs 1026310 and 1032137
+[browser_UITour_pocket.js]
+skip-if = os == "linux" || e10s # Bug 1073247 - UITour.jsm not e10s friendly.
 [browser_UITour_registerPageID.js]
 skip-if = e10s # Bug 1073247 - UITour.jsm not e10s friendly
 [browser_UITour_sync.js]
 skip-if = e10s # Bug 1073247 - UITour.jsm not e10s friendly
 [browser_UITour_resetProfile.js]
 skip-if = e10s # Bug 1073247 - UITour.jsm not e10s friendly
new file mode 100644
--- /dev/null
+++ b/browser/components/uitour/test/browser_UITour_pocket.js
@@ -0,0 +1,83 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+let gTestTab;
+let gContentAPI;
+let gContentWindow;
+let button;
+
+Components.utils.import("resource:///modules/UITour.jsm");
+
+function test() {
+  UITourTest();
+}
+
+let tests = [
+  taskify(function* test_menu_show_navbar() {
+    ise(button.open, false, "Menu should initially be closed");
+    gContentAPI.showMenu("pocket");
+
+    // The panel gets created dynamically.
+    let widgetPanel = null;
+    yield waitForConditionPromise(() => {
+      widgetPanel = document.getElementById("customizationui-widget-panel");
+      return widgetPanel && widgetPanel.state == "open";
+    }, "Menu should be visible after showMenu()");
+
+    ok(button.open, "Button should know its view is open");
+    ok(!widgetPanel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
+    ok(button.hasAttribute("open"), "Pocket button should know that the menu is open");
+
+    widgetPanel.hidePopup();
+    checkPanelIsHidden(widgetPanel);
+  }),
+  taskify(function* test_menu_show_appMenu() {
+    CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_PANEL);
+
+    ise(button.open, false, "Menu should initially be closed");
+    gContentAPI.showMenu("pocket");
+
+    yield waitForConditionPromise(() => {
+      return PanelUI.panel.state == "open";
+    }, "Menu should be visible after showMenu()");
+
+    ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
+    ok(PanelUI.multiView.showingSubView, "Subview should be open");
+    ok(PanelUI.multiView.hasAttribute("panelopen"), "Multiview should know it's open");
+
+    PanelUI.panel.hidePopup();
+    checkPanelIsHidden(PanelUI.panel);
+  }),
+];
+
+// End tests
+
+function checkPanelIsHidden(aPanel) {
+  if (aPanel.parentElement) {
+    is_hidden(aPanel);
+  } else {
+    ok(!aPanel.parentElement, "Widget panel should have been removed");
+  }
+  is(button.hasAttribute("open"), false, "Pocket button should know that the panel is closed");
+}
+
+if (Services.prefs.getBoolPref("browser.pocket.enabled")) {
+  let placement = CustomizableUI.getPlacementOfWidget("pocket-button");
+
+  // Add the button to the nav-bar by default.
+  if (!placement || placement.area != CustomizableUI.AREA_NAVBAR) {
+    CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_NAVBAR);
+  }
+  registerCleanupFunction(() => {
+    CustomizableUI.reset();
+  });
+
+  let widgetGroupWrapper = CustomizableUI.getWidget("pocket-button");
+  button = widgetGroupWrapper.forWindow(window).node;
+  ok(button, "Got button node");
+} else {
+  todo(false, "Pocket is disabled so skip its UITour tests");
+  tests = [];
+}