Bug 859062 - [netmonitor] Hide right arrow in the SideMenuWidget, r=dcamp
authorVictor Porof <vporof@mozilla.com>
Wed, 10 Apr 2013 02:05:09 +0300
changeset 128278 9c4a7e02a3d61a89a05bf5d877a30e9a71fa5b46
parent 128277 2e2ae594b1acebe9e83d8528ca1797b4548454ea
child 128279 730c2bb841eea7292adc3d260b818524f5b912e7
push id24524
push userryanvm@gmail.com
push dateWed, 10 Apr 2013 18:39:26 +0000
treeherdermozilla-central@1a426b650b1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdcamp
bugs859062
milestone23.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 859062 - [netmonitor] Hide right arrow in the SideMenuWidget, r=dcamp
browser/devtools/netmonitor/netmonitor-view.js
browser/devtools/netmonitor/netmonitor.xul
browser/devtools/shared/widgets/SideMenuWidget.jsm
browser/themes/linux/devtools/netmonitor.css
browser/themes/linux/devtools/widgets.css
browser/themes/osx/devtools/netmonitor.css
browser/themes/osx/devtools/widgets.css
browser/themes/windows/devtools/netmonitor.css
browser/themes/windows/devtools/widgets.css
--- a/browser/devtools/netmonitor/netmonitor-view.js
+++ b/browser/devtools/netmonitor/netmonitor-view.js
@@ -254,17 +254,17 @@ function RequestsMenuView() {
 
 create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
   /**
    * Initialization function, called when the network monitor is started.
    */
   initialize: function NVRM_initialize() {
     dumpn("Initializing the RequestsMenuView");
 
-    this.node = new SideMenuWidget($("#requests-menu-contents"));
+    this.node = new SideMenuWidget($("#requests-menu-contents"), false);
 
     this.node.addEventListener("mousedown", this._onMouseDown, false);
     this.node.addEventListener("select", this._onSelect, false);
     window.addEventListener("resize", this._onResize, false);
   },
 
   /**
    * Destruction function, called when the network monitor is closed.
@@ -453,28 +453,33 @@ create({ constructor: RequestsMenuView, 
    */
   _createMenuView: function NVRM__createMenuView(aMethod, aUrl) {
     let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
     let name = NetworkHelper.convertToUnicode(unescape(uri.fileName)) || "/";
     let query = NetworkHelper.convertToUnicode(unescape(uri.query));
     let hostPort = NetworkHelper.convertToUnicode(unescape(uri.hostPort));
 
     let template = $("#requests-menu-item-template");
-    let requestsMenuItem = template.firstChild.cloneNode(true);
+    let fragment = document.createDocumentFragment();
 
-    $(".requests-menu-method", requestsMenuItem)
+    $(".requests-menu-method", template)
       .setAttribute("value", aMethod);
 
-    $(".requests-menu-file", requestsMenuItem)
+    $(".requests-menu-file", template)
       .setAttribute("value", name + (query ? "?" + query : ""));
 
-    $(".requests-menu-domain", requestsMenuItem)
+    $(".requests-menu-domain", template)
       .setAttribute("value", hostPort);
 
-    return requestsMenuItem;
+    // Flatten the DOM by removing one redundant box (the template container).
+    for (let node of template.childNodes) {
+      fragment.appendChild(node.cloneNode(true));
+    }
+
+    return fragment;
   },
 
   /**
    * Updates the information displayed in a network request item view.
    *
    * @param MenuItem aItem
    *        The network request item in this container.
    * @param string aKey
--- a/browser/devtools/netmonitor/netmonitor.xul
+++ b/browser/devtools/netmonitor/netmonitor.xul
@@ -50,45 +50,43 @@
         <toolbarbutton id="details-pane-toggle"
                        class="devtools-toolbarbutton"
                        tooltiptext="&netmonitorUI.panesButton.tooltip;"
                        tabindex="0"/>
       </toolbar>
       <label class="plain requests-menu-empty-notice"
              value="&netmonitorUI.emptyNotice;"/>
       <vbox id="requests-menu-contents" flex="1">
-        <template id="requests-menu-item-template">
-          <hbox class="requests-menu-item">
-            <hbox class="requests-menu-subitem requests-menu-status-and-method"
+        <hbox id="requests-menu-item-template" hidden="true">
+          <hbox class="requests-menu-subitem requests-menu-status-and-method"
+                align="center">
+            <hbox class="requests-menu-status"/>
+            <label class="plain requests-menu-method"
+                   crop="end"
+                   flex="1"/>
+          </hbox>
+          <label class="plain requests-menu-subitem requests-menu-file"
+                 crop="end"/>
+          <label class="plain requests-menu-subitem requests-menu-domain"
+                 crop="end"/>
+          <label class="plain requests-menu-subitem requests-menu-type"
+                 crop="end"/>
+          <label class="plain requests-menu-subitem requests-menu-size"
+                 crop="end"/>
+          <hbox class="requests-menu-subitem requests-menu-waterfall"
+                align="center"
+                flex="1">
+            <hbox class="requests-menu-timings"
                   align="center">
-              <hbox class="requests-menu-status"/>
-              <label class="plain requests-menu-method"
-                     crop="end"
-                     flex="1"/>
-            </hbox>
-            <label class="plain requests-menu-subitem requests-menu-file"
-                   crop="end"/>
-            <label class="plain requests-menu-subitem requests-menu-domain"
-                   crop="end"/>
-            <label class="plain requests-menu-subitem requests-menu-type"
-                   crop="end"/>
-            <label class="plain requests-menu-subitem requests-menu-size"
-                   crop="end"/>
-            <hbox class="requests-menu-subitem requests-menu-waterfall"
-                  align="center"
-                  flex="1">
-              <hbox class="requests-menu-timings"
-                    align="center">
-                <hbox class="start requests-menu-timings-cap" hidden="true"/>
-                <hbox class="end requests-menu-timings-cap" hidden="true"/>
-                <label class="plain requests-menu-timings-total"/>
-              </hbox>
+              <hbox class="start requests-menu-timings-cap" hidden="true"/>
+              <hbox class="end requests-menu-timings-cap" hidden="true"/>
+              <label class="plain requests-menu-timings-total"/>
             </hbox>
           </hbox>
-        </template>
+        </hbox>
       </vbox>
     </vbox>
 
     <splitter class="devtools-side-splitter"/>
 
     <tabbox id="details-pane" class="devtools-sidebar-tabs" hidden="true">
       <tabs>
         <tab label="&netmonitorUI.tab.headers;"/>
--- a/browser/devtools/shared/widgets/SideMenuWidget.jsm
+++ b/browser/devtools/shared/widgets/SideMenuWidget.jsm
@@ -28,25 +28,29 @@ this.EXPORTED_SYMBOLS = ["SideMenuWidget
  * }
  * ViewHelpers.create({ constructor: MyView, proto: MenuContainer.prototype }, {
  *   myMethod: function() {},
  *   ...
  * });
  *
  * @param nsIDOMNode aNode
  *        The element associated with the widget.
+ * @param boolean aShowArrows
+ *        Specifies if items in this container should display horizontal arrows.
  */
-this.SideMenuWidget = function SideMenuWidget(aNode) {
+this.SideMenuWidget = function SideMenuWidget(aNode, aShowArrows = true) {
   this._parent = aNode;
+  this._showArrows = aShowArrows;
 
   // Create an internal scrollbox container.
   this._list = this.document.createElement("scrollbox");
   this._list.className = "side-menu-widget-container";
   this._list.setAttribute("flex", "1");
   this._list.setAttribute("orient", "vertical");
+  this._list.setAttribute("with-arrow", aShowArrows);
   this._parent.appendChild(this._list);
   this._boxObject = this._list.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
 
   // Menu items can optionally be grouped.
   this._groupsByName = new Map(); // Can't use a WeakMap because keys are strings.
   this._orderedGroupElementsArray = [];
   this._orderedMenuElementsArray = [];
 
@@ -78,17 +82,17 @@ SideMenuWidget.prototype = {
    *        The group to place the displayed item into.
    * @return nsIDOMNode
    *         The element associated with the displayed item.
    */
   insertItemAt: function SMW_insertItemAt(aIndex, aContents, aTooltip = "", aGroup = "") {
     this.ensureSelectionIsVisible(true, true); // Don't worry, it's delayed.
 
     let group = this._getGroupForName(aGroup);
-    return group.insertItemAt(aIndex, aContents, aTooltip);
+    return group.insertItemAt(aIndex, aContents, aTooltip, this._showArrows);
   },
 
   /**
    * Returns the child node in this container situated at the specified index.
    *
    * @param number aIndex
    *        The position in the container intended for this item.
    * @return nsIDOMNode
@@ -145,19 +149,21 @@ SideMenuWidget.prototype = {
   set selectedItem(aChild) {
     let menuElementsArray = this._orderedMenuElementsArray;
 
     if (!aChild) {
       this._selectedItem = null;
     }
     for (let node of menuElementsArray) {
       if (node == aChild) {
+        node.classList.add("selected");
         node.parentNode.classList.add("selected");
         this._selectedItem = node;
       } else {
+        node.classList.remove("selected");
         node.parentNode.classList.remove("selected");
       }
     }
     // Repeated calls to ensureElementIsVisible would interfere with each other
     // and may sometimes result in incorrect scroll positions.
     this.ensureSelectionIsVisible(false, true);
   },
 
@@ -392,23 +398,25 @@ SideMenuGroup.prototype = {
    * Inserts an item in this group at the specified index.
    *
    * @param number aIndex
    *        The position in the container intended for this item.
    * @param string | nsIDOMNode aContents
    *        The string or node displayed in the container.
    * @param string aTooltip [optional]
    *        A tooltip attribute for the displayed item.
+   * @param boolean aArrowFlag
+   *        True if a horizontal arrow should be shown.
    * @return nsIDOMNode
    *         The element associated with the displayed item.
    */
-  insertItemAt: function SMG_insertItemAt(aIndex, aContents, aTooltip) {
+  insertItemAt: function SMG_insertItemAt(aIndex, aContents, aTooltip, aArrowFlag) {
     let list = this._list;
     let menuArray = this._menuElementsArray;
-    let item = new SideMenuItem(this, aContents, aTooltip);
+    let item = new SideMenuItem(this, aContents, aTooltip, aArrowFlag);
 
     // Invalidate any notices set on the owner widget.
     this.ownerView.removeAttribute("notice");
 
     if (aIndex >= 0) {
       list.insertBefore(item._container, list.childNodes[aIndex]);
       menuArray.splice(aIndex, 0, item._target);
     } else {
@@ -470,34 +478,49 @@ SideMenuGroup.prototype = {
  * A SideMenuItem constructor for the BreadcrumbsWidget.
  *
  * @param SideMenuGroup aGroup
  *        The group to contain this menu item.
  * @param string aTooltip [optional]
  *        A tooltip attribute for the displayed item.
  * @param string | nsIDOMNode aContents
  *        The string or node displayed in the container.
+ * @param boolean aArrowFlag
+ *        True if a horizontal arrow should be shown.
  */
-function SideMenuItem(aGroup, aContents, aTooltip = "") {
+function SideMenuItem(aGroup, aContents, aTooltip, aArrowFlag) {
   this.ownerView = aGroup;
 
   let document = this.document;
-  let target = this._target = document.createElement("vbox");
-  target.className = "side-menu-widget-item-contents";
-  target.setAttribute("flex", "1");
-  this.contents = aContents;
+
+  // Show a horizontal arrow towards the content.
+  if (aArrowFlag) {
+    let target = this._target = document.createElement("vbox");
+    target.className = "side-menu-widget-item-contents";
+
+    let arrow = this._arrow = document.createElement("hbox");
+    arrow.className = "side-menu-widget-item-arrow";
 
-  let arrow = this._arrow = document.createElement("hbox");
-  arrow.className = "side-menu-widget-item-arrow";
+    let container = this._container = document.createElement("hbox");
+    container.className = "side-menu-widget-item side-menu-widget-item-or-group";
+    container.setAttribute("tooltiptext", aTooltip);
+    container.appendChild(target);
+    container.appendChild(arrow);
+  }
+  // Skip a few redundant nodes when no horizontal arrow is shown.
+  else {
+    let target = this._target = this._container = document.createElement("hbox");
+    target.className =
+      "side-menu-widget-item " +
+      "side-menu-widget-item-or-group " +
+      "side-menu-widget-item-contents";
+  }
 
-  let container = this._container = document.createElement("hbox");
-  container.className = "side-menu-widget-item side-menu-widget-item-or-group";
-  container.setAttribute("tooltiptext", aTooltip);
-  container.appendChild(target);
-  container.appendChild(arrow);
+  this._target.setAttribute("flex", "1");
+  this.contents = aContents;
 }
 
 SideMenuItem.prototype = {
   get document() this.ownerView.document,
   get window() this.document.defaultView,
 
   /**
    * Sets the contents displayed in this item's view.
--- a/browser/themes/linux/devtools/netmonitor.css
+++ b/browser/themes/linux/devtools/netmonitor.css
@@ -202,21 +202,16 @@
 
 .requests-menu-timings-box.receive,
 .requests-menu-timings-cap.receive {
   background-color: rgba(255,255,255,1.0);
   box-shadow: 0 0 8px 0 rgba(128,255,255,1.0),
               0 0 4px 0 rgba(255,255,255,1.0) inset;
 }
 
-.side-menu-widget-container,
-.side-menu-widget-item-or-group {
-  box-shadow: none !important;
-}
-
 .side-menu-widget-item:nth-child(even) {
   background: rgba(255,255,255,0.05);
 }
 
 /* Network request details */
 
 #details-pane {
   background: hsl(208,11%,27%);
--- a/browser/themes/linux/devtools/widgets.css
+++ b/browser/themes/linux/devtools/widgets.css
@@ -269,23 +269,23 @@
 
 /* SideMenuWidget */
 
 .side-menu-widget-container {
   background: url(background-noise-toolbar.png), hsl(208,11%,27%);
   color: #fff;
 }
 
-.side-menu-widget-container:-moz-locale-dir(ltr),
-.side-menu-widget-item-or-group:-moz-locale-dir(ltr) {
+.side-menu-widget-container[with-arrow=true]:-moz-locale-dir(ltr),
+.side-menu-widget-item-or-group[with-arrow=true]:-moz-locale-dir(ltr) {
   box-shadow: inset -1px 0 0 #222426;
 }
 
-.side-menu-widget-container:-moz-locale-dir(rtl),
-.side-menu-widget-item-or-group:-moz-locale-dir(rtl) {
+.side-menu-widget-container[with-arrow=true]:-moz-locale-dir(rtl),
+.side-menu-widget-item-or-group[with-arrow=true]:-moz-locale-dir(rtl) {
   box-shadow: inset 1px 0 0 #222426;
 }
 
 .side-menu-widget-group-title {
   background-image: linear-gradient(#1f3e4f, #1b3243);
   box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
               0 -2px 0 hsla(206,37%,4%,.05) inset,
               0 -1px 1px hsla(206,37%,4%,.1) inset;
@@ -310,41 +310,38 @@
 .side-menu-widget-item:last-of-type {
   box-shadow: 0 1px 0 hsla(210,16%,76%,.1);
 }
 
 .side-menu-widget-item.selected {
   background: linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%)) repeat-x top left !important;
   box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
               inset 0 -1px 0 hsla(210,40%,83%,.05);
-  border-top: 0;
-  padding-top: 1px;
-}
-
-.side-menu-widget-item-arrow {
-  -moz-margin-start: -8px;
-  width: 8px;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow {
-  margin-top: -1px; /* Selection removes the top border, offset by 1 pixel */
   background-size: auto, 1px 100%;
   background-repeat: no-repeat;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
   background-image: url(itemArrow-ltr.png), linear-gradient(to right, black, black);
   background-position: center right, top right;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
   background-image: url(itemArrow-rtl.png), linear-gradient(to right, black, black);
   background-position: center left, top left;
 }
 
+.side-menu-widget-item-arrow {
+  -moz-margin-start: -8px;
+  width: 8px;
+}
+
 .side-menu-widget-item-contents {
   padding: 4px;
 }
 
 .side-menu-widget-item label {
   cursor: inherit;
 }
 
--- a/browser/themes/osx/devtools/netmonitor.css
+++ b/browser/themes/osx/devtools/netmonitor.css
@@ -202,21 +202,16 @@
 
 .requests-menu-timings-box.receive,
 .requests-menu-timings-cap.receive {
   background-color: rgba(255,255,255,1.0);
   box-shadow: 0 0 8px 0 rgba(128,255,255,1.0),
               0 0 4px 0 rgba(255,255,255,1.0) inset;
 }
 
-.side-menu-widget-container,
-.side-menu-widget-item-or-group {
-  box-shadow: none !important;
-}
-
 .side-menu-widget-item:nth-child(even) {
   background: rgba(255,255,255,0.05);
 }
 
 /* Network request details */
 
 #details-pane {
   background: hsl(208,11%,27%);
--- a/browser/themes/osx/devtools/widgets.css
+++ b/browser/themes/osx/devtools/widgets.css
@@ -269,23 +269,23 @@
 
 /* SideMenuWidget */
 
 .side-menu-widget-container {
   background: url(background-noise-toolbar.png), hsl(208,11%,27%);
   color: #fff;
 }
 
-.side-menu-widget-container:-moz-locale-dir(ltr),
-.side-menu-widget-item-or-group:-moz-locale-dir(ltr) {
+.side-menu-widget-container[with-arrow=true]:-moz-locale-dir(ltr),
+.side-menu-widget-item-or-group[with-arrow=true]:-moz-locale-dir(ltr) {
   box-shadow: inset -1px 0 0 #222426;
 }
 
-.side-menu-widget-container:-moz-locale-dir(rtl),
-.side-menu-widget-item-or-group:-moz-locale-dir(rtl) {
+.side-menu-widget-container[with-arrow=true]:-moz-locale-dir(rtl),
+.side-menu-widget-item-or-group[with-arrow=true]:-moz-locale-dir(rtl) {
   box-shadow: inset 1px 0 0 #222426;
 }
 
 .side-menu-widget-group-title {
   background-image: linear-gradient(#1f3e4f, #1b3243);
   box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
               0 -2px 0 hsla(206,37%,4%,.05) inset,
               0 -1px 1px hsla(206,37%,4%,.1) inset;
@@ -310,41 +310,38 @@
 .side-menu-widget-item:last-of-type {
   box-shadow: 0 1px 0 hsla(210,16%,76%,.1);
 }
 
 .side-menu-widget-item.selected {
   background: linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%)) repeat-x top left !important;
   box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
               inset 0 -1px 0 hsla(210,40%,83%,.05);
-  border-top: 0;
-  padding-top: 1px;
-}
-
-.side-menu-widget-item-arrow {
-  -moz-margin-start: -8px;
-  width: 8px;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow {
-  margin-top: -1px; /* Selection removes the top border, offset by 1 pixel */
   background-size: auto, 1px 100%;
   background-repeat: no-repeat;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
   background-image: url(itemArrow-ltr.png), linear-gradient(to right, black, black);
   background-position: center right, top right;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
   background-image: url(itemArrow-rtl.png), linear-gradient(to right, black, black);
   background-position: center left, top left;
 }
 
+.side-menu-widget-item-arrow {
+  -moz-margin-start: -8px;
+  width: 8px;
+}
+
 .side-menu-widget-item-contents {
   padding: 4px;
 }
 
 .side-menu-widget-item label {
   cursor: inherit;
 }
 
--- a/browser/themes/windows/devtools/netmonitor.css
+++ b/browser/themes/windows/devtools/netmonitor.css
@@ -202,21 +202,16 @@
 
 .requests-menu-timings-box.receive,
 .requests-menu-timings-cap.receive {
   background-color: rgba(255,255,255,1.0);
   box-shadow: 0 0 8px 0 rgba(128,255,255,1.0),
               0 0 4px 0 rgba(255,255,255,1.0) inset;
 }
 
-.side-menu-widget-container,
-.side-menu-widget-item-or-group {
-  box-shadow: none !important;
-}
-
 .side-menu-widget-item:nth-child(even) {
   background: rgba(255,255,255,0.05);
 }
 
 /* Network request details */
 
 #details-pane {
   background: hsl(208,11%,27%);
--- a/browser/themes/windows/devtools/widgets.css
+++ b/browser/themes/windows/devtools/widgets.css
@@ -273,23 +273,23 @@
 
 /* SideMenuWidget */
 
 .side-menu-widget-container {
   background: url(background-noise-toolbar.png), hsl(208,11%,27%);
   color: #fff;
 }
 
-.side-menu-widget-container:-moz-locale-dir(ltr),
-.side-menu-widget-item-or-group:-moz-locale-dir(ltr) {
+.side-menu-widget-container[with-arrow=true]:-moz-locale-dir(ltr),
+.side-menu-widget-item-or-group[with-arrow=true]:-moz-locale-dir(ltr) {
   box-shadow: inset -1px 0 0 #222426;
 }
 
-.side-menu-widget-container:-moz-locale-dir(rtl),
-.side-menu-widget-item-or-group:-moz-locale-dir(rtl) {
+.side-menu-widget-container[with-arrow=true]:-moz-locale-dir(rtl),
+.side-menu-widget-item-or-group[with-arrow=true]:-moz-locale-dir(rtl) {
   box-shadow: inset 1px 0 0 #222426;
 }
 
 .side-menu-widget-group-title {
   background-image: linear-gradient(#1f3e4f, #1b3243);
   box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
               0 -2px 0 hsla(206,37%,4%,.05) inset,
               0 -1px 1px hsla(206,37%,4%,.1) inset;
@@ -314,41 +314,38 @@
 .side-menu-widget-item:last-of-type {
   box-shadow: 0 1px 0 hsla(210,16%,76%,.1);
 }
 
 .side-menu-widget-item.selected {
   background: linear-gradient(hsl(206,61%,40%), hsl(206,61%,31%)) repeat-x top left !important;
   box-shadow: inset 0 1px 0 hsla(210,40%,83%,.15),
               inset 0 -1px 0 hsla(210,40%,83%,.05);
-  border-top: 0;
-  padding-top: 1px;
-}
-
-.side-menu-widget-item-arrow {
-  -moz-margin-start: -8px;
-  width: 8px;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow {
-  margin-top: -1px; /* Selection removes the top border, offset by 1 pixel */
   background-size: auto, 1px 100%;
   background-repeat: no-repeat;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
   background-image: url(itemArrow-ltr.png), linear-gradient(to right, black, black);
   background-position: center right, top right;
 }
 
 .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
   background-image: url(itemArrow-rtl.png), linear-gradient(to right, black, black);
   background-position: center left, top left;
 }
 
+.side-menu-widget-item-arrow {
+  -moz-margin-start: -8px;
+  width: 8px;
+}
+
 .side-menu-widget-item-contents {
   padding: 4px;
 }
 
 .side-menu-widget-item label {
   cursor: inherit;
 }