Bug 1284221 - Move the font panel to the last position in the sidebar; r=jdescottes
authorPatrick Brosset <pbrosset@mozilla.com>
Mon, 04 Jul 2016 15:21:58 +0200
changeset 303486 76746a3c04de178f267af8a716f8ae419f09ac91
parent 303485 05cb30a038a27b6ef490bbb453cc3424f836e7dc
child 303487 bb2fbb0f9984d4fa0ebf020ef00086384a1865bf
push id19856
push userpbrosset@mozilla.com
push dateMon, 04 Jul 2016 13:25:56 +0000
treeherderfx-team@76746a3c04de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1284221
milestone50.0a1
Bug 1284221 - Move the font panel to the last position in the sidebar; r=jdescottes MozReview-Commit-ID: Kh64bTWxQkA
devtools/client/framework/sidebar.js
devtools/client/framework/test/browser_toolbox_sidebar.js
devtools/client/framework/test/browser_toolbox_sidebar_events.js
devtools/client/framework/test/browser_toolbox_sidebar_overflow_menu.js
devtools/client/inspector/inspector-panel.js
devtools/client/inspector/inspector.xul
devtools/client/scratchpad/scratchpad.js
devtools/client/webconsole/jsterm.js
--- a/devtools/client/framework/sidebar.js
+++ b/devtools/client/framework/sidebar.js
@@ -139,17 +139,19 @@ ToolSidebar.prototype = {
 
     // Listening to tabs overflow event to toggle the alltabs button
     tabs.addEventListener("overflow", this._onTabBoxOverflow, false);
     tabs.addEventListener("underflow", this._onTabBoxUnderflow, false);
 
     // Add menuitems to the alltabs menu if there are already tabs in the
     // sidebar
     for (let [id, tab] of this._tabs) {
-      let item = this._addItemToAllTabsMenu(id, tab, tab.hasAttribute("selected"));
+      let item = this._addItemToAllTabsMenu(id, tab, {
+        selected: tab.hasAttribute("selected")
+      });
       if (tab.hidden) {
         item.hidden = true;
       }
     }
   },
 
   removeAllTabsMenu: function () {
     if (!this._allTabsBtn) {
@@ -174,66 +176,85 @@ ToolSidebar.prototype = {
 
   _onTabBoxUnderflow: function () {
     this._allTabsBtn.setAttribute("hidden", "true");
   },
 
   /**
    * Add an item in the allTabs menu for a given tab.
    */
-  _addItemToAllTabsMenu: function (id, tab, selected = false) {
+  _addItemToAllTabsMenu: function (id, tab, options) {
     if (!this._allTabsBtn) {
       return;
     }
 
     let item = this._panelDoc.createElementNS(XULNS, "menuitem");
-    item.setAttribute("id", "sidebar-alltabs-item-" + id);
+    let idPrefix = "sidebar-alltabs-item-";
+    item.setAttribute("id", idPrefix + id);
     item.setAttribute("label", tab.getAttribute("label"));
     item.setAttribute("type", "checkbox");
-    if (selected) {
+    if (options.selected) {
       item.setAttribute("checked", true);
     }
     // The auto-checking of menuitems in this menu doesn't work, so let's do
     // it manually
     item.setAttribute("autocheck", false);
 
-    this._allTabsBtn.querySelector("menupopup").appendChild(item);
+    let menu = this._allTabsBtn.querySelector("menupopup");
+    if (options.insertBefore) {
+      let referenceItem = menu.querySelector(`#${idPrefix}${options.insertBefore}`);
+      menu.insertBefore(item, referenceItem);
+    } else {
+      menu.appendChild(item);
+    }
 
     item.addEventListener("click", () => {
       this._tabbox.selectedTab = tab;
     }, false);
 
     tab.allTabsMenuItem = item;
 
     return item;
   },
 
   /**
    * Register a tab. A tab is a document.
    * The document must have a title, which will be used as the name of the tab.
    *
-   * @param {string} tab uniq id
-   * @param {string} url
+   * @param {string} id The unique id for this tab.
+   * @param {string} url The URL of the document to load in this new tab.
+   * @param {Object} options A set of options for this new tab:
+   * - {Boolean} selected Set to true to make this new tab selected by default.
+   * - {String} insertBefore By default, the new tab is appended at the end of the
+   * tabbox, pass the ID of an existing tab to insert it before that tab instead.
    */
-  addTab: function (id, url, selected = false) {
+  addTab: function (id, url, options = {}) {
     let iframe = this._panelDoc.createElementNS(XULNS, "iframe");
     iframe.className = "iframe-" + id;
     iframe.setAttribute("flex", "1");
     iframe.setAttribute("src", url);
     iframe.tooltip = "aHTMLTooltip";
 
     // Creating the tab and adding it to the tabbox
     let tab = this._panelDoc.createElementNS(XULNS, "tab");
-    this._tabbox.tabs.appendChild(tab);
-    tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading
+
     tab.setAttribute("id", this.TAB_ID_PREFIX + id);
     tab.setAttribute("crop", "end");
+    // Avoid showing "undefined" while the tab is loading
+    tab.setAttribute("label", "");
+
+    if (options.insertBefore) {
+      let referenceTab = this.getTab(options.insertBefore);
+      this._tabbox.tabs.insertBefore(tab, referenceTab);
+    } else {
+      this._tabbox.tabs.appendChild(tab);
+    }
 
     // Add the tab to the allTabs menu if exists
-    let allTabsItem = this._addItemToAllTabsMenu(id, tab, selected);
+    let allTabsItem = this._addItemToAllTabsMenu(id, tab, options);
 
     let onIFrameLoaded = (event) => {
       let doc = event.target;
       let win = doc.defaultView;
       tab.setAttribute("label", doc.title);
 
       if (allTabsItem) {
         allTabsItem.setAttribute("label", doc.title);
@@ -246,29 +267,35 @@ ToolSidebar.prototype = {
       this.emit(id + "-ready");
     };
 
     iframe.addEventListener("load", onIFrameLoaded, true);
 
     let tabpanel = this._panelDoc.createElementNS(XULNS, "tabpanel");
     tabpanel.setAttribute("id", this.TABPANEL_ID_PREFIX + id);
     tabpanel.appendChild(iframe);
-    this._tabbox.tabpanels.appendChild(tabpanel);
+
+    if (options.insertBefore) {
+      let referenceTabpanel = this.getTabPanel(options.insertBefore);
+      this._tabbox.tabpanels.insertBefore(tabpanel, referenceTabpanel);
+    } else {
+      this._tabbox.tabpanels.appendChild(tabpanel);
+    }
 
     this._tooltip = this._panelDoc.createElementNS(XULNS, "tooltip");
     this._tooltip.id = "aHTMLTooltip";
     tabpanel.appendChild(this._tooltip);
     this._tooltip.page = true;
 
     tab.linkedPanel = this.TABPANEL_ID_PREFIX + id;
 
     // We store the index of this tab.
     this._tabs.set(id, tab);
 
-    if (selected) {
+    if (options.selected) {
       this._selectTabSoon(id);
     }
 
     this.emit("new-tab-registered", id);
   },
 
   untitledTabsIndex: 0,
 
--- a/devtools/client/framework/test/browser_toolbox_sidebar.js
+++ b/devtools/client/framework/test/browser_toolbox_sidebar.js
@@ -78,17 +78,17 @@ function test() {
       });
 
       panel.sidebar.once("tab1-selected", function (event) {
         info(event);
         tab1Selected = true;
         allTabsReady(panel);
       });
 
-      panel.sidebar.addTab("tab1", tab1URL, true);
+      panel.sidebar.addTab("tab1", tab1URL, {selected: true});
       panel.sidebar.addTab("tab2", tab2URL);
       panel.sidebar.addTab("tab3", tab3URL);
 
       panel.sidebar.show();
     }).then(null, console.error);
   });
 
   function allTabsReady(panel) {
--- a/devtools/client/framework/test/browser_toolbox_sidebar_events.js
+++ b/devtools/client/framework/test/browser_toolbox_sidebar_events.js
@@ -62,17 +62,17 @@ function test() {
         collectedEvents.push(event);
       });
 
       panel.sidebar.once("hide", function (event, id) {
         collectedEvents.push(event);
       });
 
       panel.sidebar.once("tab1-selected", () => finishUp(panel));
-      panel.sidebar.addTab("tab1", tab1URL, true);
+      panel.sidebar.addTab("tab1", tab1URL, {selected: true});
       panel.sidebar.show();
     }).then(null, console.error);
   });
 
   function finishUp(panel) {
     panel.sidebar.hide();
     panel.sidebar.destroy();
 
--- a/devtools/client/framework/test/browser_toolbox_sidebar_overflow_menu.js
+++ b/devtools/client/framework/test/browser_toolbox_sidebar_overflow_menu.js
@@ -43,17 +43,17 @@ add_task(function* () {
 
   let allTabsMenu = toolPanel.panelDoc.querySelector(".devtools-sidebar-alltabs");
   ok(allTabsMenu, "The all-tabs menu is available");
   is(allTabsMenu.getAttribute("hidden"), "true", "The menu is hidden for now");
 
   info("Adding 10 tabs to the sidebar widget");
   for (let nb = 0; nb < 10; nb++) {
     let url = `data:text/html;charset=utf8,<title>tab ${nb}</title><p>Test tab ${nb}</p>`;
-    sidebar.addTab("tab" + nb, url, nb === 0);
+    sidebar.addTab("tab" + nb, url, {selected: nb === 0});
   }
 
   info("Fake an overflow event so that the all-tabs menu is visible");
   sidebar._onTabBoxOverflow();
   ok(!allTabsMenu.hasAttribute("hidden"), "The all-tabs menu is now shown");
 
   info("Select each tab, one by one");
   for (let nb = 0; nb < 10; nb++) {
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -402,31 +402,31 @@ InspectorPanel.prototype = {
     this._setDefaultSidebar = (event, toolId) => {
       Services.prefs.setCharPref("devtools.inspector.activeSidebar", toolId);
     };
 
     this.sidebar.on("select", this._setDefaultSidebar);
 
     this.ruleview = new RuleViewTool(this, this.panelWin);
     this.computedview = new ComputedViewTool(this, this.panelWin);
+    this.layoutview = new LayoutView(this, this.panelWin);
+
+    if (this.target.form.animationsActor) {
+      this.sidebar.addTab("animationinspector",
+                          "chrome://devtools/content/animationinspector/animation-inspector.xhtml",
+                          {selected: defaultTab == "animationinspector",
+                           insertBefore: "fontinspector"});
+    }
 
     if (Services.prefs.getBoolPref("devtools.fontinspector.enabled") &&
         this.canGetUsedFontFaces) {
       this.fontInspector = new FontInspector(this, this.panelWin);
       this.sidebar.toggleTab(true, "fontinspector");
     }
 
-    this.layoutview = new LayoutView(this, this.panelWin);
-
-    if (this.target.form.animationsActor) {
-      this.sidebar.addTab("animationinspector",
-                          "chrome://devtools/content/animationinspector/animation-inspector.xhtml",
-                          defaultTab == "animationinspector");
-    }
-
     this.sidebar.show(defaultTab);
 
     this.setupSidebarToggle();
   },
 
   /**
    * Add the expand/collapse behavior for the sidebar panel.
    */
--- a/devtools/client/inspector/inspector.xul
+++ b/devtools/client/inspector/inspector.xul
@@ -53,23 +53,23 @@
     <tabbox id="inspector-sidebar" handleCtrlTab="false" class="devtools-sidebar-tabs" hidden="true">
       <tabs>
         <tab id="sidebar-tab-ruleview"
              label="&ruleViewTitle;"
              crop="end"/>
         <tab id="sidebar-tab-computedview"
              label="&computedViewTitle;"
              crop="end"/>
+        <tab id="sidebar-tab-layoutview"
+             label="&layoutViewTitle;"
+             crop="end"/>
         <tab id="sidebar-tab-fontinspector"
              label="&fontInspectorTitle;"
              crop="end"
              hidden="true"/>
-        <tab id="sidebar-tab-layoutview"
-             label="&layoutViewTitle;"
-             crop="end"/>
       </tabs>
       <tabpanels flex="1">
         <tabpanel id="sidebar-panel-ruleview" class="devtools-monospace theme-sidebar inspector-tabpanel">
           <html:div id="ruleview-toolbar-container" class="devtools-toolbar">
             <html:div id="ruleview-toolbar">
               <html:div class="devtools-searchbox">
                 <html:input id="ruleview-searchbox"
                             class="devtools-searchinput devtools-rule-searchbox"
@@ -111,51 +111,16 @@
           <html:div id="propertyContainer">
           </html:div>
 
           <html:div id="computedview-no-results" hidden="">
             &noPropertiesFound;
           </html:div>
         </tabpanel>
 
-        <tabpanel id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
-          <html:div class="devtools-toolbar">
-            <html:div class="devtools-searchbox">
-              <html:input id="font-preview-text-input"
-                          class="devtools-textinput"
-                          type="search"
-                          placeholder="&previewHint;"/>
-            </html:div>
-          </html:div>
-
-          <html:div id="font-container">
-            <html:ul id="all-fonts"></html:ul>
-            <html:button id="font-showall">&showAllFonts;</html:button>
-          </html:div>
-
-          <html:div id="font-template">
-            <html:section class="font">
-              <html:div class="font-preview-container">
-                <html:img class="font-preview"></html:img>
-              </html:div>
-              <html:div class="font-info">
-                <html:h1 class="font-name"></html:h1>
-                <html:span class="font-is-local">&system;</html:span>
-                <html:span class="font-is-remote">&remote;</html:span>
-                <html:p class="font-format-url">
-                  <html:input readonly="readonly" class="font-url"></html:input>
-                  <html:span class="font-format"></html:span>
-                </html:p>
-                <html:p class="font-css">&usedAs; "<html:span class="font-css-name"></html:span>"</html:p>
-                <html:pre class="font-css-code"></html:pre>
-              </html:div>
-            </html:section>
-          </html:div>
-        </tabpanel>
-
         <tabpanel id="sidebar-panel-layoutview" class="devtools-monospace theme-sidebar inspector-tabpanel">
           <html:div id="layout-wrapper">
             <html:div id="layout-container">
               <html:p id="layout-header">
                 <html:span id="layout-element-size"></html:span>
                 <html:section id="layout-position-group">
                   <html:button class="devtools-button" id="layout-geometry-editor" title="&geometry.button.tooltip;"></html:button>
                   <html:span id="layout-element-position"></html:span>
@@ -194,12 +159,47 @@
               </html:div>
 
               <html:div style="display: none">
                 <html:p id="layout-dummy"></html:p>
               </html:div>
             </html:div>
           </html:div>
         </tabpanel>
+
+        <tabpanel id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
+          <html:div class="devtools-toolbar">
+            <html:div class="devtools-searchbox">
+              <html:input id="font-preview-text-input"
+                          class="devtools-textinput"
+                          type="search"
+                          placeholder="&previewHint;"/>
+            </html:div>
+          </html:div>
+
+          <html:div id="font-container">
+            <html:ul id="all-fonts"></html:ul>
+            <html:button id="font-showall">&showAllFonts;</html:button>
+          </html:div>
+
+          <html:div id="font-template">
+            <html:section class="font">
+              <html:div class="font-preview-container">
+                <html:img class="font-preview"></html:img>
+              </html:div>
+              <html:div class="font-info">
+                <html:h1 class="font-name"></html:h1>
+                <html:span class="font-is-local">&system;</html:span>
+                <html:span class="font-is-remote">&remote;</html:span>
+                <html:p class="font-format-url">
+                  <html:input readonly="readonly" class="font-url"></html:input>
+                  <html:span class="font-format"></html:span>
+                </html:p>
+                <html:p class="font-css">&usedAs; "<html:span class="font-css-name"></html:span>"</html:p>
+                <html:pre class="font-css-code"></html:pre>
+              </html:div>
+            </html:section>
+          </html:div>
+        </tabpanel>
       </tabpanels>
     </tabbox>
   </box>
 </window>
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -2304,17 +2304,17 @@ ScratchpadSidebar.prototype = {
       this._update(aObject).then(() => deferred.resolve());
     };
 
     if (this._sidebar.getCurrentTabID() == "variablesview") {
       onTabReady();
     }
     else {
       this._sidebar.once("variablesview-ready", onTabReady);
-      this._sidebar.addTab("variablesview", VARIABLES_VIEW_URL, true);
+      this._sidebar.addTab("variablesview", VARIABLES_VIEW_URL, {selected: true});
     }
 
     return deferred.promise;
   },
 
   /**
    * Show the sidebar.
    */
--- a/devtools/client/webconsole/jsterm.js
+++ b/devtools/client/webconsole/jsterm.js
@@ -652,17 +652,17 @@ JSTerm.prototype = {
       if (this.sidebar.getCurrentTabID() == "variablesview") {
         onTabReady();
       } else {
         this.sidebar.once("variablesview-selected", onTabReady);
         this.sidebar.select("variablesview");
       }
     } else {
       this.sidebar.once("variablesview-ready", onTabReady);
-      this.sidebar.addTab("variablesview", VARIABLES_VIEW_URL, true);
+      this.sidebar.addTab("variablesview", VARIABLES_VIEW_URL, {selected: true});
     }
 
     return deferred.promise;
   },
 
   /**
    * The keypress event handler for the Variables View sidebar. Currently this
    * is used for removing the sidebar when Escape is pressed.