Backed out Bug 770818 (highlighter v3) for test failures.
authorDave Camp <dcamp@mozilla.com>
Sat, 25 Aug 2012 11:04:28 -0700
changeset 105440 aeb96f8edcb804722bcca98fd9b46d7cdb33f58f
parent 105439 d8accb9118ce3328d71dec425b24a8249b4e46af
child 105441 328402a45248dbcfebbcd2a5e96ce3e8a755234c
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
bugs770818
milestone17.0a1
Backed out Bug 770818 (highlighter v3) for test failures.
browser/app/profile/firefox.js
browser/base/content/browser.xul
browser/base/content/highlighter.css
browser/devtools/highlighter/highlighter.jsm
browser/devtools/highlighter/inspector.jsm
browser/devtools/highlighter/test/Makefile.in
browser/devtools/highlighter/test/browser_inspector_highlighter.js
browser/devtools/highlighter/test/browser_inspector_highlighter_autohide.js
browser/devtools/highlighter/test/browser_inspector_invalidate.js
browser/devtools/highlighter/test/head.js
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/gnomestripe/browser.css
browser/themes/gnomestripe/devtools/inspector-option-icon.png
browser/themes/gnomestripe/jar.mn
browser/themes/pinstripe/browser.css
browser/themes/pinstripe/devtools/inspector-option-icon.png
browser/themes/pinstripe/jar.mn
browser/themes/winstripe/browser.css
browser/themes/winstripe/devtools/inspector-option-icon.png
browser/themes/winstripe/jar.mn
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1002,16 +1002,18 @@ pref("devtools.gcli.allowSet", false);
 pref("devtools.commands.dir", "");
 
 // Enable the Inspector
 pref("devtools.inspector.enabled", true);
 pref("devtools.inspector.htmlHeight", 112);
 pref("devtools.inspector.htmlPanelOpen", false);
 pref("devtools.inspector.sidebarOpen", false);
 pref("devtools.inspector.activeSidebar", "ruleview");
+pref("devtools.inspector.highlighterShowVeil", true);
+pref("devtools.inspector.highlighterShowInfobar", true);
 
 // Enable the Layout View
 pref("devtools.layoutview.enabled", true);
 pref("devtools.layoutview.open", false);
 
 // Enable the Responsive UI tool
 pref("devtools.responsiveUI.enabled", true);
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1101,16 +1101,34 @@
              nowindowdrag="true"
              hidden="true">
 #ifdef XP_MACOSX
       <toolbarbutton id="highlighter-closebutton"
                      class="devtools-closebutton"
                      oncommand="InspectorUI.closeInspectorUI(false);"
                      tooltiptext="&inspectCloseButton.tooltiptext;"/>
 #endif
+      <toolbarbutton id="inspector-option-toolbarbutton"
+                     type="menu"
+                     tabindex="0"
+                     tooltiptext="&inspectOptionButton.tooltiptext;">
+        <menupopup id="inspector-option-popup"
+                   position="before_start">
+          <menuitem id="inspectorToggleVeil"
+                    type="checkbox"
+                    label="&inspectorToggleVeil.label;"
+                    accesskey="&inspectorToggleVeil.accesskey;"
+                    command="Inspector:ToggleVeil"/>
+          <menuitem id="inspectorToggleInfobar"
+                    type="checkbox"
+                    label="&inspectorToggleInfobar.label;"
+                    accesskey="&inspectorToggleInfobar.accesskey;"
+                    command="Inspector:ToggleInfobar"/>
+        </menupopup>
+      </toolbarbutton>
       <toolbarbutton id="inspector-inspect-toolbutton"
                      class="devtools-toolbarbutton"
                      command="Inspector:Inspect"/>
       <toolbarbutton id="inspector-treepanel-toolbutton"
                      class="devtools-toolbarbutton"
                      tabindex="0"
                      aria-label="&markupButton.arialabel;"
                      accesskey="&markupButton.accesskey;"
--- a/browser/base/content/highlighter.css
+++ b/browser/base/content/highlighter.css
@@ -7,59 +7,58 @@
 }
 
 #highlighter-controls {
   position: absolute;
   top: 0;
   left: 0;
 }
 
-#highlighter-outline-container {
+#highlighter-veil-container {
   overflow: hidden;
-  position: relative;
 }
 
-#highlighter-outline {
-  position: absolute;
+#highlighter-veil-container:not([dim]) > .highlighter-veil,
+#highlighter-veil-container:not([dim]) > hbox > .highlighter-veil {
+  visibility: hidden;
 }
 
-#highlighter-outline[hidden] {
-  opacity: 0;
-  pointer-events: none;
-  display: -moz-box;
+#highlighter-veil-container:not([disable-transitions]) > .highlighter-veil,
+#highlighter-veil-container:not([disable-transitions]) > #highlighter-veil-middlebox,
+#highlighter-veil-container:not([disable-transitions]) > #highlighter-veil-middlebox > .highlighter-veil,
+#highlighter-veil-container:not([disable-transitions]) > #highlighter-veil-middlebox > #highlighter-veil-transparentbox {
+  transition-property: width, height;
+  transition-duration: 0.1s;
+  transition-timing-function: linear;
 }
 
-#highlighter-outline:not([disable-transitions]) {
-  transition-property: opacity, top, left, width, height;
-  transition-duration: 0.1s;
-  transition-timing-function: linear;
+#highlighter-veil-bottombox,
+#highlighter-veil-rightbox {
+  -moz-box-flex: 1;
+}
+
+#highlighter-veil-middlebox:-moz-locale-dir(rtl) {
+  -moz-box-direction: reverse;
 }
 
 .inspector-breadcrumbs-button {
   direction: ltr;
 }
 
 /*
  * Node Infobar
  */
 
 #highlighter-nodeinfobar-container {
   position: absolute;
   max-width: 95%;
 }
 
-#highlighter-nodeinfobar-container[hidden] {
-  opacity: 0;
-  pointer-events: none;
-  display: -moz-box;
-}
-
-#highlighter-nodeinfobar-container:not([disable-transitions]),
-#highlighter-nodeinfobar-container[disable-transitions][force-transitions] {
-  transition-property: transform, opacity, top, left;
+#highlighter-nodeinfobar-container:not([disable-transitions]) {
+  transition-property: top, left;
   transition-duration: 0.1s;
   transition-timing-function: linear;
 }
 
 #highlighter-nodeinfobar-text {
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
--- a/browser/devtools/highlighter/highlighter.jsm
+++ b/browser/devtools/highlighter/highlighter.jsm
@@ -61,54 +61,44 @@ const PSEUDO_CLASSES = [":hover", ":acti
  *   boolean isHidden();
  *
  *   // Redraw the highlighter if the visible portion of the node has changed.
  *   void invalidateSize(aScroll);
  *
  *   // Is a node highlightable.
  *   boolean isNodeHighlightable(aNode);
  *
- *   // Show/hide the outline and the infobar
+ *   // Show/hide the veil and the infobar
  *   void showInfobar();
  *   void hideInfobar();
- *   void showOutline();
- *   void hideOutline();
+ *   void showVeil();
+ *   void hideVeil();
  *
  *   // Add/Remove listeners
  *   // @param aEvent - event name
  *   // @param aListener - function callback
  *   void addListener(aEvent, aListener);
  *   void removeListener(aEvent, aListener);
  *
  * Events:
  *
  *   "closed" - Highlighter is closing
  *   "nodeselected" - A new node has been selected
  *   "highlighting" - Highlighter is highlighting
  *   "locked" - The selected node has been locked
  *   "unlocked" - The selected ndoe has been unlocked
  *   "pseudoclasstoggled" - A pseudo-class lock has changed on the selected node
+
  *
  * Structure:
- *  <stack id="highlighter-container">
- *    <box id="highlighter-outline-container">
- *      <box id="highlighter-outline" locked="true/false"/>
- *    </box>
- *    <box id="highlighter-controls">
- *      <box id="highlighter-nodeinfobar-container" position="top/bottom" locked="true/false">
- *        <box class="highlighter-nodeinfobar-arrow" id="highlighter-nodeinfobar-arrow-top"/>
- *        <hbox id="highlighter-nodeinfobar">
- *          <toolbarbutton id="highlighter-nodeinfobar-inspectbutton" class="highlighter-nodeinfobar-button"/>
- *          <hbox id="highlighter-nodeinfobar-text">tagname#id.class1.class2</hbox>
- *          <toolbarbutton id="highlighter-nodeinfobar-menu" class="highlighter-nodeinfobar-button">…</toolbarbutton>
- *        </hbox>
- *        <box class="highlighter-nodeinfobar-arrow" id="highlighter-nodeinfobar-arrow-bottom"/>
- *      </box>
- *    </box>
- *  </stack>
+ *
+ *   <stack id="highlighter-container">
+ *     <vbox id="highlighter-veil-container">...</vbox>
+ *     <box id="highlighter-controls>...</vbox>
+ *   </stack>
  *
  */
 
 
 /**
  * Constructor.
  *
  * @param object aWindow
@@ -129,75 +119,76 @@ Highlighter.prototype = {
   {
     let stack = this.browser.parentNode;
     this.win = this.browser.contentWindow;
     this._highlighting = false;
 
     this.highlighterContainer = this.chromeDoc.createElement("stack");
     this.highlighterContainer.id = "highlighter-container";
 
-    this.outline = this.chromeDoc.createElement("box");
-    this.outline.id = "highlighter-outline";
-
-    let outlineContainer = this.chromeDoc.createElement("box");
-    outlineContainer.appendChild(this.outline);
-    outlineContainer.id = "highlighter-outline-container";
+    this.veilContainer = this.chromeDoc.createElement("vbox");
+    this.veilContainer.id = "highlighter-veil-container";
 
     // The controlsBox will host the different interactive
     // elements of the highlighter (buttons, toolbars, ...).
     let controlsBox = this.chromeDoc.createElement("box");
     controlsBox.id = "highlighter-controls";
-    this.highlighterContainer.appendChild(outlineContainer);
+    this.highlighterContainer.appendChild(this.veilContainer);
     this.highlighterContainer.appendChild(controlsBox);
 
     stack.appendChild(this.highlighterContainer);
 
-    this.showOutline();
+    // The veil will make the whole page darker except
+    // for the region of the selected box.
+    this.buildVeil(this.veilContainer);
+    this.showVeil();
 
     this.buildInfobar(controlsBox);
 
     this.transitionDisabler = null;
-    this.pageEventsMuter = null;
 
     this.computeZoomFactor();
     this.unlock();
     this.hide();
   },
 
   /**
    * Destroy the nodes. Remove listeners.
    */
   destroy: function Highlighter_destroy()
   {
     this.detachMouseListeners();
     this.detachPageListeners();
 
     this.chromeWin.clearTimeout(this.transitionDisabler);
-    this.chromeWin.clearTimeout(this.pageEventsMuter);
     this.boundCloseEventHandler = null;
     this._contentRect = null;
     this._highlightRect = null;
     this._highlighting = false;
-    this.outline = null;
+    this.veilTopBox = null;
+    this.veilLeftBox = null;
+    this.veilMiddleBox = null;
+    this.veilTransparentBox = null;
+    this.veilContainer = null;
     this.node = null;
     this.nodeInfo = null;
     this.highlighterContainer.parentNode.removeChild(this.highlighterContainer);
     this.highlighterContainer = null;
     this.win = null
     this.browser = null;
     this.chromeDoc = null;
     this.chromeWin = null;
     this.tabbrowser = null;
 
     this.emitEvent("closed");
     this.removeAllListeners();
   },
 
   /**
-   * Show the outline, and select a node.
+   * Show the veil, and select a node.
    * If no node is specified, the previous selected node is highlighted if any.
    * If no node was selected, the root element is selected.
    *
    * @param aNode [optional] - The node to be selected.
    * @param aScroll [optional] boolean
    *        Should we scroll to ensure that the selected node is visible.
    */
   highlight: function Highlighter_highlight(aNode, aScroll)
@@ -272,31 +263,30 @@ Highlighter.prototype = {
     return this.node;
   },
 
   /**
    * Show the highlighter if it has been hidden.
    */
   show: function() {
     if (!this.hidden) return;
-    this.showOutline();
-    this.showInfobar();
-    this.computeZoomFactor();
+    this.veilContainer.removeAttribute("hidden");
+    this.nodeInfo.container.removeAttribute("hidden");
     this.attachPageListeners();
     this.invalidateSize();
     this.hidden = false;
   },
 
   /**
-   * Hide the highlighter, the outline and the infobar.
+   * Hide the highlighter, the veil and the infobar.
    */
   hide: function() {
     if (this.hidden) return;
-    this.hideOutline();
-    this.hideInfobar();
+    this.veilContainer.setAttribute("hidden", "true");
+    this.nodeInfo.container.setAttribute("hidden", "true");
     this.detachPageListeners();
     this.hidden = true;
   },
 
   /**
    * Is the highlighter visible?
    *
    * @return boolean
@@ -305,34 +295,33 @@ Highlighter.prototype = {
     return this.hidden;
   },
 
   /**
    * Lock a node. Stops the inspection.
    */
   lock: function() {
     if (this.locked === true) return;
-    this.outline.setAttribute("locked", "true");
+    this.veilContainer.setAttribute("locked", "true");
     this.nodeInfo.container.setAttribute("locked", "true");
     this.detachMouseListeners();
     this.locked = true;
     this.emitEvent("locked");
   },
 
   /**
    * Start inspecting.
    * Unlock the current node (if any), and select any node being hovered.
    */
   unlock: function() {
     if (this.locked === false) return;
-    this.outline.removeAttribute("locked");
+    this.veilContainer.removeAttribute("locked");
     this.nodeInfo.container.removeAttribute("locked");
     this.attachMouseListeners();
     this.locked = false;
-    this.showOutline();
     this.emitEvent("unlocked");
   },
 
   /**
    * Is the specified node highlightable?
    *
    * @param nsIDOMNode aNode
    *        the DOM element in question
@@ -347,46 +336,98 @@ Highlighter.prototype = {
     if (aNode.nodeType != aNode.ELEMENT_NODE) {
       return false;
     }
     let nodeName = aNode.nodeName.toLowerCase();
     return !INSPECTOR_INVISIBLE_ELEMENTS[nodeName];
   },
 
   /**
-   * Hide the infobar
+   * Hide the veil
    */
-   hideInfobar: function Highlighter_hideInfobar() {
-     this.nodeInfo.container.setAttribute("force-transitions", "true");
-     this.nodeInfo.container.setAttribute("hidden", "true");
+   hideVeil: function Highlighter_hideVeil() {
+     this.veilContainer.removeAttribute("dim");
    },
 
   /**
-   * Show the infobar
+   * Show the veil
    */
-   showInfobar: function Highlighter_showInfobar() {
-     this.nodeInfo.container.removeAttribute("hidden");
-     this.moveInfobar();
-     this.nodeInfo.container.removeAttribute("force-transitions");
+   showVeil: function Highlighter_showVeil() {
+     this.veilContainer.setAttribute("dim", "true");
    },
 
+   /**
+    * Hide the infobar
+    */
+    hideInfobar: function Highlighter_hideInfobar() {
+      this.nodeInfo.container.setAttribute("hidden", "true");
+    },
+
+   /**
+    * Show the infobar
+    */
+    showInfobar: function Highlighter_showInfobar() {
+      this.nodeInfo.container.removeAttribute("hidden");
+      this.moveInfobar();
+    },
+
   /**
-   * Hide the outline
+   * Build the veil:
+   *
+   * <vbox id="highlighter-veil-container">
+   *   <box id="highlighter-veil-topbox" class="highlighter-veil"/>
+   *   <hbox id="highlighter-veil-middlebox">
+   *     <box id="highlighter-veil-leftbox" class="highlighter-veil"/>
+   *     <box id="highlighter-veil-transparentbox"/>
+   *     <box id="highlighter-veil-rightbox" class="highlighter-veil"/>
+   *   </hbox>
+   *   <box id="highlighter-veil-bottombox" class="highlighter-veil"/>
+   * </vbox>
+   *
+   * @param nsIDOMElement aParent
+   *        The container of the veil boxes.
    */
-   hideOutline: function Highlighter_hideOutline() {
-     this.outline.setAttribute("hidden", "true");
-   },
+  buildVeil: function Highlighter_buildVeil(aParent)
+  {
+    // We will need to resize these boxes to surround a node.
+    // See highlightRectangle().
+
+    this.veilTopBox = this.chromeDoc.createElement("box");
+    this.veilTopBox.id = "highlighter-veil-topbox";
+    this.veilTopBox.className = "highlighter-veil";
+
+    this.veilMiddleBox = this.chromeDoc.createElement("hbox");
+    this.veilMiddleBox.id = "highlighter-veil-middlebox";
 
-  /**
-   * Show the outline
-   */
-   showOutline: function Highlighter_showOutline() {
-     if (this._highlighting)
-       this.outline.removeAttribute("hidden");
-   },
+    this.veilLeftBox = this.chromeDoc.createElement("box");
+    this.veilLeftBox.id = "highlighter-veil-leftbox";
+    this.veilLeftBox.className = "highlighter-veil";
+
+    this.veilTransparentBox = this.chromeDoc.createElement("box");
+    this.veilTransparentBox.id = "highlighter-veil-transparentbox";
+
+    // We don't need any references to veilRightBox and veilBottomBox.
+    // These boxes are automatically resized (flex=1)
+
+    let veilRightBox = this.chromeDoc.createElement("box");
+    veilRightBox.id = "highlighter-veil-rightbox";
+    veilRightBox.className = "highlighter-veil";
+
+    let veilBottomBox = this.chromeDoc.createElement("box");
+    veilBottomBox.id = "highlighter-veil-bottombox";
+    veilBottomBox.className = "highlighter-veil";
+
+    this.veilMiddleBox.appendChild(this.veilLeftBox);
+    this.veilMiddleBox.appendChild(this.veilTransparentBox);
+    this.veilMiddleBox.appendChild(veilRightBox);
+
+    aParent.appendChild(this.veilTopBox);
+    aParent.appendChild(this.veilMiddleBox);
+    aParent.appendChild(veilBottomBox);
+  },
 
   /**
    * Build the node Infobar.
    *
    * <box id="highlighter-nodeinfobar-container">
    *   <box id="Highlighter-nodeinfobar-arrow-top"/>
    *   <hbox id="highlighter-nodeinfobar">
    *     <toolbarbutton class="highlighter-nodeinfobar-button" id="highlighter-nodeinfobar-inspectbutton"/>
@@ -558,25 +599,24 @@ Highlighter.prototype = {
       return; // same rectangle
     }
 
     let aRectScaled = LayoutHelpers.getZoomedRect(this.win, aRect);
 
     if (aRectScaled.left >= 0 && aRectScaled.top >= 0 &&
         aRectScaled.width > 0 && aRectScaled.height > 0) {
 
-      this.showOutline();
+      this.veilTransparentBox.style.visibility = "visible";
 
       // The bottom div and the right div are flexibles (flex=1).
       // We don't need to resize them.
-      let top = "top:" + aRectScaled.top + "px;";
-      let left = "left:" + aRectScaled.left + "px;";
-      let width = "width:" + aRectScaled.width + "px;";
-      let height = "height:" + aRectScaled.height + "px;";
-      this.outline.setAttribute("style", top + left + width + height);
+      this.veilTopBox.style.height = aRectScaled.top + "px";
+      this.veilLeftBox.style.width = aRectScaled.left + "px";
+      this.veilMiddleBox.style.height = aRectScaled.height + "px";
+      this.veilTransparentBox.style.width = aRectScaled.width + "px";
 
       this._highlighting = true;
     } else {
       this.unhighlight();
     }
 
     this._contentRect = aRect; // save orig (non-scaled) rect
     this._highlightRect = aRectScaled; // and save the scaled rect.
@@ -585,17 +625,19 @@ Highlighter.prototype = {
   },
 
   /**
    * Clear the highlighter surface.
    */
   unhighlight: function Highlighter_unhighlight()
   {
     this._highlighting = false;
-    this.hideOutline();
+    this.veilMiddleBox.style.height = 0;
+    this.veilTransparentBox.style.width = 0;
+    this.veilTransparentBox.style.visibility = "hidden";
   },
 
   /**
    * Update node information (tagName#id.class)
    */
   updateInfobar: function Highlighter_updateInfobar()
   {
     // Tag name
@@ -779,17 +821,16 @@ Highlighter.prototype = {
    */
   handleEvent: function Highlighter_handleEvent(aEvent)
   {
     switch (aEvent.type) {
       case "click":
         this.handleClick(aEvent);
         break;
       case "mousemove":
-        this.brieflyIgnorePageEvents();
         this.handleMouseMove(aEvent);
         break;
       case "resize":
         this.computeZoomFactor();
         break;
       case "MozAfterPaint":
       case "scroll":
         this.brieflyDisableTransitions();
@@ -805,56 +846,28 @@ Highlighter.prototype = {
   },
 
   /**
    * Disable the CSS transitions for a short time to avoid laggy animations
    * during scrolling or resizing.
    */
   brieflyDisableTransitions: function Highlighter_brieflyDisableTransitions()
   {
-    if (this.transitionDisabler) {
-      this.chromeWin.clearTimeout(this.transitionDisabler);
-    } else {
-      this.outline.setAttribute("disable-transitions", "true");
-      this.nodeInfo.container.setAttribute("disable-transitions", "true");
-    }
-    this.transitionDisabler =
-      this.chromeWin.setTimeout(function() {
-        this.outline.removeAttribute("disable-transitions");
-        this.nodeInfo.container.removeAttribute("disable-transitions");
-        this.transitionDisabler = null;
-      }.bind(this), 500);
-  },
-
-  /**
-   * Don't listen to page events while inspecting with the mouse.
-   */
-  brieflyIgnorePageEvents: function Highlighter_brieflyIgnorePageEvents()
-  {
-    // The goal is to keep smooth animations while inspecting.
-    // CSS Transitions might be interrupted because of a MozAfterPaint
-    // event that would triger an invalidateSize() call.
-    // So we don't listen to events that would trigger an invalidateSize()
-    // call.
-    //
-    // Side effect, zoom levels are not updated during this short period.
-    // It's very unlikely this would happen, but just in case, we call
-    // computeZoomFactor() when reattaching the events.
-    if (this.pageEventsMuter) {
-      this.chromeWin.clearTimeout(this.pageEventsMuter);
-    } else {
-      this.detachPageListeners();
-    }
-    this.pageEventsMuter =
-      this.chromeWin.setTimeout(function() {
-        this.attachPageListeners();
-        // Just in case the zoom level changed while ignoring the paint events
-        this.computeZoomFactor();
-        this.pageEventsMuter = null;
-      }.bind(this), 500);
+   if (this.transitionDisabler) {
+     this.chromeWin.clearTimeout(this.transitionDisabler);
+   } else {
+     this.veilContainer.setAttribute("disable-transitions", "true");
+     this.nodeInfo.container.setAttribute("disable-transitions", "true");
+   }
+   this.transitionDisabler =
+     this.chromeWin.setTimeout(function() {
+       this.veilContainer.removeAttribute("disable-transitions");
+       this.nodeInfo.container.removeAttribute("disable-transitions");
+       this.transitionDisabler = null;
+     }.bind(this), 500);
   },
 
   /**
    * Handle clicks.
    *
    * @param nsIDOMEvent aEvent
    *        The DOM event.
    */
@@ -893,12 +906,13 @@ Highlighter.prototype = {
 };
 
 ///////////////////////////////////////////////////////////////////////////
 
 XPCOMUtils.defineLazyGetter(this, "DOMUtils", function () {
   return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils)
 });
 
-XPCOMUtils.defineLazyGetter(Highlighter.prototype, "strings", function () {
+XPCOMUtils.defineLazyGetter(Highlighter.prototype, "strings",
+  function () {
     return Services.strings.createBundle(
             "chrome://browser/locale/devtools/inspector.properties");
-});
+  });
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -596,16 +596,48 @@ InspectorUI.prototype = {
    * @returns boolean
    */
   get isInspectorOpen()
   {
     return !!(this.toolbar && !this.toolbar.hidden && this.highlighter);
   },
 
   /**
+   * Toggle highlighter veil.
+   */
+  toggleVeil: function IUI_toggleVeil()
+  {
+    if (this.currentInspector._highlighterShowVeil) {
+      this.highlighter.hideVeil();
+      this.currentInspector._highlighterShowVeil = false;
+      Services.prefs.setBoolPref("devtools.inspector.highlighterShowVeil", false);
+    } else {
+      this.highlighter.showVeil();
+      this.currentInspector._highlighterShowVeil = true;
+      Services.prefs.setBoolPref("devtools.inspector.highlighterShowVeil", true);
+    }
+  },
+
+  /**
+   * Toggle highlighter infobar.
+   */
+  toggleInfobar: function IUI_toggleInfobar()
+  {
+    if (this.currentInspector._highlighterShowInfobar) {
+      this.highlighter.hideInfobar();
+      this.currentInspector._highlighterShowInfobar = false;
+      Services.prefs.setBoolPref("devtools.inspector.highlighterShowInfobar", false);
+    } else {
+      this.highlighter.showInfobar();
+      this.currentInspector._highlighterShowInfobar = true;
+      Services.prefs.setBoolPref("devtools.inspector.highlighterShowInfobar", true);
+    }
+  },
+
+  /**
    * Return the default selection element for the inspected document.
    */
   get defaultSelection()
   {
     let doc = this.win.document;
     return doc.documentElement ? doc.documentElement.lastElementChild : null;
   },
 
@@ -675,21 +707,16 @@ InspectorUI.prototype = {
 
     this.initializeStore();
 
     this._sidebar = new InspectorStyleSidebar({
       document: this.chromeDoc,
       inspector: this._currentInspector,
     });
 
-    // Fade out the highlighter when needed
-    let deck = this.chromeDoc.getElementById("devtools-sidebar-deck");
-    deck.addEventListener("mouseenter", this, true);
-    deck.addEventListener("mouseleave", this, true);
-
     // Create UI for any sidebars registered with
     // InspectorUI.registerSidebar()
     for each (let tool in InspectorUI._registeredSidebars) {
       this._sidebar.addTool(tool);
     }
 
     this.setupNavigationKeys();
     this.highlighterReady();
@@ -738,16 +765,22 @@ InspectorUI.prototype = {
         Services.prefs.getBoolPref("devtools.inspector.htmlPanelOpen");
 
       inspector._sidebarOpen =
         Services.prefs.getBoolPref("devtools.inspector.sidebarOpen");
 
       inspector._activeSidebar =
         Services.prefs.getCharPref("devtools.inspector.activeSidebar");
 
+      inspector._highlighterShowVeil =
+        Services.prefs.getBoolPref("devtools.inspector.highlighterShowVeil");
+
+      inspector._highlighterShowInfobar =
+        Services.prefs.getBoolPref("devtools.inspector.highlighterShowInfobar");
+
       this.win.addEventListener("pagehide", this, true);
 
       this._currentInspector = inspector;
     }
   },
 
   /**
    * Browse nodes according to the breadcrumbs layout, only for some specific
@@ -818,22 +851,20 @@ InspectorUI.prototype = {
     this.stopInspecting();
 
     // close the sidebar
     if (this._sidebar) {
       this._sidebar.destroy();
       this._sidebar = null;
     }
 
-    let deck = this.chromeDoc.getElementById("devtools-sidebar-deck");
-    deck.removeEventListener("mouseenter", this, true);
-    deck.removeEventListener("mouseleave", this, true);
-
-    this.highlighter.destroy();
-    this.highlighter = null;
+    if (this.highlighter) {
+      this.highlighter.destroy();
+      this.highlighter = null;
+    }
 
     if (this.breadcrumbs) {
       this.breadcrumbs.destroy();
       this.breadcrumbs = null;
     }
 
     if (aKeepInspector) {
       this._currentInspector._freeze();
@@ -1024,16 +1055,33 @@ InspectorUI.prototype = {
     Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.STATE_RESTORED, null);
 
     this.highlighter.highlight();
 
     if (this.currentInspector._sidebarOpen) {
       this._sidebar.show();
     }
 
+    let menu = this.chromeDoc.getElementById("inspectorToggleVeil");
+    if (this.currentInspector._highlighterShowVeil) {
+      menu.setAttribute("checked", "true");
+    } else {
+      menu.removeAttribute("checked");
+      this.highlighter.hideVeil();
+    }
+
+    menu = this.chromeDoc.getElementById("inspectorToggleInfobar");
+    if (this.currentInspector._highlighterShowInfobar) {
+      menu.setAttribute("checked", "true");
+      this.highlighter.showInfobar();
+    } else {
+      menu.removeAttribute("checked");
+      this.highlighter.hideInfobar();
+    }
+
     Services.obs.notifyObservers({wrappedJSObject: this},
                                  INSPECTOR_NOTIFICATIONS.OPENED, null);
   },
 
   /**
    * Main callback handler for events.
    *
    * @param event
@@ -1093,22 +1141,16 @@ InspectorUI.prototype = {
           this.store.deleteInspector(winID);
         }
 
         if (this.store.isEmpty()) {
           this.tabbrowser.tabContainer.removeEventListener("TabSelect", this,
                                                          false);
         }
         break;
-      case "mouseleave":
-        this.highlighter.show();
-        break;
-      case "mouseenter":
-        this.highlighter.hide();
-        break;
     }
   },
 
   /*
    * handles "keypress" events.
   */
   onKeypress: function IUI_onKeypress(event)
   {
--- a/browser/devtools/highlighter/test/Makefile.in
+++ b/browser/devtools/highlighter/test/Makefile.in
@@ -10,17 +10,16 @@ relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
 		browser_inspector_initialization.js \
 		browser_inspector_treeSelection.js \
 		browser_inspector_highlighter.js \
-		browser_inspector_highlighter_autohide.js \
 		browser_inspector_iframeTest.js \
 		browser_inspector_scrolling.js \
 		browser_inspector_tab_switch.js \
 		browser_inspector_bug_665880.js \
 		browser_inspector_bug_674871.js \
 		browser_inspector_bug_566084_location_changed.js \
 		browser_inspector_infobar.js \
 		browser_inspector_bug_690361.js \
--- a/browser/devtools/highlighter/test/browser_inspector_highlighter.js
+++ b/browser/devtools/highlighter/test/browser_inspector_highlighter.js
@@ -63,17 +63,17 @@ function setupHighlighterTests()
 function runSelectionTests(subject)
 {
   Services.obs.removeObserver(runSelectionTests,
     InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
 
   is(subject.wrappedJSObject, InspectorUI,
      "InspectorUI accessible in the observer");
 
-  InspectorUI.highlighter.outline.setAttribute("disable-transitions", "true");
+  InspectorUI.highlighter.veilContainer.setAttribute("disable-transitions", "true");
 
   executeSoon(function() {
     InspectorUI.highlighter.addListener("nodeselected", performTestComparisons);
     EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
   });
 }
 
 function performTestComparisons(evt)
@@ -99,57 +99,53 @@ function finishTestComparisons()
 {
   InspectorUI.highlighter.removeListener("nodeselected", finishTestComparisons);
 
   // get dimensions of div element
   let divDims = div.getBoundingClientRect();
   let divWidth = divDims.width;
   let divHeight = divDims.height;
 
-  // get dimensions of the outline
-  let outlineDims = 
-    InspectorUI.highlighter.outline.getBoundingClientRect();
-  let outlineWidth = outlineDims.width;
-  let outlineHeight = outlineDims.height;
+  // get dimensions of transparent veil box over element
+  let veilBoxDims = 
+    InspectorUI.highlighter.veilTransparentBox.getBoundingClientRect();
+  let veilBoxWidth = veilBoxDims.width;
+  let veilBoxHeight = veilBoxDims.height;
 
   // Disabled due to bug 716245
-  //is(outlineWidth, divWidth, "outline width matches dimensions of element (no zoom)");
-  //is(outlineHeight, divHeight, "outline height matches dimensions of element (no zoom)");
+  //is(veilBoxWidth, divWidth, "transparent veil box width matches dimensions of element (no zoom)");
+  //is(veilBoxHeight, divHeight, "transparent veil box height matches dimensions of element (no zoom)");
 
   // zoom the page by a factor of 2
   let contentViewer = InspectorUI.browser.docShell.contentViewer
                              .QueryInterface(Ci.nsIMarkupDocumentViewer);
   contentViewer.fullZoom = 2;
 
-  // We wait at least 500ms to make sure the highlighter is not "mutting" the
-  // resize event
-
-  window.setTimeout(function() {
+  executeSoon(function() {
     // check what zoom factor we're at, should be 2
     let zoom = InspectorUI.highlighter.zoom;
     is(zoom, 2, "zoom is 2?");
 
     // simulate the zoomed dimensions of the div element
     let divDims = div.getBoundingClientRect();
     let divWidth = divDims.width * zoom;
     let divHeight = divDims.height * zoom;
 
-    // now zoomed, get new dimensions the outline
-    let outlineDims = 
-      InspectorUI.highlighter.outline.getBoundingClientRect();
-    let outlineWidth = outlineDims.width;
-    let outlineHeight = outlineDims.height;
+    // now zoomed, get new dimensions of transparent veil box over element
+    let veilBoxDims = InspectorUI.highlighter.veilTransparentBox.getBoundingClientRect();
+    let veilBoxWidth = veilBoxDims.width;
+    let veilBoxHeight = veilBoxDims.height;
 
     // Disabled due to bug 716245
-    //is(outlineWidth, divWidth, "outline width matches dimensions of element (no zoom)");
-    //is(outlineHeight, divHeight, "outline height matches dimensions of element (no zoom)");
+    //is(veilBoxWidth, divWidth, "transparent veil box width matches width of element (2x zoom)");
+    //is(veilBoxHeight, divHeight, "transparent veil box height matches width of element (2x zoom)");
 
     doc = h1 = div = null;
     executeSoon(finishUp);
-  }, 500);
+  });
 }
 
 function finishUp() {
   InspectorUI.closeInspectorUI();
   gBrowser.removeCurrentTab();
   finish();
 }
 
deleted file mode 100644
--- a/browser/devtools/highlighter/test/browser_inspector_highlighter_autohide.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-let doc;
-
-function createDocument() {
-  doc.body.innerHTML = '<h1>highlighter autohide test</h1>';
-
-  InspectorUI.openInspectorUI(doc.querySelector("h1"));
-
-  // Open the sidebar and wait for the default view (the rule view) to show.
-  InspectorUI.currentInspector.once("sidebaractivated-ruleview", inspectorRuleViewOpened);
-
-  InspectorUI.sidebar.show();
-  InspectorUI.sidebar.activatePanel("ruleview");
-}
-
-function inspectorRuleViewOpened() {
-  let deck = InspectorUI.sidebar._deck;
-
-  EventUtils.synthesizeMouse(InspectorUI.highlighter.highlighterContainer, 2, 2, {type: "mousemove"}, window);
-
-  executeSoon(function() {
-    ok(!InspectorUI.highlighter.hidden, "Outline visible (1)");
-
-    EventUtils.synthesizeMouse(deck, 10, 2, {type: "mouseover"}, window);
-
-    executeSoon(function() {
-      ok(InspectorUI.highlighter.hidden, "Outline not visible");
-
-      EventUtils.synthesizeMouse(deck, -10, 2, {type: "mouseover"}, window);
-
-      executeSoon(function() {
-        ok(!InspectorUI.highlighter.hidden, "Outline visible (2)");
-        finishTest();
-      });
-    });
-  });
-}
-
-function finishTest() {
-  InspectorUI.closeInspectorUI();
-  gBrowser.removeCurrentTab();
-  finish();
-}
-
-function test() {
-  waitForExplicitFinish();
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function() {
-    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-    doc = content.document;
-    waitForFocus(createDocument, content);
-  }, true);
-
-  content.location = "data:text/html,basic tests for highlighter";
-}
-
-
--- a/browser/devtools/highlighter/test/browser_inspector_invalidate.js
+++ b/browser/devtools/highlighter/test/browser_inspector_invalidate.js
@@ -18,22 +18,23 @@ function createDocument()
 function runTest(subject)
 {
   Services.obs.removeObserver(runTest,
     InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
 
   InspectorUI.highlighter.highlight(div);
 
   executeSoon(function() {
-    let outline = InspectorUI.highlighter.outline;
-    is(outline.style.width, "100px", "selection has the right width");
+    let veilBoxDims = InspectorUI.highlighter.veilTransparentBox;
+    is(veilBoxDims.style.width, "100px", "selection has the right width");
 
     div.style.width = "200px";
     setTimeout(function () {
-      is(outline.style.width, "200px", "selection updated");
+      let veilBoxDims = InspectorUI.highlighter.veilTransparentBox;
+      is(veilBoxDims.style.width, "200px", "selection updated");
       InspectorUI.closeInspectorUI();
       gBrowser.removeCurrentTab();
       finish();
     }, 1000);
   });
 }
 
 function test()
--- a/browser/devtools/highlighter/test/head.js
+++ b/browser/devtools/highlighter/test/head.js
@@ -18,18 +18,18 @@ function clearUserPrefs()
   Services.prefs.clearUserPref("devtools.inspector.sidebarOpen");
   Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
 }
 
 registerCleanupFunction(clearUserPrefs);
 
 function isHighlighting()
 {
-  let outline = InspectorUI.highlighter.outline;
-  return !(outline.getAttribute("hidden") == "true");
+  let veil = InspectorUI.highlighter.veilTransparentBox;
+  return !(veil.style.visibility == "hidden");
 }
 
 function getHighlitNode()
 {
   let h = InspectorUI.highlighter;
   if (!isHighlighting() || !h._contentRect)
     return null;
 
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -250,16 +250,26 @@ These should match what Safari and other
 <!ENTITY inspectorHTMLCopyInner.accesskey   "I">
 
 <!ENTITY inspectorHTMLCopyOuter.label       "Copy Outer HTML">
 <!ENTITY inspectorHTMLCopyOuter.accesskey   "O">
 
 <!ENTITY inspectorHTMLDelete.label          "Delete Node">
 <!ENTITY inspectorHTMLDelete.accesskey      "D">
 
+<!-- LOCALIZATION NOTE (inspectOptionButton.*): The menu in the Inspector
+  -  toolbar.  -->
+<!ENTITY inspectOptionButton.tooltiptext    "Inspector Options">
+
+<!-- LOCALIZATION NOTE: These are for the menu in the Inspector Toolbar -->
+<!ENTITY inspectorToggleVeil.label          "Dim The Page">
+<!ENTITY inspectorToggleVeil.accesskey      "D">
+<!ENTITY inspectorToggleInfobar.label       "Show Node Info">
+<!ENTITY inspectorToggleInfobar.accesskey   "S">
+
 <!-- LOCALIZATION NOTE (inspect3DViewButton.label): This button shows an
   -  alternate view for the Inspector, creating a 3D visualization of the
   -  webpage. -->
 <!ENTITY inspect3DViewButton.label     "3D View">
 <!ENTITY inspect3DViewButton.accesskey "W">
 
 <!ENTITY inspectStyleButton.label     "Style">
 <!ENTITY inspectStyleButton.accesskey "S">
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1968,38 +1968,54 @@ toolbar[mode="text"] toolbarbutton.chevr
 .statuspanel-label:-moz-locale-dir(ltr)[mirror] {
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 /* Highlighter */
 
-#highlighter-outline {
-  box-shadow: 0 0 0 1px black;
-  outline: 1px dashed white;
+.highlighter-veil {
+  background-color: rgba(25, 25, 25, 0.5);
+}
+
+#highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+  outline: 1px dashed rgba(255,255,255,0.5);
   outline-offset: -1px;
 }
 
-#highlighter-outline[locked]  {
-  box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
-  outline-color: rgba(255,255,255,0.7);
+#highlighter-veil-container[locked] > #highlighter-veil-middlebox > #highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px black;
+  outline-color: white;
 }
 
 /* Highlighter toolbar */
 
 #inspector-inspect-toolbutton {
   list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
 #inspector-inspect-toolbutton[checked=true] {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 
+#inspector-option-toolbarbutton {
+  -moz-appearance: none;
+  -moz-margin-end: 6px;
+  list-style-image: url("chrome://browser/skin/devtools/inspector-option-icon.png");
+  -moz-image-region: rect(0px 16px 16px 0px);
+  border: none;
+}
+
+#inspector-option-toolbarbutton[open] {
+  -moz-image-region: rect(0px 32px 16px 16px);
+}
+
 #inspector-toolbar,
 #developer-toolbar {
   border-top: 1px solid hsla(210, 8%, 5%, .65);
 }
 
 #devtools-side-splitter {
   -moz-appearance: none;
   border: 0;
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9fd78175dfd5449b43034602ed854907ea82d885
GIT binary patch
literal 1441
zc$@*D1z!4zP)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^000GONkl<Zc-noH
zc~Db#5XbX=FXZ3|2*e{0KoL~H3KUe(V!f^Bc!Cwt78Pj)1R)g|!c{@afN}~F0fkl@
z6f0o8kI|ymp<um5FkA*u4h_hd9`m}J@@6O<{Npq4xBK0FyZg)Um&egFmJEdg_<#vu
z1keBh^a0~RjT)N6Q8L5f0z!Zf5P$-B=tFII{O|_!<}F({Re9#zH~Z4EH-kM25CzNR
z%THEZkj-7X_9L))A83G{pzN`qbLFps8RxZMaSA&1Ik_zYm#TqP;5$5C**ghiKGc9P
zGH(CIj_y9i!)K~ouonXhZrrKOKwnyRK>*l>BQ-$DDtRvDUE60}{+sc-{AU{{ugwvf
zm^}NU_8$7&D>czn;w{1O1}K~yivuPGVw>fU8d?svcWZK9_4XGc?cII3P3o>p=_Hr+
z5Mv4m26HHOazKxYy>7sbx#aFxG0^M$vzD26<qsXM=d_Gd)qAZd>E?WB(s1ynpxFla
zUW->drDo=D5?fDMl%AuAS9fVLfP=$HNXdvb96f$6JU2|A^O*zY;>)a*Z|py=dKYYX
zw9DDGyz8h_<pASQ@n0N)X=ShS^c0;AE|vW|EKc;=>Keg`N|Zl^cJ}mTHLG7|b@cRM
z@l@pI-QQEL->ywzZPXfDJF+@^`m;`ypN)WAGo0GByt}}yLc@4ez3q2Cqhah$z11<{
z_$&2<<DG4+?E*2LRd3(8RcaX5)7>TTa~N{Cu<f7w?^=KEYIOn>*$*TmTLZ)5KwF3S
z1?-Mv{TNeS^WfW{2)Q2@8}L75V3AqpXH}wpVyo<C#{c*);sd`OAuD9_5pjA=0qe&Y
z>+d^SrFoC{P+#U4akwH053qul`Kn&N#_dnI`Rl!Su$R&zi5P+PlJnPY#i3T;q(*Hk
z<k$iNGIfa_`E=Vj%J1MJ%aV4jWoZW^DQ;~eKFJ=mwW}Ed>lu>5=0?;kj;RMAb_wKI
zl3Bid+yO3Zr5IQPFPB4+nA^1v<zRb(#zSB|`^KF*od!*!wi2fYXgE|f6?RHQg`f5q
zTiEh$Oi?Q%DO9}#p9AHa#zk-~IihMtZCp`{mI^JKfzyLV@C+F3jZ0orbN>lW9|`P*
z8xR#DlZS%lg6s;9-VHY)8a0f$aIIRtB_L!WXa;!CZHk)%CLdEZnHRiZOb@?cMk`c|
zm7*b)Q`9R(tQ5~v#()nsGr<1ni#p4q<`tZ5m2L;jGxLjgLQ&a+XR2^0paTwC%-y<2
zI&jVU>zmsnpqagerDcJ52yuGJp~ni-yyuK4`>95hThAcUBMppQabqKbYxL>JdG=nM
z|D2H?ep*UJT`<B1jBFg-JT`3E>Bl#f`bWr<WKbvsfkI&jYllT8Mwm$Kc5K-h`h|m=
z*C&uGBFkm^f`EK?Uewtb;=OMbf8Q@v!i+}@BFcKKgSA1cp#2W`@a311g~27W$@&BX
zJcL|e6d(a?MdNIJAJjJmLBU-^x&KrZ1P%H?%tSy6m|-p)QW_4TF_|)N4Dr|~r2`9>
z@zU<~^V07#Ljj+L_~$MlGrg^d(;^9RTxdev*K&1#r|=R2&^S?OWc(&57<jVsVi4Fn
zfWWKOHD9A|dr$;kOGAtW2>Vye=EI@VH&4AS=cd*&B<W5AOt_kOC#@#QciYit_FZ)_
zSsN>4^Z)lPfR_s=PV<-<la%hiV5K)Zt^FF`?VA%*v$okgdrpTK!ARc%Xn@BHE_LU`
zUOUd+Qx>F~)^n2$EjuIU#9cql5Bb3jV@CWKK{0x8YwZ9_fDZ@(8*BtH$C!~Cz^Pzc
vP2hf8!*eW|JeLPg0h#F|!A4MHCujKww^Ko-W{nMk00000NkvXXu0mjfmjtI_
--- a/browser/themes/gnomestripe/jar.mn
+++ b/browser/themes/gnomestripe/jar.mn
@@ -156,16 +156,17 @@ browser.jar:
   skin/classic/browser/devtools/layout-buttons.png    (devtools/layout-buttons.png)
   skin/classic/browser/devtools/debugger-collapse.png  (devtools/debugger-collapse.png)
   skin/classic/browser/devtools/debugger-expand.png    (devtools/debugger-expand.png)
   skin/classic/browser/devtools/debugger-pause.png     (devtools/debugger-pause.png)
   skin/classic/browser/devtools/debugger-play.png      (devtools/debugger-play.png)
   skin/classic/browser/devtools/debugger-step-in.png   (devtools/debugger-step-in.png)
   skin/classic/browser/devtools/debugger-step-out.png  (devtools/debugger-step-out.png)
   skin/classic/browser/devtools/debugger-step-over.png (devtools/debugger-step-over.png)
+  skin/classic/browser/devtools/inspector-option-icon.png (devtools/inspector-option-icon.png)
   skin/classic/browser/devtools/responsive-se-resizer.png (devtools/responsive-se-resizer.png)
   skin/classic/browser/devtools/responsive-vertical-resizer.png (devtools/responsive-vertical-resizer.png)
   skin/classic/browser/devtools/responsive-background.png (devtools/responsive-background.png)
   skin/classic/browser/devtools/tools-icons-small.png     (devtools/tools-icons-small.png)
 #ifdef MOZ_SERVICES_SYNC
   skin/classic/browser/sync-16-throbber.png
   skin/classic/browser/sync-16.png
   skin/classic/browser/sync-24-throbber.png
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -2661,38 +2661,54 @@ toolbarbutton.chevron > .toolbarbutton-m
   border-left-style: solid;
   border-top-left-radius: .3em;
   margin-left: 1em;
 }
 
 
 /* Highlighter */
 
-#highlighter-outline {
-  box-shadow: 0 0 0 1px black;
-  outline: 1px dashed white;
+.highlighter-veil {
+  background-color: rgba(25, 25, 25, 0.5);
+}
+
+#highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+  outline: 1px dashed rgba(255,255,255,0.5);
   outline-offset: -1px;
 }
 
-#highlighter-outline[locked]  {
-  box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
-  outline-color: rgba(255,255,255,0.7);
+#highlighter-veil-container[locked] > #highlighter-veil-middlebox > #highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px black;
+  outline-color: white;
 }
 
 /* Highlighter toolbar */
 
 #inspector-inspect-toolbutton {
   list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
 #inspector-inspect-toolbutton[checked=true] {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 
+#inspector-option-toolbarbutton {
+  -moz-appearance: none;
+  -moz-margin-end: 6px;
+  list-style-image: url("chrome://browser/skin/devtools/inspector-option-icon.png");
+  -moz-image-region: rect(0px 16px 16px 0px);
+  border: none;
+}
+
+#inspector-option-toolbarbutton[open] {
+  -moz-image-region: rect(0px 32px 16px 16px);
+}
+
 #inspector-toolbar,
 #developer-toolbar {
   border-top: 1px solid hsla(210, 8%, 5%, .65);
   padding-top: 4px;
   padding-bottom: 4px;
 }
 
 #inspector-toolbar:-moz-locale-dir(ltr),
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9fd78175dfd5449b43034602ed854907ea82d885
GIT binary patch
literal 1441
zc$@*D1z!4zP)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^000GONkl<Zc-noH
zc~Db#5XbX=FXZ3|2*e{0KoL~H3KUe(V!f^Bc!Cwt78Pj)1R)g|!c{@afN}~F0fkl@
z6f0o8kI|ymp<um5FkA*u4h_hd9`m}J@@6O<{Npq4xBK0FyZg)Um&egFmJEdg_<#vu
z1keBh^a0~RjT)N6Q8L5f0z!Zf5P$-B=tFII{O|_!<}F({Re9#zH~Z4EH-kM25CzNR
z%THEZkj-7X_9L))A83G{pzN`qbLFps8RxZMaSA&1Ik_zYm#TqP;5$5C**ghiKGc9P
zGH(CIj_y9i!)K~ouonXhZrrKOKwnyRK>*l>BQ-$DDtRvDUE60}{+sc-{AU{{ugwvf
zm^}NU_8$7&D>czn;w{1O1}K~yivuPGVw>fU8d?svcWZK9_4XGc?cII3P3o>p=_Hr+
z5Mv4m26HHOazKxYy>7sbx#aFxG0^M$vzD26<qsXM=d_Gd)qAZd>E?WB(s1ynpxFla
zUW->drDo=D5?fDMl%AuAS9fVLfP=$HNXdvb96f$6JU2|A^O*zY;>)a*Z|py=dKYYX
zw9DDGyz8h_<pASQ@n0N)X=ShS^c0;AE|vW|EKc;=>Keg`N|Zl^cJ}mTHLG7|b@cRM
z@l@pI-QQEL->ywzZPXfDJF+@^`m;`ypN)WAGo0GByt}}yLc@4ez3q2Cqhah$z11<{
z_$&2<<DG4+?E*2LRd3(8RcaX5)7>TTa~N{Cu<f7w?^=KEYIOn>*$*TmTLZ)5KwF3S
z1?-Mv{TNeS^WfW{2)Q2@8}L75V3AqpXH}wpVyo<C#{c*);sd`OAuD9_5pjA=0qe&Y
z>+d^SrFoC{P+#U4akwH053qul`Kn&N#_dnI`Rl!Su$R&zi5P+PlJnPY#i3T;q(*Hk
z<k$iNGIfa_`E=Vj%J1MJ%aV4jWoZW^DQ;~eKFJ=mwW}Ed>lu>5=0?;kj;RMAb_wKI
zl3Bid+yO3Zr5IQPFPB4+nA^1v<zRb(#zSB|`^KF*od!*!wi2fYXgE|f6?RHQg`f5q
zTiEh$Oi?Q%DO9}#p9AHa#zk-~IihMtZCp`{mI^JKfzyLV@C+F3jZ0orbN>lW9|`P*
z8xR#DlZS%lg6s;9-VHY)8a0f$aIIRtB_L!WXa;!CZHk)%CLdEZnHRiZOb@?cMk`c|
zm7*b)Q`9R(tQ5~v#()nsGr<1ni#p4q<`tZ5m2L;jGxLjgLQ&a+XR2^0paTwC%-y<2
zI&jVU>zmsnpqagerDcJ52yuGJp~ni-yyuK4`>95hThAcUBMppQabqKbYxL>JdG=nM
z|D2H?ep*UJT`<B1jBFg-JT`3E>Bl#f`bWr<WKbvsfkI&jYllT8Mwm$Kc5K-h`h|m=
z*C&uGBFkm^f`EK?Uewtb;=OMbf8Q@v!i+}@BFcKKgSA1cp#2W`@a311g~27W$@&BX
zJcL|e6d(a?MdNIJAJjJmLBU-^x&KrZ1P%H?%tSy6m|-p)QW_4TF_|)N4Dr|~r2`9>
z@zU<~^V07#Ljj+L_~$MlGrg^d(;^9RTxdev*K&1#r|=R2&^S?OWc(&57<jVsVi4Fn
zfWWKOHD9A|dr$;kOGAtW2>Vye=EI@VH&4AS=cd*&B<W5AOt_kOC#@#QciYit_FZ)_
zSsN>4^Z)lPfR_s=PV<-<la%hiV5K)Zt^FF`?VA%*v$okgdrpTK!ARc%Xn@BHE_LU`
zUOUd+Qx>F~)^n2$EjuIU#9cql5Bb3jV@CWKK{0x8YwZ9_fDZ@(8*BtH$C!~Cz^Pzc
vP2hf8!*eW|JeLPg0h#F|!A4MHCujKww^Ko-W{nMk00000NkvXXu0mjfmjtI_
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -197,16 +197,17 @@ browser.jar:
   skin/classic/browser/devtools/layout-buttons.png          (devtools/layout-buttons.png)
   skin/classic/browser/devtools/debugger-collapse.png       (devtools/debugger-collapse.png)
   skin/classic/browser/devtools/debugger-expand.png         (devtools/debugger-expand.png)
   skin/classic/browser/devtools/debugger-pause.png          (devtools/debugger-pause.png)
   skin/classic/browser/devtools/debugger-play.png           (devtools/debugger-play.png)
   skin/classic/browser/devtools/debugger-step-in.png        (devtools/debugger-step-in.png)
   skin/classic/browser/devtools/debugger-step-out.png       (devtools/debugger-step-out.png)
   skin/classic/browser/devtools/debugger-step-over.png      (devtools/debugger-step-over.png)
+  skin/classic/browser/devtools/inspector-option-icon.png   (devtools/inspector-option-icon.png)
   skin/classic/browser/devtools/responsive-se-resizer.png   (devtools/responsive-se-resizer.png)
   skin/classic/browser/devtools/responsive-vertical-resizer.png (devtools/responsive-vertical-resizer.png)
   skin/classic/browser/devtools/responsive-background.png   (devtools/responsive-background.png)
   skin/classic/browser/devtools/tools-icons-small.png       (devtools/tools-icons-small.png)
 #ifdef MOZ_SERVICES_SYNC
   skin/classic/browser/sync-throbber.png
   skin/classic/browser/sync-16.png
   skin/classic/browser/sync-32.png
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -2647,38 +2647,54 @@ toolbarbutton.bookmark-item[dragover="tr
   /* disabled for triggering grayscale AA (bug 659213)
   border-top-left-radius: .3em;
   */
   margin-left: 1em;
 }
 
 /* Highlighter */
 
-#highlighter-outline {
-  box-shadow: 0 0 0 1px black;
-  outline: 1px dashed white;
+.highlighter-veil {
+  background-color: rgba(25, 25, 25, 0.5);
+}
+
+#highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px rgba(0,0,0,0.5);
+  outline: 1px dashed rgba(255,255,255,0.5);
   outline-offset: -1px;
 }
 
-#highlighter-outline[locked]  {
-  box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
-  outline-color: rgba(255,255,255,0.7);
+#highlighter-veil-container[locked] > #highlighter-veil-middlebox > #highlighter-veil-transparentbox {
+  box-shadow: 0 0 0 1px black;
+  outline-color: white;
 }
 
 /* Highlighter toolbar */
 
 #inspector-inspect-toolbutton {
   list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
 #inspector-inspect-toolbutton[checked=true] {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 
+#inspector-option-toolbarbutton {
+  -moz-appearance: none;
+  -moz-margin-end: 6px;
+  list-style-image: url("chrome://browser/skin/devtools/inspector-option-icon.png");
+  -moz-image-region: rect(0px 16px 16px 0px);
+  border: none;
+}
+
+#inspector-option-toolbarbutton[open] {
+  -moz-image-region: rect(0px 32px 16px 16px);
+}
+
 #inspector-toolbar,
 #developer-toolbar {
   border-top: 1px solid hsla(211,68%,6%,.65) !important;
 }
 
 #devtools-side-splitter {
   border: 0;
   -moz-border-start: 1px solid #242b33;
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9fd78175dfd5449b43034602ed854907ea82d885
GIT binary patch
literal 1441
zc$@*D1z!4zP)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^000GONkl<Zc-noH
zc~Db#5XbX=FXZ3|2*e{0KoL~H3KUe(V!f^Bc!Cwt78Pj)1R)g|!c{@afN}~F0fkl@
z6f0o8kI|ymp<um5FkA*u4h_hd9`m}J@@6O<{Npq4xBK0FyZg)Um&egFmJEdg_<#vu
z1keBh^a0~RjT)N6Q8L5f0z!Zf5P$-B=tFII{O|_!<}F({Re9#zH~Z4EH-kM25CzNR
z%THEZkj-7X_9L))A83G{pzN`qbLFps8RxZMaSA&1Ik_zYm#TqP;5$5C**ghiKGc9P
zGH(CIj_y9i!)K~ouonXhZrrKOKwnyRK>*l>BQ-$DDtRvDUE60}{+sc-{AU{{ugwvf
zm^}NU_8$7&D>czn;w{1O1}K~yivuPGVw>fU8d?svcWZK9_4XGc?cII3P3o>p=_Hr+
z5Mv4m26HHOazKxYy>7sbx#aFxG0^M$vzD26<qsXM=d_Gd)qAZd>E?WB(s1ynpxFla
zUW->drDo=D5?fDMl%AuAS9fVLfP=$HNXdvb96f$6JU2|A^O*zY;>)a*Z|py=dKYYX
zw9DDGyz8h_<pASQ@n0N)X=ShS^c0;AE|vW|EKc;=>Keg`N|Zl^cJ}mTHLG7|b@cRM
z@l@pI-QQEL->ywzZPXfDJF+@^`m;`ypN)WAGo0GByt}}yLc@4ez3q2Cqhah$z11<{
z_$&2<<DG4+?E*2LRd3(8RcaX5)7>TTa~N{Cu<f7w?^=KEYIOn>*$*TmTLZ)5KwF3S
z1?-Mv{TNeS^WfW{2)Q2@8}L75V3AqpXH}wpVyo<C#{c*);sd`OAuD9_5pjA=0qe&Y
z>+d^SrFoC{P+#U4akwH053qul`Kn&N#_dnI`Rl!Su$R&zi5P+PlJnPY#i3T;q(*Hk
z<k$iNGIfa_`E=Vj%J1MJ%aV4jWoZW^DQ;~eKFJ=mwW}Ed>lu>5=0?;kj;RMAb_wKI
zl3Bid+yO3Zr5IQPFPB4+nA^1v<zRb(#zSB|`^KF*od!*!wi2fYXgE|f6?RHQg`f5q
zTiEh$Oi?Q%DO9}#p9AHa#zk-~IihMtZCp`{mI^JKfzyLV@C+F3jZ0orbN>lW9|`P*
z8xR#DlZS%lg6s;9-VHY)8a0f$aIIRtB_L!WXa;!CZHk)%CLdEZnHRiZOb@?cMk`c|
zm7*b)Q`9R(tQ5~v#()nsGr<1ni#p4q<`tZ5m2L;jGxLjgLQ&a+XR2^0paTwC%-y<2
zI&jVU>zmsnpqagerDcJ52yuGJp~ni-yyuK4`>95hThAcUBMppQabqKbYxL>JdG=nM
z|D2H?ep*UJT`<B1jBFg-JT`3E>Bl#f`bWr<WKbvsfkI&jYllT8Mwm$Kc5K-h`h|m=
z*C&uGBFkm^f`EK?Uewtb;=OMbf8Q@v!i+}@BFcKKgSA1cp#2W`@a311g~27W$@&BX
zJcL|e6d(a?MdNIJAJjJmLBU-^x&KrZ1P%H?%tSy6m|-p)QW_4TF_|)N4Dr|~r2`9>
z@zU<~^V07#Ljj+L_~$MlGrg^d(;^9RTxdev*K&1#r|=R2&^S?OWc(&57<jVsVi4Fn
zfWWKOHD9A|dr$;kOGAtW2>Vye=EI@VH&4AS=cd*&B<W5AOt_kOC#@#QciYit_FZ)_
zSsN>4^Z)lPfR_s=PV<-<la%hiV5K)Zt^FF`?VA%*v$okgdrpTK!ARc%Xn@BHE_LU`
zUOUd+Qx>F~)^n2$EjuIU#9cql5Bb3jV@CWKK{0x8YwZ9_fDZ@(8*BtH$C!~Cz^Pzc
vP2hf8!*eW|JeLPg0h#F|!A4MHCujKww^Ko-W{nMk00000NkvXXu0mjfmjtI_
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -184,16 +184,17 @@ browser.jar:
         skin/classic/browser/devtools/layout-buttons.png            (devtools/layout-buttons.png)
         skin/classic/browser/devtools/debugger-collapse.png         (devtools/debugger-collapse.png)
         skin/classic/browser/devtools/debugger-expand.png           (devtools/debugger-expand.png)
         skin/classic/browser/devtools/debugger-pause.png            (devtools/debugger-pause.png)
         skin/classic/browser/devtools/debugger-play.png             (devtools/debugger-play.png)
         skin/classic/browser/devtools/debugger-step-in.png          (devtools/debugger-step-in.png)
         skin/classic/browser/devtools/debugger-step-out.png         (devtools/debugger-step-out.png)
         skin/classic/browser/devtools/debugger-step-over.png        (devtools/debugger-step-over.png)
+        skin/classic/browser/devtools/inspector-option-icon.png     (devtools/inspector-option-icon.png)
         skin/classic/browser/devtools/responsive-se-resizer.png     (devtools/responsive-se-resizer.png)
         skin/classic/browser/devtools/responsive-vertical-resizer.png (devtools/responsive-vertical-resizer.png)
         skin/classic/browser/devtools/responsive-background.png     (devtools/responsive-background.png)
         skin/classic/browser/devtools/tools-icons-small.png         (devtools/tools-icons-small.png)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/browser/sync-throbber.png
         skin/classic/browser/sync-16.png
         skin/classic/browser/sync-32.png
@@ -388,16 +389,17 @@ browser.jar:
         skin/classic/aero/browser/devtools/layout-buttons.png        (devtools/layout-buttons.png)
         skin/classic/aero/browser/devtools/debugger-collapse.png     (devtools/debugger-collapse.png)
         skin/classic/aero/browser/devtools/debugger-expand.png       (devtools/debugger-expand.png)
         skin/classic/aero/browser/devtools/debugger-pause.png        (devtools/debugger-pause.png)
         skin/classic/aero/browser/devtools/debugger-play.png         (devtools/debugger-play.png)
         skin/classic/aero/browser/devtools/debugger-step-in.png      (devtools/debugger-step-in.png)
         skin/classic/aero/browser/devtools/debugger-step-out.png     (devtools/debugger-step-out.png)
         skin/classic/aero/browser/devtools/debugger-step-over.png    (devtools/debugger-step-over.png)
+        skin/classic/aero/browser/devtools/inspector-option-icon.png (devtools/inspector-option-icon.png)
         skin/classic/aero/browser/devtools/responsive-se-resizer.png (devtools/responsive-se-resizer.png)
         skin/classic/aero/browser/devtools/responsive-vertical-resizer.png (devtools/responsive-vertical-resizer.png)
         skin/classic/aero/browser/devtools/responsive-background.png (devtools/responsive-background.png)
         skin/classic/aero/browser/devtools/tools-icons-small.png     (devtools/tools-icons-small.png)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/aero/browser/sync-throbber.png
         skin/classic/aero/browser/sync-16.png
         skin/classic/aero/browser/sync-32.png