Bug 1507704 - Migrate the columnpicker binding into a custom element, r=bgrins
authorVictor Porof <vporof@mozilla.com>
Mon, 14 Jan 2019 09:38:24 +0100
changeset 454319 dae7a246b32daf628361e3fce4d5f56f4cf5b177
parent 454274 ff0feb041ccc0381977b00ab136bc7378bf6200e
child 454320 59bdefa77dc74de0e31f59c9069445b66e602514
push id35393
push userncsoregi@mozilla.com
push dateThu, 17 Jan 2019 21:55:14 +0000
treeherdermozilla-central@1db2248f4415 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1507704
milestone66.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 1507704 - Migrate the columnpicker binding into a custom element, r=bgrins
layout/base/nsCSSFrameConstructor.cpp
toolkit/content/widgets/tree.js
toolkit/content/widgets/tree.xml
toolkit/content/xul.css
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3972,16 +3972,17 @@ nsCSSFrameConstructor::FindXULTagData(co
 #ifdef MOZ_XUL
       SCROLLABLE_XUL_CREATE(button, NS_NewButtonBoxFrame),
       SCROLLABLE_XUL_CREATE(thumb, NS_NewButtonBoxFrame),
       SCROLLABLE_XUL_CREATE(checkbox, NS_NewButtonBoxFrame),
       SCROLLABLE_XUL_CREATE(radio, NS_NewButtonBoxFrame),
       SCROLLABLE_XUL_CREATE(titlebar, NS_NewTitleBarFrame),
       SCROLLABLE_XUL_CREATE(resizer, NS_NewResizerFrame),
       SCROLLABLE_XUL_CREATE(toolbarpaletteitem, NS_NewBoxFrame),
+      SCROLLABLE_XUL_CREATE(treecolpicker, NS_NewButtonBoxFrame),
       SIMPLE_XUL_CREATE(image, NS_NewImageBoxFrame),
       SIMPLE_XUL_CREATE(spring, NS_NewLeafBoxFrame),
       SIMPLE_XUL_CREATE(spacer, NS_NewLeafBoxFrame),
       SIMPLE_XUL_CREATE(treechildren, NS_NewTreeBodyFrame),
       SIMPLE_XUL_CREATE(treecol, NS_NewTreeColFrame),
       SIMPLE_XUL_CREATE(text, NS_NewTextBoxFrame),
       SIMPLE_TAG_CHAIN(label, nsCSSFrameConstructor::FindXULLabelData),
       SIMPLE_TAG_CHAIN(description,
--- a/toolkit/content/widgets/tree.js
+++ b/toolkit/content/widgets/tree.js
@@ -159,16 +159,103 @@
       if ("_ensureColumnOrder" in this.parentNode)
         this.parentNode._ensureColumnOrder();
 
     }
   }
 
   customElements.define("treechildren", MozTreeChildren);
 
+  class MozTreecolPicker extends MozElements.BaseControl {
+    constructor() {
+      super();
+
+      this.addEventListener("command", (event) => {
+        if (event.originalTarget == this) {
+          var popup = this.querySelector("[anonid=\"popup\"]");
+          this.buildPopup(popup);
+          popup.openPopup(this, "after_end");
+        } else {
+          var tree = this.parentNode.parentNode;
+          tree.stopEditing(true);
+          var menuitem = this.querySelector("[anonid=\"menuitem\"]");
+          if (event.originalTarget == menuitem) {
+            tree.columns.restoreNaturalOrder();
+            this.removeAttribute("ordinal");
+            tree._ensureColumnOrder();
+          } else {
+            var colindex = event.originalTarget.getAttribute("colindex");
+            var column = tree.columns[colindex];
+            if (column) {
+              var element = column.element;
+              if (element.getAttribute("hidden") == "true")
+                element.setAttribute("hidden", "false");
+              else
+                element.setAttribute("hidden", "true");
+            }
+          }
+        }
+      });
+
+    }
+
+    connectedCallback() {
+      if (this.delayConnectedCallback()) {
+        return;
+      }
+
+      this.textContent = "";
+      this.appendChild(MozXULElement.parseXULToFragment(`
+        <image class="tree-columnpicker-icon"></image>
+        <menupopup anonid="popup">
+          <menuseparator anonid="menuseparator"></menuseparator>
+          <menuitem anonid="menuitem" label="&restoreColumnOrder.label;"></menuitem>
+        </menupopup>
+      `, ["chrome://global/locale/tree.dtd"]));
+
+    }
+
+    buildPopup(aPopup) {
+      // We no longer cache the picker content, remove the old content.
+      while (aPopup.childNodes.length > 2)
+        aPopup.firstChild.remove();
+
+      var refChild = aPopup.firstChild;
+
+      var tree = this.parentNode.parentNode;
+      for (var currCol = tree.columns.getFirstColumn(); currCol; currCol = currCol.getNext()) {
+        // Construct an entry for each column in the row, unless
+        // it is not being shown.
+        var currElement = currCol.element;
+        if (!currElement.hasAttribute("ignoreincolumnpicker")) {
+          var popupChild = document.createElement("menuitem");
+          popupChild.setAttribute("type", "checkbox");
+          var columnName = currElement.getAttribute("display") ||
+            currElement.getAttribute("label");
+          popupChild.setAttribute("label", columnName);
+          popupChild.setAttribute("colindex", currCol.index);
+          if (currElement.getAttribute("hidden") != "true")
+            popupChild.setAttribute("checked", "true");
+          if (currCol.primary)
+            popupChild.setAttribute("disabled", "true");
+          aPopup.insertBefore(popupChild, refChild);
+        }
+      }
+
+      var hidden = !tree.enableColumnDrag;
+      const anonids = ["menuseparator", "menuitem"];
+      for (var i = 0; i < anonids.length; i++) {
+        var element = this.querySelector(`[anonid=\"${anonids[i]}\"]`);
+        element.hidden = hidden;
+      }
+    }
+  }
+
+  customElements.define("treecolpicker", MozTreecolPicker);
+
   class MozTreecol extends MozElements.BaseControl {
     static get observedAttributes() {
       return [
         "label",
         "sortdirection",
         "hideheader",
         "crop",
       ];
--- a/toolkit/content/widgets/tree.xml
+++ b/toolkit/content/widgets/tree.xml
@@ -906,93 +906,9 @@
           else if (event.detail == 0)
             tree.removeAttribute("hidevscroll");
           event.stopPropagation();
         ]]>
       </handler>
     </handlers>
   </binding>
 
-  <binding id="columnpicker" display="xul:button"
-           extends="chrome://global/content/bindings/general.xml#basecontrol">
-    <content>
-      <xul:image class="tree-columnpicker-icon"/>
-      <xul:menupopup anonid="popup">
-        <xul:menuseparator anonid="menuseparator"/>
-        <xul:menuitem anonid="menuitem" label="&restoreColumnOrder.label;"/>
-      </xul:menupopup>
-    </content>
-
-    <implementation>
-      <method name="buildPopup">
-        <parameter name="aPopup"/>
-        <body>
-          <![CDATA[
-            // We no longer cache the picker content, remove the old content.
-            while (aPopup.childNodes.length > 2)
-              aPopup.firstChild.remove();
-
-            var refChild = aPopup.firstChild;
-
-            var tree = this.parentNode.parentNode;
-            for (var currCol = tree.columns.getFirstColumn(); currCol;
-                 currCol = currCol.getNext()) {
-              // Construct an entry for each column in the row, unless
-              // it is not being shown.
-              var currElement = currCol.element;
-              if (!currElement.hasAttribute("ignoreincolumnpicker")) {
-                var popupChild = document.createElement("menuitem");
-                popupChild.setAttribute("type", "checkbox");
-                var columnName = currElement.getAttribute("display") ||
-                                 currElement.getAttribute("label");
-                popupChild.setAttribute("label", columnName);
-                popupChild.setAttribute("colindex", currCol.index);
-                if (currElement.getAttribute("hidden") != "true")
-                  popupChild.setAttribute("checked", "true");
-                if (currCol.primary)
-                  popupChild.setAttribute("disabled", "true");
-                aPopup.insertBefore(popupChild, refChild);
-              }
-            }
-
-            var hidden = !tree.enableColumnDrag;
-            const anonids = ["menuseparator", "menuitem"];
-            for (var i = 0; i < anonids.length; i++) {
-              var element = document.getAnonymousElementByAttribute(this, "anonid", anonids[i]);
-              element.hidden = hidden;
-            }
-          ]]>
-        </body>
-      </method>
-    </implementation>
-
-    <handlers>
-      <handler event="command">
-        <![CDATA[
-          if (event.originalTarget == this) {
-            var popup = document.getAnonymousElementByAttribute(this, "anonid", "popup");
-            this.buildPopup(popup);
-            popup.openPopup(this, "after_end");
-          } else {
-            var tree = this.parentNode.parentNode;
-            tree.stopEditing(true);
-            var menuitem = document.getAnonymousElementByAttribute(this, "anonid", "menuitem");
-            if (event.originalTarget == menuitem) {
-              tree.columns.restoreNaturalOrder();
-              this.removeAttribute("ordinal");
-              tree._ensureColumnOrder();
-            } else {
-              var colindex = event.originalTarget.getAttribute("colindex");
-              var column = tree.columns[colindex];
-              if (column) {
-                var element = column.element;
-                if (element.getAttribute("hidden") == "true")
-                  element.setAttribute("hidden", "false");
-                else
-                  element.setAttribute("hidden", "true");
-              }
-            }
-          }
-        ]]>
-      </handler>
-    </handlers>
-  </binding>
 </bindings>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -443,20 +443,16 @@ tree > treechildren {
   -moz-user-select: none;
   -moz-box-flex: 1;
 }
 
 treerows {
   -moz-binding: url("chrome://global/content/bindings/tree.xml#treerows");
 }
 
-treecolpicker {
-  -moz-binding: url("chrome://global/content/bindings/tree.xml#columnpicker");
-}
-
 tree {
   -moz-box-orient: vertical;
   min-width: 0px;
   min-height: 0px;
   width: 10px;
   height: 10px;
 }