Bug 1259093: Part 2 - Reparent view nodes before dispatching ViewShowing event. r?Gijs draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 16 Aug 2016 18:31:57 -0700
changeset 401495 c07402726353cb395c827c1f66257ebcb817a1a7
parent 400540 7964660fb2234a9352d2682bcea84171f879a907
child 401496 d58a2a6de72632459e3a9d9764c417bfb725fcd2
push id26462
push usermaglione.k@gmail.com
push dateWed, 17 Aug 2016 01:44:40 +0000
reviewersGijs
bugs1259093
milestone51.0a1
Bug 1259093: Part 2 - Reparent view nodes before dispatching ViewShowing event. r?Gijs MozReview-Commit-ID: IRkAJYQFd1C
browser/components/customizableui/content/panelUI.js
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -315,38 +315,16 @@ const PanelUI = {
       Cu.reportError("Expected an anchor when opening subview with id: " + aViewId);
       return;
     }
 
     if (aPlacementArea == CustomizableUI.AREA_PANEL) {
       this.multiView.showSubView(aViewId, aAnchor);
     } else if (!aAnchor.open) {
       aAnchor.open = true;
-      // Emit the ViewShowing event so that the widget definition has a chance
-      // to lazily populate the subview with things.
-      let detail = {
-        blockers: new Set(),
-        addBlocker(aPromise) {
-          this.blockers.add(aPromise);
-        },
-      };
-
-      let evt = new CustomEvent("ViewShowing", { bubbles: true, cancelable: true, detail });
-      viewNode.dispatchEvent(evt);
-
-      let cancel = evt.defaultPrevented;
-      if (detail.blockers.size) {
-        let results = yield Promise.all(detail.blockers);
-        cancel = cancel || results.some(val => val === false);
-      }
-
-      if (cancel) {
-        aAnchor.open = false;
-        return;
-      }
 
       let tempPanel = document.createElement("panel");
       tempPanel.setAttribute("type", "arrow");
       tempPanel.setAttribute("id", "customizationui-widget-panel");
       tempPanel.setAttribute("class", "cui-widget-panel");
       tempPanel.setAttribute("viewId", aViewId);
       if (this._disableAnimations) {
         tempPanel.setAttribute("animate", "false");
@@ -359,29 +337,58 @@ const PanelUI = {
 
       let multiView = document.createElement("panelmultiview");
       multiView.setAttribute("id", "customizationui-widget-multiview");
       multiView.setAttribute("nosubviews", "true");
       tempPanel.appendChild(multiView);
       multiView.setAttribute("mainViewIsSubView", "true");
       multiView.setMainView(viewNode);
       viewNode.classList.add("cui-widget-panelview");
-      CustomizableUI.addPanelCloseListeners(tempPanel);
 
-      let panelRemover = function() {
-        tempPanel.removeEventListener("popuphidden", panelRemover);
+      let viewShown = false;
+      let panelRemover = () => {
         viewNode.classList.remove("cui-widget-panelview");
-        CustomizableUI.removePanelCloseListeners(tempPanel);
-        let evt = new CustomEvent("ViewHiding", {detail: viewNode});
-        viewNode.dispatchEvent(evt);
+        if (viewShown) {
+          CustomizableUI.removePanelCloseListeners(tempPanel);
+          tempPanel.removeEventListener("popuphidden", panelRemover);
+
+          let evt = new CustomEvent("ViewHiding", {detail: viewNode});
+          viewNode.dispatchEvent(evt);
+        }
         aAnchor.open = false;
 
         this.multiView.appendChild(viewNode);
-        tempPanel.parentElement.removeChild(tempPanel);
-      }.bind(this);
+        tempPanel.remove();
+      };
+
+      // Emit the ViewShowing event so that the widget definition has a chance
+      // to lazily populate the subview with things.
+      let detail = {
+        blockers: new Set(),
+        addBlocker(aPromise) {
+          this.blockers.add(aPromise);
+        },
+      };
+
+      let evt = new CustomEvent("ViewShowing", { bubbles: true, cancelable: true, detail });
+      viewNode.dispatchEvent(evt);
+
+      let cancel = evt.defaultPrevented;
+      if (detail.blockers.size) {
+        let results = yield Promise.all(detail.blockers);
+        cancel = cancel || results.some(val => val === false);
+      }
+
+      if (cancel) {
+        panelRemover();
+        return;
+      }
+
+      viewShown = true;
+      CustomizableUI.addPanelCloseListeners(tempPanel);
       tempPanel.addEventListener("popuphidden", panelRemover);
 
       let iconAnchor =
         document.getAnonymousElementByAttribute(aAnchor, "class",
                                                 "toolbarbutton-icon");
 
       if (iconAnchor && aAnchor.id) {
         iconAnchor.setAttribute("consumeanchor", aAnchor.id);