Bug 1367012 - update edit UI visibility checks for photon, r?mikedeboer draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 08 Jun 2017 11:17:55 +0100
changeset 591072 a5a27eb279696e5a44e8f6b6e37aad2842385e4b
parent 589544 4dd1d17ba22660b8f5869a707f2e4e9f9dd5be5b
child 632414 922777cdbdc9487fdda40b93a4834ce229344889
push id62943
push userbmo:gijskruitbosch+bugs@gmail.com
push dateThu, 08 Jun 2017 15:57:08 +0000
reviewersmikedeboer
bugs1367012
milestone55.0a1
Bug 1367012 - update edit UI visibility checks for photon, r?mikedeboer This ensures we update edit UI visibility state when opening/closing the overflow panel, as well as ensuring we do so if/when the edit controls get over/underflowed. It then updates the test to ensure we correctly check the overflow panel, both for overflown items and for items put there by the user when photon is enabled. MozReview-Commit-ID: AjRH8wz5Pla
browser/base/content/browser.js
browser/components/customizableui/CustomizableUI.jsm
browser/components/customizableui/CustomizableWidgets.jsm
browser/components/customizableui/test/browser_editcontrols_update.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4221,29 +4221,40 @@ function updateEditUIVisibility() {
   // is open, or if the toolbar has been customized to include the Cut, Copy,
   // or Paste toolbar buttons.
   gEditUIVisible = editMenuPopupState == "showing" ||
                    editMenuPopupState == "open" ||
                    contextMenuPopupState == "showing" ||
                    contextMenuPopupState == "open" ||
                    placesContextMenuPopupState == "showing" ||
                    placesContextMenuPopupState == "open";
+  const kOpenPopupStates = ["showing", "open"];
   if (!gEditUIVisible) {
     // Now check the edit-controls toolbar buttons.
     let placement = CustomizableUI.getPlacementOfWidget("edit-controls");
     let areaType = placement ? CustomizableUI.getAreaType(placement.area) : "";
     if (areaType == CustomizableUI.TYPE_MENU_PANEL) {
-      let panelUIMenuPopupState = document.getElementById("PanelUI-popup").state;
-      if (panelUIMenuPopupState == "showing" || panelUIMenuPopupState == "open") {
+      let customizablePanel = gPhotonStructure ? PanelUI.overflowPanel : PanelUI.panel;
+      gEditUIVisible = kOpenPopupStates.includes(customizablePanel.state);
+    } else if (areaType == CustomizableUI.TYPE_TOOLBAR && window.toolbar.visible) {
+      // The edit controls are on a toolbar, so they are visible,
+      // unless they're in a panel that isn't visible...
+      if (placement.area == "nav-bar") {
+        let editControls = document.getElementById("edit-controls");
+        gEditUIVisible = !editControls.hasAttribute("overflowedItem") ||
+                          kOpenPopupStates.includes(document.getElementById("widget-overflow").state);
+      } else {
         gEditUIVisible = true;
       }
-    } else if (areaType == CustomizableUI.TYPE_TOOLBAR) {
-      // The edit controls are on a toolbar, so they are visible.
-      gEditUIVisible = true;
-    }
+    }
+  }
+
+  // Now check the main menu panel if we're using photon
+  if (!gEditUIVisible && gPhotonStructure) {
+    gEditUIVisible = kOpenPopupStates.includes(PanelUI.panel.state);
   }
 
   // No need to update commands if the edit UI visibility has not changed.
   if (gEditUIVisible == oldVisible) {
     return;
   }
 
   // If UI is visible, update the edit commands' enabled state to reflect
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -4156,16 +4156,19 @@ OverflowableToolbar.prototype = {
     return new Promise(resolve => {
       let doc = this._panel.ownerDocument;
       this._panel.hidden = false;
       let mainViewId = this._panel.querySelector("panelmultiview").getAttribute("mainViewId");
       let mainView = doc.getElementById(mainViewId);
       let contextMenu = doc.getElementById(mainView.getAttribute("context"));
       gELS.addSystemEventListener(contextMenu, "command", this, true);
       let anchor = doc.getAnonymousElementByAttribute(this._chevron, "class", "toolbarbutton-icon");
+      // Ensure we update the gEditUIVisible flag when opening the popup, in
+      // case the edit controls are in it.
+      this._panel.addEventListener("popupshowing", () => doc.defaultView.updateEditUIVisibility(), {once: true});
       this._panel.openPopup(anchor || this._chevron);
       this._chevron.open = true;
 
       let overflowableToolbarInstance = this;
       this._panel.addEventListener("popupshown", function(aEvent) {
         this.addEventListener("dragover", overflowableToolbarInstance);
         this.addEventListener("dragend", overflowableToolbarInstance);
         resolve();
@@ -4182,16 +4185,17 @@ OverflowableToolbar.prototype = {
     }
   },
 
   _onPanelHiding(aEvent) {
     this._chevron.open = false;
     this._panel.removeEventListener("dragover", this);
     this._panel.removeEventListener("dragend", this);
     let doc = aEvent.target.ownerDocument;
+    doc.defaultView.updateEditUIVisibility();
     let contextMenuId = this._panel.getAttribute("context");
     if (contextMenuId) {
       let contextMenu = doc.getElementById(contextMenuId);
       gELS.removeSystemEventListener(contextMenu, "command", this, true);
     }
   },
 
   onOverflow(aEvent) {
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -870,16 +870,27 @@ const CustomizableWidgets = [
         // put the widgets in there, so they get the right style in the panel.
         onAreaNodeRegistered: (aArea, aContainer) => {
           if (aContainer.ownerDocument == node.ownerDocument &&
               aArea == this.currentArea &&
               aArea == CustomizableUI.AREA_PANEL) {
             updateCombinedWidgetStyle(node, aArea);
           }
         },
+
+        onWidgetOverflow(aWidgetNode) {
+          if (aWidgetNode == node) {
+            node.ownerGlobal.updateEditUIVisibility();
+          }
+        },
+        onWidgetUnderflow(aWidgetNode) {
+          if (aWidgetNode == node) {
+            node.ownerGlobal.updateEditUIVisibility();
+          }
+        },
       };
       CustomizableUI.addListener(listener);
 
       return node;
     }
   },
   {
     id: "feed-button",
--- a/browser/components/customizableui/test/browser_editcontrols_update.js
+++ b/browser/components/customizableui/test/browser_editcontrols_update.js
@@ -89,18 +89,18 @@ add_task(async function test_panelui_ope
   gURLBar.select();
   await overridePromise;
   checkState(true, "Update when edit-controls is on panel, hidden and selection changed");
 });
 
 // Test updating when the edit-controls are moved to the toolbar.
 add_task(async function test_panelui_customize_to_toolbar() {
   await startCustomizing();
-  let navbar = document.getElementById("nav-bar").customizationTarget;
-  simulateItemDrag(document.getElementById("edit-controls"), navbar);
+  let navbar = document.getElementById("nav-bar");
+  simulateItemDrag(document.getElementById("edit-controls"), navbar.customizationTarget);
   await endCustomizing();
 
   // updateEditUIVisibility should be called when customization ends but isn't. See bug 1359790.
   updateEditUIVisibility();
 
   // The URL bar may have been focused to begin with, which means
   // that subsequent calls to focus it won't result in command
   // updates, so we'll make sure to blur it.
@@ -112,16 +112,73 @@ add_task(async function test_panelui_cus
   gURLBar.value = "other";
   await overridePromise;
   checkState(false, "Update when edit-controls on toolbar and focused");
 
   overridePromise = expectCommandUpdate(1);
   gURLBar.select();
   await overridePromise;
   checkState(true, "Update when edit-controls on toolbar and selection changed");
+
+  const kOverflowPanel = document.getElementById("widget-overflow");
+
+  let originalWidth = window.outerWidth;
+  registerCleanupFunction(async function() {
+    kOverflowPanel.removeAttribute("animate");
+    window.resizeTo(originalWidth, window.outerHeight);
+    await waitForCondition(() => !navbar.hasAttribute("overflowing"));
+    CustomizableUI.reset();
+  });
+
+  window.resizeTo(400, window.outerHeight);
+  await waitForCondition(() => navbar.hasAttribute("overflowing"));
+
+  // Mac will update the enabled state even when the buttons are overflowing,
+  // so main menubar shortcuts will work properly.
+  overridePromise = expectCommandUpdate(isMac ? 1 : 0);
+  gURLBar.select();
+  await overridePromise;
+  checkState(true, "Update when edit-controls is on overflow panel, hidden and selection changed");
+
+  // Check that we get an update if we select content while the panel is open.
+  overridePromise = expectCommandUpdate(1);
+  await navbar.overflowable.show();
+  gURLBar.select();
+  await overridePromise;
+
+  // And that we don't (except on mac) when the panel is hidden.
+  kOverflowPanel.hidePopup();
+  overridePromise = expectCommandUpdate(isMac ? 1 : 0);
+  gURLBar.select();
+  await overridePromise;
+
+  window.resizeTo(originalWidth, window.outerHeight);
+  await waitForCondition(() => !navbar.hasAttribute("overflowing"));
+
+  if (gPhotonStructure) {
+    CustomizableUI.addWidgetToArea("edit-controls", CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
+    // updateEditUIVisibility should be called when customization happens but isn't. See bug 1359790.
+    updateEditUIVisibility();
+
+    overridePromise = expectCommandUpdate(isMac ? 1 : 0);
+    gURLBar.select();
+    await overridePromise;
+
+    // Check that we get an update if we select content while the panel is open.
+    overridePromise = expectCommandUpdate(1);
+    await navbar.overflowable.show();
+    gURLBar.select();
+    await overridePromise;
+
+    // And that we don't (except on mac) when the panel is hidden.
+    kOverflowPanel.hidePopup();
+    overridePromise = expectCommandUpdate(isMac ? 1 : 0);
+    gURLBar.select();
+    await overridePromise;
+  }
 });
 
 // Test updating when the edit-controls are moved to the palette.
 add_task(async function test_panelui_customize_to_palette() {
   await startCustomizing();
   let palette = document.getElementById("customization-palette");
   simulateItemDrag(document.getElementById("edit-controls"), palette);
   await endCustomizing();