Bug 917072 - Move black box eyeball into sources toolbar; r=vporof
authorNick Fitzgerald <fitzgen@gmail.com>
Wed, 23 Oct 2013 02:10:08 -0700
changeset 165607 2ed8270e713f783aaba5d4700236f0f65fe49dfc
parent 165606 7bdb63636763a8f41a09639f9b8570fa2f8f4ad9
child 165608 01672d68f16a6e751fe15f061fa55df0492ad3ea
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvporof
bugs917072
milestone27.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 917072 - Move black box eyeball into sources toolbar; r=vporof
browser/devtools/debugger/debugger-controller.js
browser/devtools/debugger/debugger-panes.js
browser/devtools/debugger/debugger.xul
browser/devtools/debugger/test/browser.ini
browser/devtools/debugger/test/browser_dbg_blackboxing-01.js
browser/devtools/debugger/test/browser_dbg_blackboxing-02.js
browser/devtools/debugger/test/browser_dbg_blackboxing-03.js
browser/devtools/debugger/test/browser_dbg_blackboxing-04.js
browser/devtools/debugger/test/browser_dbg_blackboxing-05.js
browser/devtools/debugger/test/browser_dbg_blackboxing-06.js
browser/devtools/debugger/test/browser_dbg_blackboxing-07.js
browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
browser/devtools/debugger/test/browser_dbg_pretty-print-10.js
browser/devtools/debugger/test/head.js
browser/locales/en-US/chrome/browser/devtools/debugger.dtd
browser/themes/linux/devtools/debugger-blackbox.png
browser/themes/linux/devtools/debugger.css
browser/themes/linux/jar.mn
browser/themes/osx/devtools/debugger-blackbox.png
browser/themes/osx/devtools/debugger.css
browser/themes/osx/jar.mn
browser/themes/windows/devtools/debugger-blackbox.png
browser/themes/windows/devtools/debugger.css
browser/themes/windows/jar.mn
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -1151,18 +1151,23 @@ SourceScripts.prototype = {
   },
 
   /**
    * Handler for the debugger client's 'blackboxchange' notification.
    */
   _onBlackBoxChange: function (aEvent, { url, isBlackBoxed }) {
     const item = DebuggerView.Sources.getItemByValue(url);
     if (item) {
-      DebuggerView.Sources.callMethod("checkItem", item.target, !isBlackBoxed);
+      if (isBlackBoxed) {
+        item.target.classList.add("black-boxed");
+      } else {
+        item.target.classList.remove("black-boxed");
+      }
     }
+    DebuggerView.Sources.updateToolbarButtonsState();
     DebuggerView.maybeShowBlackBoxMessage();
   },
 
   /**
    * Set the black boxed status of the given source.
    *
    * @param Object aSource
    *        The source form.
--- a/browser/devtools/debugger/debugger-panes.js
+++ b/browser/devtools/debugger/debugger-panes.js
@@ -14,60 +14,59 @@ function SourcesView() {
   this.togglePrettyPrint = this.togglePrettyPrint.bind(this);
   this._onEditorLoad = this._onEditorLoad.bind(this);
   this._onEditorUnload = this._onEditorUnload.bind(this);
   this._onEditorCursorActivity = this._onEditorCursorActivity.bind(this);
   this._onEditorContextMenu = this._onEditorContextMenu.bind(this);
   this._onSourceSelect = this._onSourceSelect.bind(this);
   this._onSourceClick = this._onSourceClick.bind(this);
   this._onBreakpointRemoved = this._onBreakpointRemoved.bind(this);
-  this._onSourceCheck = this._onSourceCheck.bind(this);
+  this.toggleBlackBoxing = this.toggleBlackBoxing.bind(this);
   this._onStopBlackBoxing = this._onStopBlackBoxing.bind(this);
   this._onBreakpointClick = this._onBreakpointClick.bind(this);
   this._onBreakpointCheckboxClick = this._onBreakpointCheckboxClick.bind(this);
   this._onConditionalPopupShowing = this._onConditionalPopupShowing.bind(this);
   this._onConditionalPopupShown = this._onConditionalPopupShown.bind(this);
   this._onConditionalPopupHiding = this._onConditionalPopupHiding.bind(this);
   this._onConditionalTextboxInput = this._onConditionalTextboxInput.bind(this);
   this._onConditionalTextboxKeyPress = this._onConditionalTextboxKeyPress.bind(this);
-  this._updatePrettyPrintButtonState = this._updatePrettyPrintButtonState.bind(this);
+  this.updateToolbarButtonsState = this.updateToolbarButtonsState.bind(this);
 }
 
 SourcesView.prototype = Heritage.extend(WidgetMethods, {
   /**
    * Initialization function, called when the debugger is started.
    */
   initialize: function() {
     dumpn("Initializing the SourcesView");
 
     this.widget = new SideMenuWidget(document.getElementById("sources"), {
-      showItemCheckboxes: true,
       showArrows: true
     });
 
     this.emptyText = L10N.getStr("noSourcesText");
     this._blackBoxCheckboxTooltip = L10N.getStr("blackBoxCheckboxTooltip");
 
     this._commandset = document.getElementById("debuggerCommands");
     this._popupset = document.getElementById("debuggerPopupset");
     this._cmPopup = document.getElementById("sourceEditorContextMenu");
     this._cbPanel = document.getElementById("conditional-breakpoint-panel");
     this._cbTextbox = document.getElementById("conditional-breakpoint-panel-textbox");
+    this._blackBoxButton = document.getElementById("black-box");
     this._stopBlackBoxButton = document.getElementById("black-boxed-message-button");
     this._prettyPrintButton = document.getElementById("pretty-print");
 
     if (Prefs.prettyPrintEnabled) {
       this._prettyPrintButton.removeAttribute("hidden");
     }
 
     window.on(EVENTS.EDITOR_LOADED, this._onEditorLoad, false);
     window.on(EVENTS.EDITOR_UNLOADED, this._onEditorUnload, false);
     this.widget.addEventListener("select", this._onSourceSelect, false);
     this.widget.addEventListener("click", this._onSourceClick, false);
-    this.widget.addEventListener("check", this._onSourceCheck, false);
     this._stopBlackBoxButton.addEventListener("click", this._onStopBlackBoxing, false);
     this._cbPanel.addEventListener("popupshowing", this._onConditionalPopupShowing, false);
     this._cbPanel.addEventListener("popupshown", this._onConditionalPopupShown, false);
     this._cbPanel.addEventListener("popuphiding", this._onConditionalPopupHiding, false);
     this._cbTextbox.addEventListener("input", this._onConditionalTextboxInput, false);
     this._cbTextbox.addEventListener("keypress", this._onConditionalTextboxKeyPress, false);
 
     this.autoFocusOnSelection = false;
@@ -81,17 +80,16 @@ SourcesView.prototype = Heritage.extend(
    */
   destroy: function() {
     dumpn("Destroying the SourcesView");
 
     window.off(EVENTS.EDITOR_LOADED, this._onEditorLoad, false);
     window.off(EVENTS.EDITOR_UNLOADED, this._onEditorUnload, false);
     this.widget.removeEventListener("select", this._onSourceSelect, false);
     this.widget.removeEventListener("click", this._onSourceClick, false);
-    this.widget.removeEventListener("check", this._onSourceCheck, false);
     this._stopBlackBoxButton.removeEventListener("click", this._onStopBlackBoxing, false);
     this._cbPanel.removeEventListener("popupshowing", this._onConditionalPopupShowing, false);
     this._cbPanel.removeEventListener("popupshowing", this._onConditionalPopupShown, false);
     this._cbPanel.removeEventListener("popuphiding", this._onConditionalPopupHiding, false);
     this._cbTextbox.removeEventListener("input", this._onConditionalTextboxInput, false);
     this._cbTextbox.removeEventListener("keypress", this._onConditionalTextboxKeyPress, false);
   },
 
@@ -697,32 +695,33 @@ SourcesView.prototype = Heritage.extend(
     // The container is not empty and an actual item was selected.
     DebuggerView.setEditorLocation(sourceItem.value);
 
     // Set window title.
     let script = sourceItem.value.split(" -> ").pop();
     document.title = L10N.getFormatStr("DebuggerWindowScriptTitle", script);
 
     DebuggerView.maybeShowBlackBoxMessage();
-    this._updatePrettyPrintButtonState();
+    this.updateToolbarButtonsState();
   },
 
   /**
-   * Enable or disable the pretty print button depending on whether the selected
-   * source is black boxed or not and check or uncheck it depending on if the
-   * selected source is already pretty printed or not.
+   * Update the checked/unchecked and enabled/disabled states of the buttons in
+   * the sources toolbar based on the currently selected source's state.
    */
-  _updatePrettyPrintButtonState: function() {
+  updateToolbarButtonsState: function() {
     const { source } = this.selectedItem.attachment;
     const sourceClient = gThreadClient.source(source);
 
     if (sourceClient.isBlackBoxed) {
       this._prettyPrintButton.setAttribute("disabled", true);
+      this._blackBoxButton.setAttribute("checked", true);
     } else {
       this._prettyPrintButton.removeAttribute("disabled");
+      this._blackBoxButton.removeAttribute("checked");
     }
 
     if (sourceClient.isPrettyPrinted) {
       this._prettyPrintButton.setAttribute("checked", true);
     } else {
       this._prettyPrintButton.removeAttribute("checked");
     }
   },
@@ -731,44 +730,50 @@ SourcesView.prototype = Heritage.extend(
    * The click listener for the sources container.
    */
   _onSourceClick: function() {
     // Use this container as a filtering target.
     DebuggerView.Filtering.target = this;
   },
 
   /**
-   * The check listener for the sources container.
+   * Toggle the black boxed state of the selected source.
    */
-  _onSourceCheck: function({ detail: { checked }, target }) {
-    const shouldBlackBox = !checked;
+  toggleBlackBoxing: function() {
+    const { source } = this.selectedItem.attachment;
+    const sourceClient = gThreadClient.source(source);
+    const shouldBlackBox = !sourceClient.isBlackBoxed;
 
-    // Be optimistic that the (un-)black boxing will succeed and enable/disable
-    // the pretty print button immediately. Then, once we actually get the
-    // results from the server, make sure that it is in the correct state again
-    // by calling `_updatePrettyPrintButtonState`.
+    // Be optimistic that the (un-)black boxing will succeed, so enable/disable
+    // the pretty print button and check/uncheck the black box button
+    // immediately. Then, once we actually get the results from the server, make
+    // sure that it is in the correct state again by calling
+    // `updateToolbarButtonsState`.
 
     if (shouldBlackBox) {
       this._prettyPrintButton.setAttribute("disabled", true);
+      this._blackBoxButton.setAttribute("checked", true);
     } else {
       this._prettyPrintButton.removeAttribute("disabled");
+      this._blackBoxButton.removeAttribute("checked");
     }
 
-    const { source } = this.getItemForElement(target).attachment;
     DebuggerController.SourceScripts.blackBox(source, shouldBlackBox)
-      .then(this._updatePrettyPrintButtonState,
-            this._updatePrettyPrintButtonState);
+      .then(this.updateToolbarButtonsState,
+            this.updateToolbarButtonsState);
   },
 
   /**
    * The click listener for the "stop black boxing" button.
    */
   _onStopBlackBoxing: function() {
     let sourceForm = this.selectedItem.attachment.source;
-    DebuggerController.SourceScripts.blackBox(sourceForm, false);
+    DebuggerController.SourceScripts.blackBox(sourceForm, false)
+      .then(this.updateToolbarButtonsState,
+            this.updateToolbarButtonsState);
   },
 
   /**
    * The click listener for a breakpoint container.
    */
   _onBreakpointClick: function(e) {
     let sourceItem = this.getItemForElement(e.target);
     let breakpointItem = this.getItemForElement.call(sourceItem, e.target);
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -27,16 +27,18 @@
   <script type="text/javascript" src="debugger-toolbar.js"/>
   <script type="text/javascript" src="debugger-panes.js"/>
 
   <commandset id="editMenuCommands"/>
 
   <commandset id="debuggerCommands">
     <command id="prettyPrintCommand"
              oncommand="DebuggerView.Sources.togglePrettyPrint()"/>
+    <command id="blackBoxCommand"
+             oncommand="DebuggerView.Sources.toggleBlackBoxing()"/>
     <command id="unBlackBoxButton"
              oncommand="DebuggerView.Sources._onStopBlackBoxing()"/>
     <command id="nextSourceCommand"
              oncommand="DebuggerView.Sources.selectNextItem()"/>
     <command id="prevSourceCommand"
              oncommand="DebuggerView.Sources.selectPrevItem()"/>
     <command id="resumeCommand"
              oncommand="DebuggerView.Toolbar._onResumePressed()"/>
@@ -315,22 +317,28 @@
                      tabindex="0"/>
     </toolbar>
     <scrollbox id="globalsearch" orient="vertical" hidden="true"/>
     <splitter class="devtools-horizontal-splitter" hidden="true"/>
     <hbox id="debugger-widgets" flex="1">
       <vbox id="sources-pane">
         <vbox id="sources" flex="1"/>
         <toolbar id="sources-toolbar" class="devtools-toolbar">
-          <toolbarbutton id="pretty-print"
-                         label="{}"
-                         tooltiptext="&debuggerUI.sources.prettyPrint;"
-                         class="devtools-toolbarbutton devtools-monospace"
-                         command="prettyPrintCommand"
-                         hidden="true"/>
+          <hbox id="sources-controls">
+            <toolbarbutton id="black-box"
+                           tooltiptext="&debuggerUI.sources.blackBoxTooltip;"
+                           command="blackBoxCommand"
+                           class="devtools-toolbarbutton"/>
+            <toolbarbutton id="pretty-print"
+                           label="{}"
+                           tooltiptext="&debuggerUI.sources.prettyPrint;"
+                           class="devtools-toolbarbutton devtools-monospace"
+                           command="prettyPrintCommand"
+                           hidden="true"/>
+          </hbox>
         </toolbar>
       </vbox>
       <splitter id="sources-and-editor-splitter"
                 class="devtools-side-splitter"/>
       <deck id="editor-deck" flex="4">
         <vbox id="editor"/>
         <vbox id="black-boxed-message" align="center" pack="center">
           <label id="black-boxed-message-label">
--- a/browser/devtools/debugger/test/browser.ini
+++ b/browser/devtools/debugger/test/browser.ini
@@ -60,17 +60,16 @@ support-files =
 [browser_dbg_aaa_run_first_leaktest.js]
 [browser_dbg_bfcache.js]
 [browser_dbg_blackboxing-01.js]
 [browser_dbg_blackboxing-02.js]
 [browser_dbg_blackboxing-03.js]
 [browser_dbg_blackboxing-04.js]
 [browser_dbg_blackboxing-05.js]
 [browser_dbg_blackboxing-06.js]
-[browser_dbg_blackboxing-07.js]
 [browser_dbg_file-reload.js]
 [browser_dbg_breadcrumbs-access.js]
 [browser_dbg_break-on-dom-01.js]
 [browser_dbg_break-on-dom-02.js]
 [browser_dbg_break-on-dom-03.js]
 [browser_dbg_break-on-dom-04.js]
 [browser_dbg_break-on-dom-05.js]
 [browser_dbg_break-on-dom-06.js]
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_blackboxing-01.js
@@ -22,34 +22,29 @@ function test() {
       .then(() => closeDebuggerAndFinish(gPanel))
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testBlackBoxSource() {
-  const checkbox = gDebugger.document.querySelector(".side-menu-widget-item-checkbox");
-  ok(checkbox, "Should get the checkbox for black boxing the source.");
-  ok(checkbox.checked, "Should not be black boxed by default.");
+  const bbButton = getBlackBoxButton(gPanel);
+  ok(!bbButton.checked, "Should not be black boxed by default");
 
-  let finished = waitForThreadEvents(gPanel, "blackboxchange").then(aSource => {
+  return toggleBlackBoxing(gPanel).then(aSource => {
     ok(aSource.isBlackBoxed, "The source should be black boxed now.");
-    ok(!checkbox.checked, "The checkbox should no longer be checked.");
+    ok(bbButton.checked, "The checkbox should no longer be checked.");
   });
-
-  checkbox.click();
-  return finished;
 }
 
 function testBlackBoxReload() {
   return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(() => {
-    const checkbox = gDebugger.document.querySelector(".side-menu-widget-item-checkbox");
-    ok(checkbox, "Should get the checkbox for black boxing the source.");
-    ok(!checkbox.checked, "Should still be black boxed.");
+    const bbButton = getBlackBoxButton(gPanel);
+    ok(bbButton.checked, "Should still be black boxed.");
   });
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
   gDebugger = null;
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-02.js
+++ b/browser/devtools/debugger/test/browser_dbg_blackboxing-02.js
@@ -26,43 +26,34 @@ function test() {
       .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testBlackBoxSource() {
-  let finished = waitForThreadEvents(gPanel, "blackboxchange").then(aSource => {
+  return toggleBlackBoxing(gPanel).then(aSource => {
     ok(aSource.isBlackBoxed, "The source should be black boxed now.");
   });
-
-  getBlackBoxCheckbox(BLACKBOXME_URL).click();
-  return finished;
 }
 
 function testBlackBoxStack() {
   let finished = waitForSourceAndCaretAndScopes(gPanel, ".html", 21).then(() => {
     is(gFrames.itemCount, 3,
       "Should only get 3 frames.");
     is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
       "And one of them should be the combined black boxed frames.");
   });
 
   // Spin the event loop before causing the debuggee to pause, to allow
   // this function to return first.
   executeSoon(() => gDebuggee.runTest());
   return finished;
 }
 
-function getBlackBoxCheckbox(aUrl) {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
-    ".side-menu-widget-item-checkbox");
-}
-
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
   gDebugger = null;
   gFrames = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-03.js
+++ b/browser/devtools/debugger/test/browser_dbg_blackboxing-03.js
@@ -35,33 +35,24 @@ function test() {
 function testBlackBoxStack() {
   is(gFrames.itemCount, 6,
     "Should get 6 frames.");
   is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 0,
     "And none of them are black boxed.");
 }
 
 function testBlackBoxSource() {
-  let finished = waitForThreadEvents(gPanel, "blackboxchange").then(aSource => {
+  return toggleBlackBoxing(gPanel, BLACKBOXME_URL).then(aSource => {
     ok(aSource.isBlackBoxed, "The source should be black boxed now.");
 
     is(gFrames.itemCount, 3,
       "Should only get 3 frames.");
     is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
       "And one of them should be the combined black boxed frames.");
   });
-
-  getBlackBoxCheckbox(BLACKBOXME_URL).click();
-  return finished;
-}
-
-function getBlackBoxCheckbox(aUrl) {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
-    ".side-menu-widget-item-checkbox");
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
   gDebugger = null;
   gFrames = null;
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-04.js
+++ b/browser/devtools/debugger/test/browser_dbg_blackboxing-04.js
@@ -27,19 +27,19 @@ function test() {
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function blackBoxSources() {
   let finished = waitForThreadEvents(gPanel, "blackboxchange", 3);
-  getBlackBoxCheckbox(EXAMPLE_URL + "code_blackboxing_one.js").click();
-  getBlackBoxCheckbox(EXAMPLE_URL + "code_blackboxing_two.js").click();
-  getBlackBoxCheckbox(EXAMPLE_URL + "code_blackboxing_three.js").click();
+  toggleBlackBoxing(gPanel, EXAMPLE_URL + "code_blackboxing_one.js");
+  toggleBlackBoxing(gPanel, EXAMPLE_URL + "code_blackboxing_two.js");
+  toggleBlackBoxing(gPanel, EXAMPLE_URL + "code_blackboxing_three.js");
   return finished;
 }
 
 function testBlackBoxStack() {
   let finished = waitForSourceAndCaretAndScopes(gPanel, ".html", 21).then(() => {
     is(gFrames.itemCount, 4,
       "Should get 4 frames (one -> two -> three -> doDebuggerStatement).");
     is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 3,
@@ -47,21 +47,15 @@ function testBlackBoxStack() {
   });
 
   // Spin the event loop before causing the debuggee to pause, to allow
   // this function to return first.
   executeSoon(() => gDebuggee.one());
   return finished;
 }
 
-function getBlackBoxCheckbox(aUrl) {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
-    ".side-menu-widget-item-checkbox");
-}
-
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
   gDebugger = null;
   gFrames = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-05.js
+++ b/browser/devtools/debugger/test/browser_dbg_blackboxing-05.js
@@ -16,59 +16,48 @@ function test() {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gDeck = gDebugger.document.getElementById("editor-deck");
 
     waitForSourceShown(gPanel, ".coffee")
       .then(testSourceEditorShown)
-      .then(blackBoxSource)
+      .then(toggleBlackBoxing.bind(null, gPanel))
       .then(testBlackBoxMessageShown)
       .then(clickStopBlackBoxingButton)
       .then(testSourceEditorShownAgain)
       .then(() => closeDebuggerAndFinish(gPanel))
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
   });
 }
 
 function testSourceEditorShown() {
   is(gDeck.selectedIndex, "0",
     "The first item in the deck should be selected (the source editor).");
 }
 
-function blackBoxSource() {
-  let finished = waitForThreadEvents(gPanel, "blackboxchange");
-  getAnyBlackBoxCheckbox().click();
-  return finished;
-}
-
 function testBlackBoxMessageShown() {
   is(gDeck.selectedIndex, "1",
     "The second item in the deck should be selected (the black box message).");
 }
 
 function clickStopBlackBoxingButton() {
   let finished = waitForThreadEvents(gPanel, "blackboxchange");
   getEditorBlackboxMessageButton().click();
   return finished;
 }
 
 function testSourceEditorShownAgain() {
   is(gDeck.selectedIndex, "0",
     "The first item in the deck should be selected again (the source editor).");
 }
 
-function getAnyBlackBoxCheckbox() {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item .side-menu-widget-item-checkbox");
-}
-
 function getEditorBlackboxMessageButton() {
   return gDebugger.document.getElementById("black-boxed-message-button");
 }
 
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-06.js
+++ b/browser/devtools/debugger/test/browser_dbg_blackboxing-06.js
@@ -1,56 +1,57 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Test that clicking the black box checkbox doesn't select that source.
+ * Test that clicking the black box checkbox when paused doesn't re-select the
+ * currently paused frame's source.
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
 
 let gTab, gDebuggee, gPanel, gDebugger;
 let gSources;
 
 function test() {
   initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gSources = gDebugger.DebuggerView.Sources;
 
-    waitForSourceShown(gPanel, ".js")
+    waitForSourceAndCaretAndScopes(gPanel, ".html", 21)
       .then(testBlackBox)
-      .then(() => closeDebuggerAndFinish(gPanel))
+      .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
       .then(null, aError => {
         ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
       });
+
+    gDebuggee.runTest();
   });
 }
 
 function testBlackBox() {
   const selectedUrl = gSources.selectedValue;
-  const checkbox = getDifferentBlackBoxCheckbox(selectedUrl);
-  ok(checkbox, "We should be able to grab a different checkbox.");
 
-  let finished = waitForThreadEvents(gPanel, "blackboxchange").then(() => {
-    is(selectedUrl, gSources.selectedValue,
-      "The same source should still be selected.");
+  let finished = waitForSourceShown(gPanel, "blackboxme.js").then(() => {
+    const newSelectedUrl = gSources.selectedValue;
+    isnot(selectedUrl, newSelectedUrl,
+      "Should not have the same url selected.");
+
+    return toggleBlackBoxing(gPanel).then(() => {
+      is(gSources.selectedValue, newSelectedUrl,
+        "The selected source did not change.");
+    });
   });
 
-  checkbox.click();
+  gSources.selectedIndex = 0;
   return finished;
 }
 
-function getDifferentBlackBoxCheckbox(aUrl) {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item:not([tooltiptext=\"" + aUrl + "\"]) " +
-    ".side-menu-widget-item-checkbox");
-}
-
 registerCleanupFunction(function() {
   gTab = null;
   gDebuggee = null;
   gPanel = null;
   gDebugger = null;
   gSources = null;
 });
deleted file mode 100644
--- a/browser/devtools/debugger/test/browser_dbg_blackboxing-07.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Test that clicking the black box checkbox when paused doesn't re-select the
- * currently paused frame's source.
- */
-
-const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
-
-let gTab, gDebuggee, gPanel, gDebugger;
-let gSources;
-
-function test() {
-  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
-    gTab = aTab;
-    gDebuggee = aDebuggee;
-    gPanel = aPanel;
-    gDebugger = gPanel.panelWin;
-    gSources = gDebugger.DebuggerView.Sources;
-
-    waitForSourceAndCaretAndScopes(gPanel, ".html", 21)
-      .then(testBlackBox)
-      .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
-      .then(null, aError => {
-        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
-      });
-
-    gDebuggee.runTest();
-  });
-}
-
-function testBlackBox() {
-  const selectedUrl = gSources.selectedValue;
-
-  let finished = waitForSourceShown(gPanel, "blackboxme.js").then(() => {
-    const newSelectedUrl = gSources.selectedValue;
-    isnot(selectedUrl, newSelectedUrl,
-      "Should not have the same url selected.");
-
-    let finished = waitForThreadEvents(gPanel, "blackboxchange").then(() => {
-      is(gSources.selectedValue, newSelectedUrl,
-        "The selected source did not change.");
-    });
-
-    getBlackBoxCheckbox(newSelectedUrl).click()
-    return finished;
-  });
-
-  gSources.selectedIndex = 0;
-  return finished;
-}
-
-function getBlackBoxCheckbox(aUrl) {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
-    ".side-menu-widget-item-checkbox");
-}
-
-registerCleanupFunction(function() {
-  gTab = null;
-  gDebuggee = null;
-  gPanel = null;
-  gDebugger = null;
-  gSources = null;
-});
--- a/browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
+++ b/browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
@@ -41,79 +41,105 @@ function setupGlobals(aToolbox) {
   gThreadClient = gDebugger.gThreadClient;
 }
 
 function waitForDebuggerSources() {
   return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
 }
 
 function testBlackBoxSource() {
-  return cmd("dbg blackbox " + BLACKBOXME_URL).then(() => {
-    const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
-    ok(!checkbox.checked,
-      "Should be able to black box a specific source.");
+  return Task.spawn(function* () {
+    yield cmd("dbg blackbox " + BLACKBOXME_URL);
+
+    let bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXME_URL);
+    ok(bbButton.checked,
+       "Should be able to black box a specific source.");
   });
 }
 
 function testUnBlackBoxSource() {
-  return cmd("dbg unblackbox " + BLACKBOXME_URL).then(() => {
-    const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
-    ok(checkbox.checked,
-      "Should be able to stop black boxing a specific source.");
+  return Task.spawn(function* () {
+    yield cmd("dbg unblackbox " + BLACKBOXME_URL);
+
+    let bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXME_URL);
+    ok(!bbButton.checked,
+       "Should be able to stop black boxing a specific source.");
   });
 }
 
 function testBlackBoxGlob() {
-  return cmd("dbg blackbox --glob *blackboxing_t*.js", 2,
-             [/blackboxing_three\.js/g, /blackboxing_two\.js/g]).then(() => {
-    ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
-      "blackboxme should not be black boxed because it doesn't match the glob.");
-    ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
-      "blackbox_one should not be black boxed because it doesn't match the glob.");
+  return Task.spawn(function* () {
+    yield cmd("dbg blackbox --glob *blackboxing_t*.js", 2,
+              [/blackboxing_three\.js/g, /blackboxing_two\.js/g]);
 
-    ok(!getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
-      "blackbox_two should be black boxed because it matches the glob.");
-    ok(!getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
+    let bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXME_URL);
+    ok(!bbButton.checked,
+       "blackboxme should not be black boxed because it doesn't match the glob.");
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXONE_URL);
+    ok(!bbButton.checked,
+       "blackbox_one should not be black boxed because it doesn't match the glob.");
+
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXTWO_URL);
+    ok(bbButton.checked,
+       "blackbox_two should be black boxed because it matches the glob.");
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXTHREE_URL);
+    ok(bbButton.checked,
       "blackbox_three should be black boxed because it matches the glob.");
   });
 }
 
 function testUnBlackBoxGlob() {
-  return cmd("dbg unblackbox --glob *blackboxing_t*.js", 2).then(() => {
-    ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
-      "blackbox_two should be un-black boxed because it matches the glob.");
-    ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
+  return Task.spawn(function* () {
+    yield cmd("dbg unblackbox --glob *blackboxing_t*.js", 2);
+
+    let bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXTWO_URL);
+    ok(!bbButton.checked,
+       "blackbox_two should be un-black boxed because it matches the glob.");
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXTHREE_URL);
+    ok(!bbButton.checked,
       "blackbox_three should be un-black boxed because it matches the glob.");
   });
 }
 
 function testBlackBoxInvert() {
-  return cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
-             [/blackboxing_three\.js/g, /blackboxing_two\.js/g]).then(() => {
-    ok(!getBlackBoxCheckbox(BLACKBOXME_URL).checked,
+  return Task.spawn(function* () {
+    yield cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
+              [/blackboxing_three\.js/g, /blackboxing_two\.js/g]);
+
+    let bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXME_URL);
+    ok(bbButton.checked,
       "blackboxme should be black boxed because it doesn't match the glob.");
-    ok(!getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXONE_URL);
+    ok(bbButton.checked,
       "blackbox_one should be black boxed because it doesn't match the glob.");
-    ok(!getBlackBoxCheckbox(TEST_URL).checked,
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, TEST_URL);
+    ok(bbButton.checked,
       "TEST_URL should be black boxed because it doesn't match the glob.");
 
-    ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXTWO_URL);
+    ok(!bbButton.checked,
       "blackbox_two should not be black boxed because it matches the glob.");
-    ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXTHREE_URL);
+    ok(!bbButton.checked,
       "blackbox_three should not be black boxed because it matches the glob.");
   });
 }
 
 function testUnBlackBoxInvert() {
-  return cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3).then(() => {
-    ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
+  return Task.spawn(function* () {
+    yield cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3);
+
+    let bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXME_URL);
+    ok(!bbButton.checked,
       "blackboxme should be un-black boxed because it does not match the glob.");
-    ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, BLACKBOXONE_URL);
+    ok(!bbButton.checked,
       "blackbox_one should be un-black boxed because it does not match the glob.");
-    ok(getBlackBoxCheckbox(TEST_URL).checked,
+    bbButton = yield selectSourceAndGetBlackBoxButton(gPanel, TEST_URL);
+    ok(!bbButton.checked,
       "TEST_URL should be un-black boxed because it doesn't match the glob.");
   });
 }
 
 registerCleanupFunction(function() {
   gOptions = null;
   gPanel = null;
   gDebugger = null;
@@ -121,14 +147,8 @@ registerCleanupFunction(function() {
 });
 
 function cmd(aTyped, aEventRepeat = 1, aOutput = "") {
   return promise.all([
     waitForThreadEvents(gPanel, "blackboxchange", aEventRepeat),
     helpers.audit(gOptions, [{ setup: aTyped, output: aOutput, exec: {} }])
   ]);
 }
-
-function getBlackBoxCheckbox(url) {
-  return gDebugger.document.querySelector(
-    ".side-menu-widget-item[tooltiptext=\"" + url + "\"] " +
-    ".side-menu-widget-item-checkbox");
-}
--- a/browser/devtools/debugger/test/browser_dbg_pretty-print-10.js
+++ b/browser/devtools/debugger/test/browser_dbg_pretty-print-10.js
@@ -17,38 +17,31 @@ function test() {
     gDebuggee = aDebuggee;
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gEditor = gDebugger.DebuggerView.editor;
     gSources = gDebugger.DebuggerView.Sources;
 
     waitForSourceShown(gPanel, "code_ugly.js")
       .then(testSourceIsUgly)
-      .then(blackBoxSource)
-      .then(waitForThreadEvents.bind(null, gPanel, "blackboxchange"))
+      .then(toggleBlackBoxing.bind(null, gPanel))
       .then(clickPrettyPrintButton)
       .then(testSourceIsStillUgly)
       .then(() => closeDebuggerAndFinish(gPanel))
       .then(null, aError => {
         ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
       });
   });
 }
 
 function testSourceIsUgly() {
   ok(!gEditor.getText().contains("\n    "),
      "The source shouldn't be pretty printed yet.");
 }
 
-function blackBoxSource() {
-  const checkbox = gDebugger.document.querySelector(
-    ".selected .side-menu-widget-item-checkbox");
-  checkbox.click();
-}
-
 function clickPrettyPrintButton() {
   gDebugger.document.getElementById("pretty-print").click();
 }
 
 function testSourceIsStillUgly() {
   const { source } = gSources.selectedItem.attachment;
   return gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
     ok(!text.contains("\n    "));
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -518,8 +518,34 @@ function closeDebuggerAndFinish(aPanel, 
 }
 
 function resumeDebuggerThenCloseAndFinish(aPanel, aFlags = {}) {
   let deferred = promise.defer();
   let thread = aPanel.panelWin.gThreadClient;
   thread.resume(() => closeDebuggerAndFinish(aPanel, aFlags).then(deferred.resolve));
   return deferred.promise;
 }
+
+function getBlackBoxButton(aPanel) {
+  return aPanel.panelWin.document.getElementById("black-box");
+}
+
+function toggleBlackBoxing(aPanel, aSource = null) {
+  function clickBlackBoxButton() {
+    getBlackBoxButton(aPanel).click();
+  }
+
+  const blackBoxChanged = waitForThreadEvents(aPanel, "blackboxchange");
+
+  if (aSource) {
+    aPanel.panelWin.DebuggerView.Sources.selectedValue = aSource;
+    ensureSourceIs(aPanel, aSource, true).then(clickBlackBoxButton);
+  } else {
+    clickBlackBoxButton();
+  }
+  return blackBoxChanged;
+}
+
+function selectSourceAndGetBlackBoxButton(aPanel, aSource) {
+  aPanel.panelWin.DebuggerView.Sources.selectedValue = aSource;
+  return ensureSourceIs(aPanel, aSource, true)
+    .then(getBlackBoxButton.bind(null, aPanel));
+}
--- a/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
@@ -28,18 +28,22 @@
   - the text displayed in the button to stop black boxing the currently selected
   - source. -->
 <!ENTITY debuggerUI.blackBoxMessage.unBlackBoxButton "Stop black boxing this source">
 
 <!-- LOCALIZATION NOTE (debuggerUI.optsButton.tooltip): This is the tooltip for
   -  the button that opens up an options context menu for the debugger UI. -->
 <!ENTITY debuggerUI.optsButton.tooltip  "Debugger Options">
 
+<!-- LOCALIZATION NOTE (debuggerUI.sources.blackBoxTooltip): This is the tooltip
+  -  for the button that black boxes the selected source. -->
+<!ENTITY debuggerUI.sources.blackBoxTooltip "Toggle Black Boxing">
+
 <!-- LOCALIZATION NOTE (debuggerUI.sources.prettyPrint): This is the tooltip for the
-button that pretty prints the selected source. -->
+  -  button that pretty prints the selected source. -->
 <!ENTITY debuggerUI.sources.prettyPrint "Prettify Source">
 
 <!-- LOCALIZATION NOTE (debuggerUI.pauseExceptions): This is the label for the
   -  checkbox that toggles pausing on exceptions. -->
 <!ENTITY debuggerUI.pauseExceptions     "Pause on exceptions">
 <!ENTITY debuggerUI.pauseExceptions.key "E">
 
 <!-- LOCALIZATION NOTE (debuggerUI.pauseExceptions): This is the label for the
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11a45b5d037853f7cfae2d266269382acb0cd558
GIT binary patch
literal 1005
zc$@+40}}j+P)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#k4Z#9RCwCV)mumuQ5XmCncbNkuj?$u
zqHB;^X@#wsiMk?0Jt$pK48!QX3zZK+1wGVb7bwc7u%Hmc&=4dlFhsgv)HD#%#Yk=2
z-E!TXy|~Wo?)3lMSrLnhdZ>lte0$FKJ9|9yof%eDRpwuQSiRBmZx`SV%>FT6W?A*u
z3*dg#>G<qSHi;R92+g!eeB2)=rrs9hua<vj(s%t&_3-Hk1tvbh9K2-PQXTv04!rIk
zOtu!TKhE=peS}dSq4)$$3NB$;o@?tL7`j?%D+~W<2Oe~H=;3qWv+-32AJx1bml*sf
z`0?HKjSCCWC4v{P-k6H5)>gfq+Z&b@Z%=RE`Mh;SjnpVcpTu!|L+R#C*W21Vla~G`
z_qy77_+oeqaupam>;N^2sSn-)U(|g0!ou$|KJ37urc;9JtM`V>6L{?O`1?A#A09?=
zu57*2RZ5Lw>Z38YC-B7Kp1z1aJryuDcpZEZd?j*h$jw22GOS3AV(OzY_)7To=!+i!
zn#kdrKI@(d^g6yu_c2M2wR~HCTW9x%8UO4{Y801LRTt10<$Uo5`X(H%qp&)f2)+Q`
zhOsi_RKTag7-6fZQ4F6(W0V7LgU=;PMaYFhvs@Z)2qIR{RFh~7DY7g?qA@S+5@N<A
zic}9&gmclD8kJ?mtQBzto`sK)rF{4(j2>QD<f$I$-pAlocwzoApcB%$N4<UHwR?7L
zOcDfvVVOu(MY*!Qw&9H$Q%9dYfBE?2nRE8ew%avn>1nH2hK>1rK4<mLx@$g33ebe`
zA@~e<9lQ#!!h7L^@E-Ueycs?Po`Ii({{SChw0kM;s6VjTKJmH5<?*+>XZ&}EM@H+i
z*Ay?emTfgtOno#)IW@KWOUP)J?j;W|VhnZQFF|f8OcuNWUZ9xzXpC~;Gsuu-rC^vb
zW#!RUW~?j7&u+eQY5Ur>`BuTei)?($c<gILRwB~an0=(_#OdzAq2USiOSJuo<4k$*
zN$_TPBRtQ>Z;1|nRConG0PlpK)vU@&q4^`tm@@NtTvE|QOID`w*pY)P@^W+NVZwf#
zoD8<yyfyWH)J`=)EimI8S6~*OL^@h@-g$TqJ_(-Fd;~rWuV{6as0U_Y0oo#H0)zGh
z6SN6gZM9T@lq}=NqgwuV4>oNfiN<REYN7zOrvB<>#A-jDcwj8Xzx|$BvVg_c|L1M^
bO@ILaIdut6%kstp00000NkvXXu0mjfrUB=;
--- a/browser/themes/linux/devtools/debugger.css
+++ b/browser/themes/linux/devtools/debugger.css
@@ -17,66 +17,39 @@
   -moz-border-start-color: transparent;
 }
 
 #pretty-print {
   min-width: 0;
   font-weight: bold;
 }
 
-#sources .side-menu-widget-item-checkbox {
-  -moz-appearance: none;
-  opacity: 0;
-  transition: opacity .15s ease 0s;
-}
-
-/* Only show the checkbox when the source is hovered over, is selected, or if it
- * is not checked. */
-#sources .side-menu-widget-item:hover > .side-menu-widget-item-checkbox,
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
-#sources .side-menu-widget-item-checkbox:not([checked]) {
-  opacity: 1;
-  transition: opacity .15s ease 0s;
-}
-
-#sources .side-menu-widget-item-checkbox > .checkbox-spacer-box {
-  -moz-appearance: none;
+#black-box {
+  list-style-image: url(debugger-blackbox.png);
+  -moz-image-region: rect(0px,16px,16px,0px);
 }
 
-#sources .side-menu-widget-item-checkbox > .checkbox-spacer-box > .checkbox-check {
-  -moz-appearance: none;
-  background: none;
-  background-image: url(itemToggle.png);
-  background-repeat: no-repeat;
-  background-clip: content-box;
-  background-size: 32px 16px;
-  background-position: -16px 0;
-  width: 16px;
-  height: 16px;
-  border: 0;
+#black-box[checked] {
+  -moz-image-region: rect(0px,32px,16px,16px);
 }
 
-#sources .side-menu-widget-item-checkbox[checked] > .checkbox-spacer-box > .checkbox-check {
-  background-position: 0 0;
-}
-
-#sources .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents {
+#sources .black-boxed {
   color: #888;
 }
 
-#sources .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents > .dbg-breakpoint {
+#sources .black-boxed > .dbg-breakpoint {
   display: none;
 }
 
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
+#sources .black-boxed + .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
   background-image: none;
   box-shadow: inset -1px 0 0 #222426;
 }
 
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
+#sources .black-boxed + .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
   background-image: none;
   box-shadow: inset 1px 0 0 #222426;
 }
 
 /* Black box message and source progress meter */
 
 #black-boxed-message,
 #source-progress-container {
@@ -397,30 +370,33 @@
 #step-in {
   list-style-image: url("chrome://browser/skin/devtools/debugger-step-in.png");
 }
 
 #step-out {
   list-style-image: url("chrome://browser/skin/devtools/debugger-step-out.png");
 }
 
-#debugger-controls > toolbarbutton {
+#debugger-controls > toolbarbutton,
+#sources-controls > toolbarbutton {
   margin: 0;
   box-shadow: none;
   border-radius: 0;
   border-width: 0;
   -moz-border-end-width: 1px;
   outline-offset: -3px;
 }
 
-#debugger-controls > toolbarbutton:last-of-type {
+#debugger-controls > toolbarbutton:last-of-type,
+#sources-controls > toolbarbutton:last-of-type {
   -moz-border-end-width: 0;
 }
 
-#debugger-controls {
+#debugger-controls,
+#sources-controls {
   box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset,
               0 0 0 1px hsla(210,16%,76%,.15) inset,
               0 1px 0 hsla(210,16%,76%,.15);
   border: 1px solid hsla(210,8%,5%,.45);
   border-radius: 3px;
   margin: 0 3px;
 }
 
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -190,16 +190,17 @@ browser.jar:
   skin/classic/browser/devtools/layoutview.css        (devtools/layoutview.css)
   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/debugger-blackbox.png  (devtools/debugger-blackbox.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-horizontal-resizer.png (devtools/responsive-horizontal-resizer.png)
   skin/classic/browser/devtools/responsive-background.png (devtools/responsive-background.png)
   skin/classic/browser/devtools/toggle-tools.png          (devtools/toggle-tools.png)
   skin/classic/browser/devtools/dock-bottom.png           (devtools/dock-bottom.png)
   skin/classic/browser/devtools/dock-side.png             (devtools/dock-side.png)
   skin/classic/browser/devtools/floating-scrollbars.css   (devtools/floating-scrollbars.css)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11a45b5d037853f7cfae2d266269382acb0cd558
GIT binary patch
literal 1005
zc$@+40}}j+P)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#k4Z#9RCwCV)mumuQ5XmCncbNkuj?$u
zqHB;^X@#wsiMk?0Jt$pK48!QX3zZK+1wGVb7bwc7u%Hmc&=4dlFhsgv)HD#%#Yk=2
z-E!TXy|~Wo?)3lMSrLnhdZ>lte0$FKJ9|9yof%eDRpwuQSiRBmZx`SV%>FT6W?A*u
z3*dg#>G<qSHi;R92+g!eeB2)=rrs9hua<vj(s%t&_3-Hk1tvbh9K2-PQXTv04!rIk
zOtu!TKhE=peS}dSq4)$$3NB$;o@?tL7`j?%D+~W<2Oe~H=;3qWv+-32AJx1bml*sf
z`0?HKjSCCWC4v{P-k6H5)>gfq+Z&b@Z%=RE`Mh;SjnpVcpTu!|L+R#C*W21Vla~G`
z_qy77_+oeqaupam>;N^2sSn-)U(|g0!ou$|KJ37urc;9JtM`V>6L{?O`1?A#A09?=
zu57*2RZ5Lw>Z38YC-B7Kp1z1aJryuDcpZEZd?j*h$jw22GOS3AV(OzY_)7To=!+i!
zn#kdrKI@(d^g6yu_c2M2wR~HCTW9x%8UO4{Y801LRTt10<$Uo5`X(H%qp&)f2)+Q`
zhOsi_RKTag7-6fZQ4F6(W0V7LgU=;PMaYFhvs@Z)2qIR{RFh~7DY7g?qA@S+5@N<A
zic}9&gmclD8kJ?mtQBzto`sK)rF{4(j2>QD<f$I$-pAlocwzoApcB%$N4<UHwR?7L
zOcDfvVVOu(MY*!Qw&9H$Q%9dYfBE?2nRE8ew%avn>1nH2hK>1rK4<mLx@$g33ebe`
zA@~e<9lQ#!!h7L^@E-Ueycs?Po`Ii({{SChw0kM;s6VjTKJmH5<?*+>XZ&}EM@H+i
z*Ay?emTfgtOno#)IW@KWOUP)J?j;W|VhnZQFF|f8OcuNWUZ9xzXpC~;Gsuu-rC^vb
zW#!RUW~?j7&u+eQY5Ur>`BuTei)?($c<gILRwB~an0=(_#OdzAq2USiOSJuo<4k$*
zN$_TPBRtQ>Z;1|nRConG0PlpK)vU@&q4^`tm@@NtTvE|QOID`w*pY)P@^W+NVZwf#
zoD8<yyfyWH)J`=)EimI8S6~*OL^@h@-g$TqJ_(-Fd;~rWuV{6as0U_Y0oo#H0)zGh
z6SN6gZM9T@lq}=NqgwuV4>oNfiN<REYN7zOrvB<>#A-jDcwj8Xzx|$BvVg_c|L1M^
bO@ILaIdut6%kstp00000NkvXXu0mjfrUB=;
--- a/browser/themes/osx/devtools/debugger.css
+++ b/browser/themes/osx/devtools/debugger.css
@@ -19,62 +19,39 @@
   -moz-border-start-color: transparent;
 }
 
 #pretty-print {
   min-width: 0;
   font-weight: bold;
 }
 
-#sources .side-menu-widget-item-checkbox {
-  -moz-appearance: none;
-  opacity: 0;
-  transition: opacity .15s ease-out 0s;
-}
-
-/* Only show the checkbox when the source is hovered over, is selected, or if it
- * is not checked. */
-#sources .side-menu-widget-item:hover > .side-menu-widget-item-checkbox,
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
-#sources .side-menu-widget-item-checkbox:not([checked]) {
-  opacity: 1;
-  transition: opacity .15s ease-out 0s;
+#black-box {
+  list-style-image: url(debugger-blackbox.png);
+  -moz-image-region: rect(0px,16px,16px,0px);
 }
 
-#sources .side-menu-widget-item-checkbox > .checkbox-check {
-  -moz-appearance: none;
-  background: none;
-  background-image: url(itemToggle.png);
-  background-repeat: no-repeat;
-  background-clip: content-box;
-  background-size: 32px 16px;
-  background-position: -16px 0;
-  width: 16px;
-  height: 16px;
-  border: 0;
+#black-box[checked] {
+  -moz-image-region: rect(0px,32px,16px,16px);
 }
 
-#sources .side-menu-widget-item-checkbox[checked] > .checkbox-check {
-  background-position: 0 0;
-}
-
-#sources .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents {
+#sources .black-boxed {
   color: #888;
 }
 
-#sources .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents > .dbg-breakpoint {
+#sources .black-boxed > .dbg-breakpoint {
   display: none;
 }
 
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
+#sources .black-boxed + .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
   background-image: none;
   box-shadow: inset -1px 0 0 #222426;
 }
 
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
+#sources .black-boxed + .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
   background-image: none;
   box-shadow: inset 1px 0 0 #222426;
 }
 
 /* Black box message and source progress meter */
 
 #black-boxed-message,
 #source-progress-container {
@@ -395,30 +372,33 @@
 #step-in {
   list-style-image: url("chrome://browser/skin/devtools/debugger-step-in.png");
 }
 
 #step-out {
   list-style-image: url("chrome://browser/skin/devtools/debugger-step-out.png");
 }
 
-#debugger-controls > toolbarbutton {
+#debugger-controls > toolbarbutton,
+#sources-controls > toolbarbutton {
   margin: 0;
   box-shadow: none;
   border-radius: 0;
   border-width: 0;
   -moz-border-end-width: 1px;
   outline-offset: -3px;
 }
 
-#debugger-controls > toolbarbutton:last-of-type {
+#debugger-controls > toolbarbutton:last-of-type,
+#sources-controls > toolbarbutton:last-of-type {
   -moz-border-end-width: 0;
 }
 
-#debugger-controls {
+#debugger-controls,
+#sources-controls {
   box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset,
               0 0 0 1px hsla(210,16%,76%,.15) inset,
               0 1px 0 hsla(210,16%,76%,.15);
   border: 1px solid hsla(210,8%,5%,.45);
   border-radius: @toolbarbuttonCornerRadius@;
   margin: 0 3px;
 }
 
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -282,16 +282,17 @@ browser.jar:
   skin/classic/browser/devtools/layoutview.css              (devtools/layoutview.css)
   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/debugger-blackbox.png       (devtools/debugger-blackbox.png)
   skin/classic/browser/devtools/floating-scrollbars.css     (devtools/floating-scrollbars.css)
   skin/classic/browser/devtools/floating-scrollbars-light.css (devtools/floating-scrollbars-light.css)
   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-horizontal-resizer.png (devtools/responsive-horizontal-resizer.png)
   skin/classic/browser/devtools/responsive-background.png   (devtools/responsive-background.png)
   skin/classic/browser/devtools/toggle-tools.png            (devtools/toggle-tools.png)
   skin/classic/browser/devtools/dock-bottom.png             (devtools/dock-bottom.png)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11a45b5d037853f7cfae2d266269382acb0cd558
GIT binary patch
literal 1005
zc$@+40}}j+P)<h;3K|Lk000e1NJLTq001BW000mO1^@s6cL04^0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#k4Z#9RCwCV)mumuQ5XmCncbNkuj?$u
zqHB;^X@#wsiMk?0Jt$pK48!QX3zZK+1wGVb7bwc7u%Hmc&=4dlFhsgv)HD#%#Yk=2
z-E!TXy|~Wo?)3lMSrLnhdZ>lte0$FKJ9|9yof%eDRpwuQSiRBmZx`SV%>FT6W?A*u
z3*dg#>G<qSHi;R92+g!eeB2)=rrs9hua<vj(s%t&_3-Hk1tvbh9K2-PQXTv04!rIk
zOtu!TKhE=peS}dSq4)$$3NB$;o@?tL7`j?%D+~W<2Oe~H=;3qWv+-32AJx1bml*sf
z`0?HKjSCCWC4v{P-k6H5)>gfq+Z&b@Z%=RE`Mh;SjnpVcpTu!|L+R#C*W21Vla~G`
z_qy77_+oeqaupam>;N^2sSn-)U(|g0!ou$|KJ37urc;9JtM`V>6L{?O`1?A#A09?=
zu57*2RZ5Lw>Z38YC-B7Kp1z1aJryuDcpZEZd?j*h$jw22GOS3AV(OzY_)7To=!+i!
zn#kdrKI@(d^g6yu_c2M2wR~HCTW9x%8UO4{Y801LRTt10<$Uo5`X(H%qp&)f2)+Q`
zhOsi_RKTag7-6fZQ4F6(W0V7LgU=;PMaYFhvs@Z)2qIR{RFh~7DY7g?qA@S+5@N<A
zic}9&gmclD8kJ?mtQBzto`sK)rF{4(j2>QD<f$I$-pAlocwzoApcB%$N4<UHwR?7L
zOcDfvVVOu(MY*!Qw&9H$Q%9dYfBE?2nRE8ew%avn>1nH2hK>1rK4<mLx@$g33ebe`
zA@~e<9lQ#!!h7L^@E-Ueycs?Po`Ii({{SChw0kM;s6VjTKJmH5<?*+>XZ&}EM@H+i
z*Ay?emTfgtOno#)IW@KWOUP)J?j;W|VhnZQFF|f8OcuNWUZ9xzXpC~;Gsuu-rC^vb
zW#!RUW~?j7&u+eQY5Ur>`BuTei)?($c<gILRwB~an0=(_#OdzAq2USiOSJuo<4k$*
zN$_TPBRtQ>Z;1|nRConG0PlpK)vU@&q4^`tm@@NtTvE|QOID`w*pY)P@^W+NVZwf#
zoD8<yyfyWH)J`=)EimI8S6~*OL^@h@-g$TqJ_(-Fd;~rWuV{6as0U_Y0oo#H0)zGh
z6SN6gZM9T@lq}=NqgwuV4>oNfiN<REYN7zOrvB<>#A-jDcwj8Xzx|$BvVg_c|L1M^
bO@ILaIdut6%kstp00000NkvXXu0mjfrUB=;
--- a/browser/themes/windows/devtools/debugger.css
+++ b/browser/themes/windows/devtools/debugger.css
@@ -17,64 +17,39 @@
   -moz-border-start-color: transparent;
 }
 
 #pretty-print {
   min-width: 0;
   font-weight: bold;
 }
 
-#sources .side-menu-widget-item-checkbox {
-  -moz-appearance: none;
-  -moz-margin-end: -6px;
-  padding: 0;
-  opacity: 0;
-  transition: opacity .15s ease 0s;
-}
-
-/* Only show the checkbox when the source is hovered over, is selected, or if it
- * is not checked. */
-#sources .side-menu-widget-item:hover > .side-menu-widget-item-checkbox,
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
-#sources .side-menu-widget-item-checkbox:not([checked]) {
-  opacity: 1;
-  transition: opacity .15s ease-out 0s;
+#black-box {
+  list-style-image: url(debugger-blackbox.png);
+  -moz-image-region: rect(0px,16px,16px,0px);
 }
 
-#sources .side-menu-widget-item-checkbox > .checkbox-check {
-  -moz-appearance: none;
-  background: none;
-  background-image: url(itemToggle.png);
-  background-repeat: no-repeat;
-  background-clip: content-box;
-  background-size: 32px 16px;
-  background-position: -16px 0;
-  width: 16px;
-  height: 16px;
-  border: 0;
+#black-box[checked] {
+  -moz-image-region: rect(0px,32px,16px,16px);
 }
 
-#sources .side-menu-widget-item-checkbox[checked] > .checkbox-check {
-  background-position: 0 0;
-}
-
-#sources .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents {
+#sources .black-boxed {
   color: #888;
 }
 
-#sources .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-contents > .dbg-breakpoint {
+#sources .black-boxed > .dbg-breakpoint {
   display: none;
 }
 
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
+#sources .black-boxed + .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
   background-image: none;
   box-shadow: inset -1px 0 0 #222426;
 }
 
-#sources .side-menu-widget-item.selected > .side-menu-widget-item-checkbox:not([checked]) ~ .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
+#sources .black-boxed + .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
   background-image: none;
   box-shadow: inset 1px 0 0 #222426;
 }
 
 /* Black box message and source progress meter */
 
 #black-boxed-message,
 #source-progress-container {
@@ -395,30 +370,33 @@
 #step-in {
   list-style-image: url("chrome://browser/skin/devtools/debugger-step-in.png");
 }
 
 #step-out {
   list-style-image: url("chrome://browser/skin/devtools/debugger-step-out.png");
 }
 
-#debugger-controls > toolbarbutton {
+#debugger-controls > toolbarbutton,
+#sources-controls > toolbarbutton {
   margin: 0;
   box-shadow: none;
   border-radius: 0;
   border-width: 0;
   -moz-border-end-width: 1px;
   outline-offset: -3px;
 }
 
-#debugger-controls > toolbarbutton:last-of-type {
+#debugger-controls > toolbarbutton:last-of-type,
+#sources-controls > toolbarbutton:last-of-type {
   -moz-border-end-width: 0;
 }
 
-#debugger-controls {
+#debugger-controls,
+#sources-controls {
   box-shadow: 0 1px 0 hsla(209,29%,72%,.15) inset,
               0 0 0 1px hsla(209,29%,72%,.1) inset,
               0 0 0 1px hsla(209,29%,72%,.1),
               0 1px 0 hsla(210,16%,76%,.1);
   border: 1px solid hsla(210,8%,5%,.45);
   border-radius: 3px;
   margin: 0 3px;
 }
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -217,16 +217,17 @@ browser.jar:
         skin/classic/browser/devtools/layoutview.css                (devtools/layoutview.css)
         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/debugger-blackbox.png         (devtools/debugger-blackbox.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-horizontal-resizer.png (devtools/responsive-horizontal-resizer.png)
         skin/classic/browser/devtools/responsive-background.png     (devtools/responsive-background.png)
         skin/classic/browser/devtools/toggle-tools.png              (devtools/toggle-tools.png)
         skin/classic/browser/devtools/dock-bottom.png               (devtools/dock-bottom.png)
         skin/classic/browser/devtools/dock-side.png                 (devtools/dock-side.png)
         skin/classic/browser/devtools/floating-scrollbars.css       (devtools/floating-scrollbars.css)
@@ -492,16 +493,17 @@ browser.jar:
         skin/classic/aero/browser/devtools/layoutview.css            (devtools/layoutview.css)
         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/debugger-blackbox.png     (devtools/debugger-blackbox.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-horizontal-resizer.png (devtools/responsive-horizontal-resizer.png)
         skin/classic/aero/browser/devtools/responsive-background.png (devtools/responsive-background.png)
         skin/classic/aero/browser/devtools/toggle-tools.png          (devtools/toggle-tools.png)
         skin/classic/aero/browser/devtools/dock-bottom.png           (devtools/dock-bottom.png)
         skin/classic/aero/browser/devtools/dock-side.png             (devtools/dock-side.png)
         skin/classic/aero/browser/devtools/floating-scrollbars.css   (devtools/floating-scrollbars.css)