merge m-c to fx-team
authorTim Taubert <ttaubert@mozilla.com>
Tue, 23 Apr 2013 18:56:19 +0200
changeset 140518 591caa6e37af1ad075bb2dbcc2101cbbfbb380c0
parent 140508 aa620f3fc2f7116e6fad91915cb273160a2f5f0a (current diff)
parent 140517 45829ebfd8f4d74e9275a33e2b60499334c53f85 (diff)
child 140527 424ddd76303b4d2fb7a5faf972d6714323c9e86c
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge m-c to fx-team
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
browser/devtools/webconsole/webconsole.xul
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1077,16 +1077,17 @@ pref("devtools.debugger.ui.variables-sea
 // Enable the Profiler
 pref("devtools.profiler.enabled", true);
 
 // Enable the Network Monitor
 pref("devtools.netmonitor.enabled", true);
 
 // The default Network Monitor UI settings
 pref("devtools.netmonitor.panes-network-details-width", 450);
+pref("devtools.netmonitor.panes-network-details-height", 450);
 
 // Enable the Tilt inspector
 pref("devtools.tilt.enabled", true);
 pref("devtools.tilt.intro_transition", true);
 pref("devtools.tilt.outro_transition", true);
 
 // Enable the Scratchpad tool.
 pref("devtools.scratchpad.enabled", true);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6761,18 +6761,20 @@ let gPrivateBrowsingUI = {
             newWindow.label = newPrivateWindow.label;
             newWindow.accessKey = newPrivateWindow.accessKey;
             newWindow.command = newPrivateWindow.command;
           }
         });
       }
     }
 
-    if (gURLBar) {
-      // Disable switch to tab autocompletion for private windows
+    if (gURLBar &&
+        !PrivateBrowsingUtils.permanentPrivateBrowsing) {
+      // Disable switch to tab autocompletion for private windows 
+      // (not for "Always use private browsing" mode)
       gURLBar.setAttribute("autocompletesearchparam", "");
     }
   }
 };
 
 
 /**
  * Switch to a tab that has a given URI, and focusses its browser window.
@@ -6785,19 +6787,20 @@ let gPrivateBrowsingUI = {
  *        True to open a new tab and switch to it, if no existing tab is found.
  *        If no suitable window is found, a new one will be opened.
  * @return True if an existing tab was found, false otherwise
  */
 function switchToTabHavingURI(aURI, aOpenNew) {
   // This will switch to the tab in aWindow having aURI, if present.
   function switchIfURIInWindow(aWindow) {
     // Only switch to the tab if neither the source and desination window are
-    // private.
-    if (PrivateBrowsingUtils.isWindowPrivate(window) ||
-        PrivateBrowsingUtils.isWindowPrivate(aWindow)) {
+    // private and they are not in permanent private borwsing mode
+    if ((PrivateBrowsingUtils.isWindowPrivate(window) ||
+        PrivateBrowsingUtils.isWindowPrivate(aWindow)) &&
+        !PrivateBrowsingUtils.permanentPrivateBrowsing) {
       return false;
     }
 
     let browsers = aWindow.gBrowser.browsers;
     for (let i = 0; i < browsers.length; i++) {
       let browser = browsers[i];
       if (browser.currentURI.equals(aURI)) {
         // Focus the matching window & tab
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -645,17 +645,18 @@
                 let autocomplete = this.mTabBrowser._placesAutocomplete;
                 if (this.mBrowser.registeredOpenURI) {
                   autocomplete.unregisterOpenPage(this.mBrowser.registeredOpenURI);
                   delete this.mBrowser.registeredOpenURI;
                 }
                 // Tabs in private windows aren't registered as "Open" so
                 // that they don't appear as switch-to-tab candidates.
                 if (!isBlankPageURL(aLocation.spec) &&
-                    !PrivateBrowsingUtils.isWindowPrivate(window)) {
+                    (!PrivateBrowsingUtils.isWindowPrivate(window) ||
+                    PrivateBrowsingUtils.permanentPrivateBrowsing)) {
                   autocomplete.registerOpenPage(aLocation);
                   this.mBrowser.registeredOpenURI = aLocation;
                 }
               }
 
               if (!this.mBlank) {
                 this._callProgressListeners("onLocationChange",
                                             [aWebProgress, aRequest, aLocation,
--- a/browser/devtools/commandline/gcli.jsm
+++ b/browser/devtools/commandline/gcli.jsm
@@ -7303,22 +7303,20 @@ Output.prototype.complete = function(dat
 };
 
 exports.Output = Output;
 
 /**
  * Functions and data related to the execution of a command
  */
 exports.createExecutionContext = function(requisition) {
-  return {
+  var context = {
     exec: requisition.exec.bind(requisition),
     update: requisition.update.bind(requisition),
     updateExec: requisition.updateExec.bind(requisition),
-    document: requisition.document,
-    environment: requisition.environment,
     createView: view.createView,
     typedData: function(data, type) {
       return {
         isTypedData: true,
         data: data,
         type: type
       };
     },
@@ -7329,16 +7327,28 @@ exports.createExecutionContext = functio
     /**
      * @deprecated Use defer() instead, which does the same thing, but is not
      * confusingly named
      */
     createPromise: function() {
       return Promise.defer();
     }
   };
+
+  Object.defineProperty(context, 'environment', {
+    get: function() { return requisition.environment; },
+    enumerable : true
+  });
+
+  Object.defineProperty(context, 'document', {
+    get: function() { return requisition.document; },
+    enumerable : true
+  });
+
+  return context;
 };
 
 
 });
 define("text!gcli/ui/intro.html", [], "\n" +
   "<div>\n" +
   "  <p>${l10n.introTextOpening2}</p>\n" +
   "\n" +
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-data.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-data.js
@@ -648,51 +648,51 @@ function testKeyboardAccessibility(callb
               is(gVariablesView.getFocusedItem().name, "someProp5",
                 "The someProp5 item should be focused now.");
 
               EventUtils.sendKey("DOWN", gDebugger);
               is(gVariablesView.getFocusedItem().name, "0",
                 "The 0 item should be focused now.");
 
               EventUtils.sendKey("END", gDebugger);
-              is(gVariablesView.getFocusedItem().name, "foo",
-                "The foo item should be focused now.");
+              is(gVariablesView.getFocusedItem().name, "bar",
+                "The bar item should be focused now.");
 
               EventUtils.sendKey("DOWN", gDebugger);
               is(gVariablesView.getFocusedItem().name, "bar",
-                "The bar item should be focused now.");
+                "The bar item should still be focused now.");
 
               EventUtils.sendKey("UP", gDebugger);
               is(gVariablesView.getFocusedItem().name, "foo",
                 "The foo item should be focused now.");
 
               EventUtils.sendKey("RIGHT", gDebugger);
               is(gVariablesView.getFocusedItem().name, "foo",
                 "The foo item should still be focused now.");
 
               EventUtils.sendKey("PAGE_DOWN", gDebugger);
-              is(gVariablesView.getFocusedItem().name, "foo",
-                "The foo item should still be focused now.");
+              is(gVariablesView.getFocusedItem().name, "bar",
+                "The bar item should be focused now.");
 
               EventUtils.sendKey("PAGE_UP", gDebugger);
+              is(gVariablesView.getFocusedItem().name, "someProp7",
+                "The someProp7 item should be focused now.");
+
+              EventUtils.sendKey("UP", gDebugger);
               is(gVariablesView.getFocusedItem().name, "__proto__",
                 "The __proto__ item should be focused now.");
 
               EventUtils.sendKey("UP", gDebugger);
               is(gVariablesView.getFocusedItem().name, "set",
                 "The set item should be focused now.");
 
               EventUtils.sendKey("UP", gDebugger);
               is(gVariablesView.getFocusedItem().name, "get",
                 "The get item should be focused now.");
 
-              EventUtils.sendKey("UP", gDebugger);
-              is(gVariablesView.getFocusedItem().name, "p8",
-                "The p8 item should be focused now.");
-
               EventUtils.sendKey("HOME", gDebugger);
               is(gVariablesView.getFocusedItem().name, "someProp0",
                 "The someProp0 item should be focused now.");
 
               EventUtils.sendKey("UP", gDebugger);
               is(gVariablesView.getFocusedItem().name, "someProp0",
                 "The someProp0 item should still be focused now.");
 
@@ -823,16 +823,28 @@ function testKeyboardAccessibility(callb
                 "The top-level __proto__ item should be expanded.");
 
               EventUtils.sendKey("LEFT", gDebugger);
               is(gVariablesView.getFocusedItem().name, "__proto__",
                 "The top-level __proto__ item should still be focused.");
               is(gVariablesView.getFocusedItem().expanded, false,
                 "The top-level __proto__ item should not be expanded.");
 
+              EventUtils.sendKey("END", gDebugger);
+              is(gVariablesView.getFocusedItem().name, "foo",
+                "The foo scope should be focused.");
+
+              EventUtils.sendKey("PAGE_UP", gDebugger);
+              is(gVariablesView.getFocusedItem().name, "__proto__",
+                "The __proto__ property should be focused.");
+
+              EventUtils.sendKey("PAGE_DOWN", gDebugger);
+              is(gVariablesView.getFocusedItem().name, "foo",
+                "The foo scope should be focused.");
+
               executeSoon(callback);
             });
           });
         });
       });
     });
   });
 }
--- a/browser/devtools/framework/Target.jsm
+++ b/browser/devtools/framework/Target.jsm
@@ -270,35 +270,41 @@ TabTarget.prototype = {
 
       this._client = new DebuggerClient(DebuggerServer.connectPipe());
       // A local TabTarget will never perform chrome debugging.
       this._chrome = false;
     }
 
     this._setupRemoteListeners();
 
-    if (this.isRemote) {
-      // In the remote debugging case, the protocol connection will have been
-      // already initialized in the connection screen code.
-      this._remote.resolve(null);
-    } else {
+    let attachTab = () => {
+      this._client.attachTab(this._form.actor, (aResponse, aTabClient) => {
+        if (!aTabClient) {
+          this._remote.reject("Unable to attach to the tab");
+          return;
+        }
+        this.threadActor = aResponse.threadActor;
+        this._remote.resolve(null);
+      });
+    };
+
+    if (this.isLocalTab) {
       this._client.connect((aType, aTraits) => {
         this._client.listTabs(aResponse => {
           this._form = aResponse.tabs[aResponse.selected];
-
-          this._client.attachTab(this._form.actor, (aResponse, aTabClient) => {
-            if (!aTabClient) {
-              this._remote.reject("Unable to attach to the tab");
-              return;
-            }
-            this.threadActor = aResponse.threadActor;
-            this._remote.resolve(null);
-          });
+          attachTab();
         });
       });
+    } else if (!this.chrome) {
+      // In the remote debugging case, the protocol connection will have been
+      // already initialized in the connection screen code.
+      attachTab();
+    } else {
+      // Remote chrome debugging doesn't need anything at this point.
+      this._remote.resolve(null);
     }
 
     return this._remote.promise;
   },
 
   /**
    * Listen to the different events.
    */
--- a/browser/devtools/netmonitor/netmonitor-controller.js
+++ b/browser/devtools/netmonitor/netmonitor-controller.js
@@ -510,17 +510,18 @@ NetworkEventsHandler.prototype = {
  * Localization convenience methods.
  */
 let L10N = new ViewHelpers.L10N(NET_STRINGS_URI);
 
 /**
  * Shortcuts for accessing various network monitor preferences.
  */
 let Prefs = new ViewHelpers.Prefs("devtools.netmonitor", {
-  networkDetailsWidth: ["Int", "panes-network-details-width"]
+  networkDetailsWidth: ["Int", "panes-network-details-width"],
+  networkDetailsHeight: ["Int", "panes-network-details-height"]
 });
 
 /**
  * Convenient way of emitting events from the panel window.
  */
 EventEmitter.decorate(this);
 
 /**
--- a/browser/devtools/netmonitor/netmonitor-view.js
+++ b/browser/devtools/netmonitor/netmonitor-view.js
@@ -2,16 +2,17 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const EPSILON = 0.001;
 const REQUESTS_REFRESH_RATE = 50; // ms
+const REQUESTS_HEADERS_SAFE_BOUNDS = 30; // px
 const REQUESTS_WATERFALL_SAFE_BOUNDS = 100; // px
 const REQUESTS_WATERFALL_BACKGROUND_PATTERN = [5, 250, 1000, 2000]; // ms
 const DEFAULT_HTTP_VERSION = "HTTP/1.1";
 const HEADERS_SIZE_DECIMALS = 3;
 const CONTENT_SIZE_DECIMALS = 2;
 const CONTENT_MIME_TYPE_ABBREVIATIONS = {
   "ecmascript": "js",
   "javascript": "js",
@@ -97,26 +98,28 @@ let NetMonitorView = {
 
     this._detailsPane = $("#details-pane");
     this._detailsPaneToggleButton = $("#details-pane-toggle");
 
     this._collapsePaneString = L10N.getStr("collapseDetailsPane");
     this._expandPaneString = L10N.getStr("expandDetailsPane");
 
     this._detailsPane.setAttribute("width", Prefs.networkDetailsWidth);
+    this._detailsPane.setAttribute("height", Prefs.networkDetailsHeight);
     this.toggleDetailsPane({ visible: false });
   },
 
   /**
    * Destroys the UI for all the displayed panes.
    */
   _destroyPanes: function DV__destroyPanes() {
     dumpn("Destroying the NetMonitorView panes");
 
     Prefs.networkDetailsWidth = this._detailsPane.getAttribute("width");
+    Prefs.networkDetailsHeight = this._detailsPane.getAttribute("height");
 
     this._detailsPane = null;
     this._detailsPaneToggleButton = null;
   },
 
   /**
    * Gets the visibility state of the network details pane.
    * @return boolean
@@ -587,16 +590,37 @@ create({ constructor: RequestsMenuView, 
    *        True if this container's width was changed.
    */
   _flushWaterfallViews: function NVRM__flushWaterfallViews(aReset) {
     // To avoid expensive operations like getBoundingClientRect(), the
     // waterfalls width is cached. However, in certain scenarios like when
     // the window is resized, this needs to be invalidated.
     if (aReset) {
       this._cachedWaterfallWidth = 0;
+
+      let table = $("#network-table");
+      let toolbar = $("#requests-menu-toolbar");
+      let columns = [
+        [".requests-menu-waterfall", "waterfall-overflows"],
+        [".requests-menu-size", "size-overflows"],
+        [".requests-menu-type", "type-overflows"],
+        [".requests-menu-domain", "domain-overflows"]
+      ];
+
+      // Flush headers.
+      columns.forEach(([, attribute]) => table.removeAttribute(attribute));
+      let availableWidth = toolbar.getBoundingClientRect().width;
+
+      // Hide overflowing columns.
+      columns.forEach(([className, attribute]) => {
+        let bounds = $(".requests-menu-header" + className).getBoundingClientRect();
+        if (bounds.right > availableWidth - REQUESTS_HEADERS_SAFE_BOUNDS) {
+          table.setAttribute(attribute, "");
+        }
+      });
     }
 
     // Determine the scaling to be applied to all the waterfalls so that
     // everything is visible at once. One millisecond == one unscaled pixel.
     let availableWidth = this._waterfallWidth - REQUESTS_WATERFALL_SAFE_BOUNDS;
     let longestWidth = this._lastRequestEndedMillis - this._firstRequestStartedMillis;
     let scale = Math.min(Math.max(availableWidth / longestWidth, EPSILON), 1);
 
--- a/browser/devtools/netmonitor/netmonitor.css
+++ b/browser/devtools/netmonitor/netmonitor.css
@@ -8,13 +8,41 @@
 }
 
 #timings-summary-blocked {
   display: none; /* This doesn't work yet. */
 }
 
 /* Responsive sidebar */
 @media (max-width: 700px) {
+  #toolbar-spacer,
   #details-pane-toggle,
+  #details-pane[pane-collapsed],
   .requests-menu-waterfall {
     display: none;
   }
 }
+
+@media (min-width: 701px) {
+  #network-table[waterfall-overflows] .requests-menu-waterfall {
+    display: none;
+  }
+
+  #network-table[size-overflows] .requests-menu-size {
+    display: none;
+  }
+
+  #network-table[type-overflows] .requests-menu-type {
+    display: none;
+  }
+
+  #network-table[domain-overflows] .requests-menu-domain {
+    display: none;
+  }
+
+  #network-table[type-overflows] .requests-menu-domain {
+    -moz-box-flex: 1;
+  }
+
+  #network-table[domain-overflows] .requests-menu-file {
+    -moz-box-flex: 1;
+  }
+}
--- a/browser/devtools/netmonitor/netmonitor.xul
+++ b/browser/devtools/netmonitor/netmonitor.xul
@@ -41,17 +41,17 @@
         <label id="requests-menu-size-label"
                class="plain requests-menu-header requests-menu-size"
                value="&netmonitorUI.toolbar.size;"
                crop="end"/>
         <label id="requests-menu-waterfall-label"
                class="plain requests-menu-header requests-menu-waterfall"
                value="&netmonitorUI.toolbar.waterfall;"
                crop="end"/>
-        <spacer flex="1"/>
+        <spacer id="toolbar-spacer" flex="1"/>
         <toolbarbutton id="details-pane-toggle"
                        class="devtools-toolbarbutton"
                        tooltiptext="&netmonitorUI.panesButton.tooltip;"
                        tabindex="0"/>
       </toolbar>
       <label class="plain requests-menu-empty-notice"
              value="&netmonitorUI.emptyNotice;"/>
       <vbox id="requests-menu-contents" flex="1">
--- a/browser/devtools/netmonitor/test/browser_net_prefs-reload.js
+++ b/browser/devtools/netmonitor/test/browser_net_prefs-reload.js
@@ -4,23 +4,30 @@
 /**
  * Tests if the prefs that should survive across tool reloads work.
  */
 
 function test() {
   initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => {
     info("Starting test... ");
 
+    // This test reopens the network monitor a bunch of times, for different
+    // hosts (bottom, side, window). This seems to be slow on debug builds.
+    requestLongerTimeout(2);
+
     let prefsToCheck = {
       networkDetailsWidth: {
         newValue: ~~(Math.random() * 200 + 100),
-        validate: () =>
-          ~~aMonitor._view._detailsPane.getAttribute("width"),
-        modifyFrontend: (aValue) =>
-          aMonitor._view._detailsPane.setAttribute("width", aValue)
+        validate: ($) => ~~$("#details-pane").getAttribute("width"),
+        modifyFrontend: ($, aValue) => $("#details-pane").setAttribute("width", aValue)
+      },
+      networkDetailsHeight: {
+        newValue: ~~(Math.random() * 300 + 100),
+        validate: ($) => ~~$("#details-pane").getAttribute("height"),
+        modifyFrontend: ($, aValue) => $("#details-pane").setAttribute("height", aValue)
       },
       /* add more prefs here... */
     };
 
     function storeFirstPrefValues() {
       info("Caching initial pref values.");
 
       for (let name in prefsToCheck) {
@@ -34,97 +41,177 @@ function test() {
 
       for (let name in prefsToCheck) {
         let currentValue = aMonitor.panelWin.Prefs[name];
         let firstValue = prefsToCheck[name].firstValue;
         let validate = prefsToCheck[name].validate;
 
         is(currentValue, firstValue,
           "Pref " + name + " should be equal to first value: " + firstValue);
-        is(currentValue, validate(),
+        is(currentValue, validate(aMonitor.panelWin.$),
           "Pref " + name + " should validate: " + currentValue);
       }
     }
 
     function modifyFrontend() {
       info("Modifying UI elements to the specified new values.");
 
       for (let name in prefsToCheck) {
         let currentValue = aMonitor.panelWin.Prefs[name];
         let firstValue = prefsToCheck[name].firstValue;
         let newValue = prefsToCheck[name].newValue;
         let validate = prefsToCheck[name].validate;
         let modifyFrontend = prefsToCheck[name].modifyFrontend;
 
-        modifyFrontend(newValue);
+        modifyFrontend(aMonitor.panelWin.$, newValue);
         info("Modified UI element affecting " + name + " to: " + newValue);
 
         is(currentValue, firstValue,
           "Pref " + name + " should still be equal to first value: " + firstValue);
         isnot(currentValue, newValue,
           "Pref " + name + " should't yet be equal to second value: " + newValue);
-        is(newValue, validate(),
+        is(newValue, validate(aMonitor.panelWin.$),
           "The UI element affecting " + name + " should validate: " + newValue);
       }
     }
 
     function validateNewPrefValues() {
       info("Invalidating old pref values to the modified UI elements.");
 
       for (let name in prefsToCheck) {
         let currentValue = aMonitor.panelWin.Prefs[name];
         let firstValue = prefsToCheck[name].firstValue;
         let newValue = prefsToCheck[name].newValue;
         let validate = prefsToCheck[name].validate;
-        let modifyFrontend = prefsToCheck[name].modifyFrontend;
 
         isnot(currentValue, firstValue,
           "Pref " + name + " should't be equal to first value: " + firstValue);
         is(currentValue, newValue,
           "Pref " + name + " should now be equal to second value: " + newValue);
-        is(newValue, validate(),
+        is(newValue, validate(aMonitor.panelWin.$),
           "The UI element affecting " + name + " should validate: " + newValue);
       }
     }
 
     function resetFrontend() {
       info("Resetting UI elements to the cached initial pref values.");
 
       for (let name in prefsToCheck) {
         let currentValue = aMonitor.panelWin.Prefs[name];
         let firstValue = prefsToCheck[name].firstValue;
         let newValue = prefsToCheck[name].newValue;
         let validate = prefsToCheck[name].validate;
         let modifyFrontend = prefsToCheck[name].modifyFrontend;
 
-        modifyFrontend(firstValue);
+        modifyFrontend(aMonitor.panelWin.$, firstValue);
         info("Modified UI element affecting " + name + " to: " + firstValue);
 
         isnot(currentValue, firstValue,
           "Pref " + name + " should't yet be equal to first value: " + firstValue);
         is(currentValue, newValue,
           "Pref " + name + " should still be equal to second value: " + newValue);
-        is(firstValue, validate(),
+        is(firstValue, validate(aMonitor.panelWin.$),
           "The UI element affecting " + name + " should validate: " + firstValue);
       }
     }
 
-    storeFirstPrefValues();
+    function testBottom() {
+      info("Testing prefs reload for a bottom host.");
+      storeFirstPrefValues();
+
+      // Validate and modify while toolbox is on the bottom.
+      validateFirstPrefValues();
+      modifyFrontend();
+
+      return restartNetMonitor(aMonitor)
+        .then(([,, aNewMonitor]) => {
+          aMonitor = aNewMonitor;
+
+          // Revalidate and reset frontend while toolbox is on the bottom.
+          validateNewPrefValues();
+          resetFrontend();
+
+          return restartNetMonitor(aMonitor);
+        })
+        .then(([,, aNewMonitor]) => {
+          aMonitor = aNewMonitor;
 
-    // Validate and modify.
-    validateFirstPrefValues();
-    modifyFrontend();
-    restartNetMonitor(aMonitor).then(([,, aNewMonitor]) => {
-      aMonitor = aNewMonitor;
+          // Revalidate.
+          validateFirstPrefValues();
+        });
+    }
+
+    function testSide() {
+      info("Moving toolbox to the side...");
+
+      return aMonitor._toolbox.switchHost(Toolbox.HostType.SIDE)
+        .then(() => {
+          info("Testing prefs reload for a side host.");
+          storeFirstPrefValues();
+
+          // Validate and modify frontend while toolbox is on the side.
+          validateFirstPrefValues();
+          modifyFrontend();
+
+          return restartNetMonitor(aMonitor);
+        })
+        .then(([,, aNewMonitor]) => {
+          aMonitor = aNewMonitor;
+
+          // Revalidate and reset frontend while toolbox is on the side.
+          validateNewPrefValues();
+          resetFrontend();
 
-      // Revalidate and reset.
-      validateNewPrefValues();
-      resetFrontend();
-      restartNetMonitor(aMonitor).then(([,, aNewMonitor]) => {
-        aMonitor = aNewMonitor;
+          return restartNetMonitor(aMonitor);
+        })
+        .then(([,, aNewMonitor]) => {
+          aMonitor = aNewMonitor;
+
+          // Revalidate.
+          validateFirstPrefValues();
+        });
+    }
+
+    function testWindow() {
+      info("Moving toolbox into a window...");
+
+      return aMonitor._toolbox.switchHost(Toolbox.HostType.WINDOW)
+        .then(() => {
+          info("Testing prefs reload for a window host.");
+          storeFirstPrefValues();
+
+          // Validate and modify frontend while toolbox is in a window.
+          validateFirstPrefValues();
+          modifyFrontend();
+
+          return restartNetMonitor(aMonitor);
+        })
+        .then(([,, aNewMonitor]) => {
+          aMonitor = aNewMonitor;
 
-        // Revalidate and finish.
-        validateFirstPrefValues();
-        teardown(aMonitor).then(finish);
-      });
-    });
+          // Revalidate and reset frontend while toolbox is in a window.
+          validateNewPrefValues();
+          resetFrontend();
+
+          return restartNetMonitor(aMonitor);
+        })
+        .then(([,, aNewMonitor]) => {
+          aMonitor = aNewMonitor;
+
+          // Revalidate.
+          validateFirstPrefValues();
+        });
+    }
+
+    function cleanupAndFinish() {
+      info("Moving toolbox back to the bottom...");
+
+      aMonitor._toolbox.switchHost(Toolbox.HostType.BOTTOM)
+        .then(() => teardown(aMonitor))
+        .then(finish);
+    }
+
+    testBottom()
+      .then(testSide)
+      .then(testWindow)
+      .then(cleanupAndFinish);
   });
 }
--- a/browser/devtools/netmonitor/test/head.js
+++ b/browser/devtools/netmonitor/test/head.js
@@ -2,16 +2,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 let { Promise } = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
 let { TargetFactory } = Cu.import("resource:///modules/devtools/Target.jsm", {});
+let { Toolbox } = Cu.import("resource:///modules/devtools/Toolbox.jsm", {});
 let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
 
 const EXAMPLE_URL = "http://example.com/browser/browser/devtools/netmonitor/test/";
 
 const SIMPLE_URL = EXAMPLE_URL + "html_simple-test-page.html";
 const NAVIGATE_URL = EXAMPLE_URL + "html_navigate-test-page.html";
 const CONTENT_TYPE_URL = EXAMPLE_URL + "html_content-type-test-page.html";
 const STATUS_CODES_URL = EXAMPLE_URL + "html_status-codes-test-page.html";
--- a/browser/devtools/shared/DeveloperToolbar.jsm
+++ b/browser/devtools/shared/DeveloperToolbar.jsm
@@ -501,17 +501,17 @@ DeveloperToolbar.prototype.destroy = fun
 {
   if (this._lastState == NOTIFICATIONS.HIDE) {
     return;
   }
 
   let tabbrowser = this._chromeWindow.getBrowser();
   tabbrowser.tabContainer.removeEventListener("TabSelect", this, false);
   tabbrowser.tabContainer.removeEventListener("TabClose", this, false);
-  tabbrowser.removeEventListener("load", this, true); 
+  tabbrowser.removeEventListener("load", this, true);
   tabbrowser.removeEventListener("beforeunload", this, true);
 
   Array.prototype.forEach.call(tabbrowser.tabs, this._stopErrorsCount, this);
 
   this.display.focusManager.removeMonitoredElement(this.outputPanel._frame);
   this.display.focusManager.removeMonitoredElement(this._element);
 
   this.display.onVisibilityChange.remove(this.outputPanel._visibilityChanged, this.outputPanel);
--- a/browser/devtools/shared/widgets/VariablesView.jsm
+++ b/browser/devtools/shared/widgets/VariablesView.jsm
@@ -47,16 +47,17 @@ const STR = Services.strings.createBundl
  * @param nsIDOMNode aParentNode
  *        The parent node to hold this view.
  * @param object aFlags [optional]
  *        An object contaning initialization options for this view.
  *        e.g. { lazyEmpty: true, searchEnabled: true ... }
  */
 this.VariablesView = function VariablesView(aParentNode, aFlags = {}) {
   this._store = new Map();
+  this._items = [];
   this._itemsByElement = new WeakMap();
   this._prevHierarchy = new Map();
   this._currHierarchy = new Map();
 
   this._parent = aParentNode;
   this._parent.classList.add("variables-view-container");
   this._appendEmptyNotice();
 
@@ -98,16 +99,17 @@ VariablesView.prototype = {
    *         The newly created Scope instance.
    */
   addScope: function VV_addScope(aName = "") {
     this._removeEmptyNotice();
     this._toggleSearchVisibility(true);
 
     let scope = new Scope(this, aName);
     this._store.set(scope.id, scope);
+    this._items.push(scope);
     this._currHierarchy.set(aName, scope);
     this._itemsByElement.set(scope._target, scope);
     scope.header = !!aName;
     return scope;
   },
 
   /**
    * Removes all items from this container.
@@ -130,16 +132,17 @@ VariablesView.prototype = {
     let list = this._list;
     let firstChild;
 
     while (firstChild = list.firstChild) {
       list.removeChild(firstChild);
     }
 
     this._store.clear();
+    this._items.length = 0;
     this._itemsByElement.clear();
 
     this._appendEmptyNotice();
     this._toggleSearchVisibility(false);
   },
 
   /**
    * Emptying this container and rebuilding it immediately afterwards would
@@ -156,16 +159,17 @@ VariablesView.prototype = {
    * @see VariablesView.empty
    * @see VariablesView.commitHierarchy
    */
   _emptySoon: function VV__emptySoon(aTimeout) {
     let prevList = this._list;
     let currList = this._list = this.document.createElement("scrollbox");
 
     this._store.clear();
+    this._items.length = 0;
     this._itemsByElement.clear();
 
     this._emptyTimeout = this.window.setTimeout(function() {
       this._emptyTimeout = null;
 
       prevList.removeEventListener("keypress", this._onViewKeyPress, false);
       currList.addEventListener("keypress", this._onViewKeyPress, false);
       currList.setAttribute("orient", "vertical");
@@ -524,74 +528,83 @@ VariablesView.prototype = {
       let match = scope._firstMatch;
       if (match) {
         match.expand();
       }
     }
   },
 
   /**
-   * Focuses the first visible variable or property in this container.
+   * Find the first item in the tree of visible items in this container that
+   * matches the predicate. Searches in visual order (the order seen by the
+   * user). Descends into each scope to check the scope and its children.
+   *
+   * @param function aPredicate
+   *        A function that returns true when a match is found.
+   * @return Scope | Variable | Property
+   *         The first visible scope, variable or property, or null if nothing
+   *         is found.
+   */
+  _findInVisibleItems: function VV__findInVisibleItems(aPredicate) {
+    for (let scope of this._items) {
+      let result = scope._findInVisibleItems(aPredicate);
+      if (result) {
+        return result;
+      }
+    }
+    return null;
+  },
+
+  /**
+   * Find the last item in the tree of visible items in this container that
+   * matches the predicate. Searches in reverse visual order (opposite of the
+   * order seen by the user). Descends into each scope to check the scope and
+   * its children.
+   *
+   * @param function aPredicate
+   *        A function that returns true when a match is found.
+   * @return Scope | Variable | Property
+   *         The last visible scope, variable or property, or null if nothing
+   *         is found.
+   */
+  _findInVisibleItemsReverse: function VV__findInVisibleItemsReverse(aPredicate) {
+    for (let i = this._items.length - 1; i >= 0; i--) {
+      let scope = this._items[i];
+      let result = scope._findInVisibleItemsReverse(aPredicate);
+      if (result) {
+        return result;
+      }
+    }
+    return null;
+  },
+
+  /**
+   * Focuses the first visible scope, variable, or property in this container.
    */
   focusFirstVisibleNode: function VV_focusFirstVisibleNode() {
-    let property, variable, scope;
-
-    for (let [, item] of this._currHierarchy) {
-      if (!item.focusable) {
-        continue;
-      }
-      if (item instanceof Property) {
-        property = item;
-        break;
-      } else if (item instanceof Variable) {
-        variable = item;
-        break;
-      } else if (item instanceof Scope) {
-        scope = item;
-        break;
-      }
-    }
-    if (scope) {
-      this._focusItem(scope);
-    } else if (variable) {
-      this._focusItem(variable);
-    } else if (property) {
-      this._focusItem(property);
+    let focusableItem = this._findInVisibleItems(item => item.focusable);
+
+    if (focusableItem) {
+      this._focusItem(focusableItem);
     }
     this._parent.scrollTop = 0;
     this._parent.scrollLeft = 0;
   },
 
   /**
-   * Focuses the last visible variable or property in this container.
+   * Focuses the last visible scope, variable, or property in this container.
    */
   focusLastVisibleNode: function VV_focusLastVisibleNode() {
-    let property, variable, scope;
-
-    for (let [, item] of this._currHierarchy) {
-      if (!item.focusable) {
-        continue;
-      }
-      if (item instanceof Property) {
-        property = item;
-      } else if (item instanceof Variable) {
-        variable = item;
-      } else if (item instanceof Scope) {
-        scope = item;
-      }
+    let focusableItem = this._findInVisibleItemsReverse(item => item.focusable);
+
+    if (focusableItem) {
+      this._focusItem(focusableItem);
     }
-    if (property && (!variable || property.isDescendantOf(variable))) {
-      this._focusItem(property);
-    } else if (variable && (!scope || variable.isDescendantOf(scope))) {
-      this._focusItem(variable);
-    } else if (scope) {
-      this._focusItem(scope);
-      this._parent.scrollTop = this._parent.scrollHeight;
-      this._parent.scrollLeft = 0;
-    }
+    this._parent.scrollTop = this._parent.scrollHeight;
+    this._parent.scrollLeft = 0;
   },
 
   /**
    * Searches for the scope in this container displayed by the specified node.
    *
    * @param nsIDOMNode aNode
    *        The node to search for.
    * @return Scope
@@ -883,16 +896,17 @@ VariablesView.prototype = {
    * @return nsIDOMWindow
    */
   get window() this._window || (this._window = this.document.defaultView),
 
   _document: null,
   _window: null,
 
   _store: null,
+  _items: null,
   _prevHierarchy: null,
   _currHierarchy: null,
   _enumVisible: true,
   _nonEnumVisible: true,
   _emptyTimeout: null,
   _searchTimeout: null,
   _searchFunction: null,
   _parent: null,
@@ -1077,16 +1091,18 @@ function Scope(aView, aName, aFlags = {}
   this.editableNameTooltip = aView.editableNameTooltip;
   this.editButtonTooltip = aView.editButtonTooltip;
   this.deleteButtonTooltip = aView.deleteButtonTooltip;
   this.descriptorTooltip = aView.descriptorTooltip;
   this.contextMenuId = aView.contextMenuId;
   this.separatorStr = aView.separatorStr;
 
   this._store = new Map();
+  this._enumItems = [];
+  this._nonEnumItems = [];
   this._init(aName.trim(), aFlags);
 }
 
 Scope.prototype = {
   /**
    * Adds a variable to contain any inspected properties.
    *
    * @param string aName
@@ -1781,16 +1797,99 @@ Scope.prototype = {
       if (match) {
         return match;
       }
     }
     return null;
   },
 
   /**
+   * Find the first item in the tree of visible items in this item that matches
+   * the predicate. Searches in visual order (the order seen by the user).
+   * Tests itself, then descends into first the enumerable children and then
+   * the non-enumerable children (since they are presented in separate groups).
+   *
+   * @param function aPredicate
+   *        A function that returns true when a match is found.
+   * @return Scope | Variable | Property
+   *         The first visible scope, variable or property, or null if nothing
+   *         is found.
+   */
+  _findInVisibleItems: function S__findInVisibleItems(aPredicate) {
+    if (aPredicate(this)) {
+      return this;
+    }
+
+    if (this._isExpanded) {
+      if (this._variablesView._enumVisible) {
+        for (let item of this._enumItems) {
+          let result = item._findInVisibleItems(aPredicate);
+          if (result) {
+            return result;
+          }
+        }
+      }
+
+      if (this._variablesView._nonEnumVisible) {
+        for (let item of this._nonEnumItems) {
+          let result = item._findInVisibleItems(aPredicate);
+          if (result) {
+            return result;
+          }
+        }
+      }
+    }
+
+    return null;
+  },
+
+  /**
+   * Find the last item in the tree of visible items in this item that matches
+   * the predicate. Searches in reverse visual order (opposite of the order
+   * seen by the user). Descends into first the non-enumerable children, then
+   * the enumerable children (since they are presented in separate groups), and
+   * finally tests itself.
+   *
+   * @param function aPredicate
+   *        A function that returns true when a match is found.
+   * @return Scope | Variable | Property
+   *         The last visible scope, variable or property, or null if nothing
+   *         is found.
+   */
+  _findInVisibleItemsReverse: function S__findInVisibleItemsReverse(aPredicate) {
+    if (this._isExpanded) {
+      if (this._variablesView._nonEnumVisible) {
+        for (let i = this._nonEnumItems.length - 1; i >= 0; i--) {
+          let item = this._nonEnumItems[i];
+          let result = item._findInVisibleItemsReverse(aPredicate);
+          if (result) {
+            return result;
+          }
+        }
+      }
+
+      if (this._variablesView._enumVisible) {
+        for (let i = this._enumItems.length - 1; i >= 0; i--) {
+          let item = this._enumItems[i];
+          let result = item._findInVisibleItemsReverse(aPredicate);
+          if (result) {
+            return result;
+          }
+        }
+      }
+    }
+
+    if (aPredicate(this)) {
+      return this;
+    }
+
+    return null;
+  },
+
+  /**
    * Gets top level variables view instance.
    * @return VariablesView
    */
   get _variablesView() this._topView || (this._topView = (function(self) {
     let parentView = self.ownerView;
     let topView;
 
     while (topView = parentView.ownerView) {
@@ -1849,17 +1948,19 @@ Scope.prototype = {
   _isMatch: true,
   _idString: "",
   _nameString: "",
   _target: null,
   _arrow: null,
   _name: null,
   _title: null,
   _enum: null,
+  _enumItems: null,
   _nonenum: null,
+  _nonEnumItems: null,
   _throbber: null
 };
 
 /**
  * A Variable is a Scope holding Property instances.
  * Iterable via "for (let [name, property] in instance) { }".
  *
  * @param Scope aScope
@@ -2162,18 +2263,20 @@ ViewHelpers.create({ constructor: Variab
    * @param boolean aImmediateFlag
    *        @see Scope.prototype._lazyAppend
    */
   _onInit: function V__onInit(aImmediateFlag) {
     if (this._initialDescriptor.enumerable ||
         this._nameString == "this" ||
         this._nameString == "<exception>") {
       this.ownerView._lazyAppend(aImmediateFlag, true, this._target);
+      this.ownerView._enumItems.push(this);
     } else {
       this.ownerView._lazyAppend(aImmediateFlag, false, this._target);
+      this.ownerView._nonEnumItems.push(this);
     }
   },
 
   /**
    * Creates the necessary nodes for this variable.
    */
   _displayVariable: function V__createVariable() {
     let document = this.document;
@@ -2669,18 +2772,20 @@ ViewHelpers.create({ constructor: Proper
    * be attached to the owner view.
    *
    * @param boolean aImmediateFlag
    *        @see Scope.prototype._lazyAppend
    */
   _onInit: function P__onInit(aImmediateFlag) {
     if (this._initialDescriptor.enumerable) {
       this.ownerView._lazyAppend(aImmediateFlag, true, this._target);
+      this.ownerView._enumItems.push(this);
     } else {
       this.ownerView._lazyAppend(aImmediateFlag, false, this._target);
+      this.ownerView._nonEnumItems.push(this);
     }
   }
 });
 
 /**
  * A generator-iterator over the VariablesView, Scopes, Variables and Properties.
  */
 VariablesView.prototype.__iterator__ =
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -658,19 +658,29 @@ var HeadsUpDisplayUICommands = {
 
       if (!DebuggerServer.initialized) {
         DebuggerServer.init();
         DebuggerServer.addBrowserActors();
       }
 
       let client = new DebuggerClient(DebuggerServer.connectPipe());
       client.connect(() =>
-        client.listTabs((aResponse) =>
-          deferred.resolve({ form: aResponse, client: client })
-        ));
+        client.listTabs((aResponse) => {
+          // Add Global Process debugging...
+          let globals = JSON.parse(JSON.stringify(aResponse));
+          delete globals.tabs;
+          delete globals.selected;
+          // ...only if there are appropriate actors (a 'from' property will
+          // always be there).
+          if (Object.keys(globals).length > 1) {
+            deferred.resolve({ form: globals, client: client, chrome: true });
+          } else {
+            deferred.reject("Global console not found!");
+          }
+        }));
 
       return deferred.promise;
     }
 
     let target;
     function getTarget(aConnection)
     {
       let options = {
--- a/browser/devtools/webconsole/webconsole.xul
+++ b/browser/devtools/webconsole/webconsole.xul
@@ -57,18 +57,18 @@
       <menuitem id="saveBodiesContextMenu" type="checkbox" label="&saveBodies.label;"
                 accesskey="&saveBodies.accesskey;"/>
       <menuitem id="menu_openURL" label="&openURL.label;"
                 accesskey="&openURL.accesskey;" command="consoleCmd_openURL"
                 selection="network" selectionType="single"/>
       <menuitem id="menu_copyURL" label="&copyURLCmd.label;"
                 accesskey="&copyURLCmd.accesskey;" command="consoleCmd_copyURL"
                 selection="network" selectionType="single"/>
-      <menuitem id="menu_copy"/>
-      <menuitem id="menu_selectAll"/>
+      <menuitem id="cMenu_copy"/>
+      <menuitem id="cMenu_selectAll"/>
     </menupopup>
   </popupset>
 
   <box class="hud-outer-wrapper devtools-responsive-container" flex="1">
     <vbox class="hud-console-wrapper" flex="1">
       <toolbar class="hud-console-filter-toolbar devtools-toolbar" mode="full">
         <toolbarbutton label="&btnPageNet.label;" type="menu-button"
                        category="net" class="devtools-toolbarbutton webconsole-filter-button"
--- a/browser/themes/linux/devtools/netmonitor.css
+++ b/browser/themes/linux/devtools/netmonitor.css
@@ -88,21 +88,23 @@
 }
 
 .requests-menu-method {
   text-align: center;
   font-weight: 600;
 }
 
 .requests-menu-file {
-  width: 14em;
+  width: 20vw;
+  min-width: 4em;
 }
 
 .requests-menu-domain {
-  width: 14em;
+  width: 14vw;
+  min-width: 10em;
 }
 
 .requests-menu-type {
   text-align: center;
   width: 4em;
 }
 
 .requests-menu-size {
@@ -298,18 +300,49 @@
   transition: transform 0.2s ease-out;
 }
 
 /* Responsive sidebar */
 @media (max-width: 700px) {
   #details-pane {
     max-width: none;
     margin: 0 !important;
-    /* To prevent all the margin hacks to hide the sidebar */
+    /* To prevent all the margin hacks to hide the sidebar. */
+  }
+
+  .requests-menu-status-and-method {
+    width: 14vw;
+  }
+
+  .requests-menu-file,
+  .requests-menu-domain {
+    width: 30vw;
+    min-width: 10em;
+  }
+
+  .requests-menu-type {
+    width: 8vw;
   }
 
   .requests-menu-size {
-    border-width: 0px !important;
+    width: 16vw;
+    border-width: 0 !important;
     box-shadow: none !important;
-    /* !important are required here because Timeline is not visible and thus
-       the right border and box-shadow of Size column should be hidden */
+    /* The "Timeline" header is not visible anymore, and thus the
+       right border and box-shadow of "Size" column should be hidden. */
   }
 }
+
+@media (min-width: 701px) {
+  #network-table[type-overflows] .requests-menu-domain {
+    border-width: 0 !important;
+    box-shadow: none !important;
+    /* The "Type" header is not visible anymore, and thus the
+       right border and box-shadow of "Domain" column should be hidden. */
+  }
+
+  #network-table[domain-overflows] .requests-menu-file {
+    border-width: 0 !important;
+    box-shadow: none !important;
+    /* The "Domain" header is not visible anymore, and thus the
+       right border and box-shadow of "File" column should be hidden. */
+  }
+}
--- a/browser/themes/osx/devtools/netmonitor.css
+++ b/browser/themes/osx/devtools/netmonitor.css
@@ -88,21 +88,23 @@
 }
 
 .requests-menu-method {
   text-align: center;
   font-weight: 600;
 }
 
 .requests-menu-file {
-  width: 16em;
+  width: 20vw;
+  min-width: 4em;
 }
 
 .requests-menu-domain {
-  width: 16em;
+  width: 14vw;
+  min-width: 10em;
 }
 
 .requests-menu-type {
   text-align: center;
   width: 4em;
 }
 
 .requests-menu-size {
@@ -298,18 +300,49 @@
   transition: transform 0.2s ease-out;
 }
 
 /* Responsive sidebar */
 @media (max-width: 700px) {
   #details-pane {
     max-width: none;
     margin: 0 !important;
-    /* To prevent all the margin hacks to hide the sidebar */
+    /* To prevent all the margin hacks to hide the sidebar. */
+  }
+
+  .requests-menu-status-and-method {
+    width: 14vw;
+  }
+
+  .requests-menu-file,
+  .requests-menu-domain {
+    width: 30vw;
+    min-width: 10em;
+  }
+
+  .requests-menu-type {
+    width: 8vw;
   }
 
   .requests-menu-size {
-    border-width: 0px !important;
+    width: 16vw;
+    border-width: 0 !important;
     box-shadow: none !important;
-    /* !important are required here because Timeline is not visible and thus
-       the right border and box-shadow of Size column should be hidden */
+    /* The "Timeline" header is not visible anymore, and thus the
+       right border and box-shadow of "Size" column should be hidden. */
   }
 }
+
+@media (min-width: 701px) {
+  #network-table[type-overflows] .requests-menu-domain {
+    border-width: 0 !important;
+    box-shadow: none !important;
+    /* The "Type" header is not visible anymore, and thus the
+       right border and box-shadow of "Domain" column should be hidden. */
+  }
+
+  #network-table[domain-overflows] .requests-menu-file {
+    border-width: 0 !important;
+    box-shadow: none !important;
+    /* The "Domain" header is not visible anymore, and thus the
+       right border and box-shadow of "File" column should be hidden. */
+  }
+}
--- a/browser/themes/windows/devtools/netmonitor.css
+++ b/browser/themes/windows/devtools/netmonitor.css
@@ -88,21 +88,23 @@
 }
 
 .requests-menu-method {
   text-align: center;
   font-weight: 600;
 }
 
 .requests-menu-file {
-  width: 16em;
+  width: 20vw;
+  min-width: 4em;
 }
 
 .requests-menu-domain {
-  width: 16em;
+  width: 14vw;
+  min-width: 10em;
 }
 
 .requests-menu-type {
   text-align: center;
   width: 4em;
 }
 
 .requests-menu-size {
@@ -298,18 +300,49 @@
   transition: transform 0.2s ease-out;
 }
 
 /* Responsive sidebar */
 @media (max-width: 700px) {
   #details-pane {
     max-width: none;
     margin: 0 !important;
-    /* To prevent all the margin hacks to hide the sidebar */
+    /* To prevent all the margin hacks to hide the sidebar. */
+  }
+
+  .requests-menu-status-and-method {
+    width: 14vw;
+  }
+
+  .requests-menu-file,
+  .requests-menu-domain {
+    width: 30vw;
+    min-width: 10em;
+  }
+
+  .requests-menu-type {
+    width: 8vw;
   }
 
   .requests-menu-size {
-    border-width: 0px !important;
+    width: 16vw;
+    border-width: 0 !important;
     box-shadow: none !important;
-    /* !important are required here because Timeline is not visible and thus
-       the right border and box-shadow of Size column should be hidden */
+    /* The "Timeline" header is not visible anymore, and thus the
+       right border and box-shadow of "Size" column should be hidden. */
   }
 }
+
+@media (min-width: 701px) {
+  #network-table[type-overflows] .requests-menu-domain {
+    border-width: 0 !important;
+    box-shadow: none !important;
+    /* The "Type" header is not visible anymore, and thus the
+       right border and box-shadow of "Domain" column should be hidden. */
+  }
+
+  #network-table[domain-overflows] .requests-menu-file {
+    border-width: 0 !important;
+    box-shadow: none !important;
+    /* The "Domain" header is not visible anymore, and thus the
+       right border and box-shadow of "File" column should be hidden. */
+  }
+}
--- a/toolkit/devtools/debugger/server/dbg-script-actors.js
+++ b/toolkit/devtools/debugger/server/dbg-script-actors.js
@@ -592,35 +592,41 @@ ThreadActor.prototype = {
    * take that into account.
    *
    * @param object aLocation
    *        The location of the breakpoint as specified in the protocol.
    */
   _setBreakpoint: function TA__setBreakpoint(aLocation) {
     let breakpoints = this._breakpointStore[aLocation.url];
 
+    // Get or create the breakpoint actor for the given location
     let actor;
     if (breakpoints[aLocation.line].actor) {
       actor = breakpoints[aLocation.line].actor;
     } else {
       actor = breakpoints[aLocation.line].actor = new BreakpointActor(this, {
         url: aLocation.url,
         line: aLocation.line
       });
       this._hooks.addToParentPool(actor);
     }
 
+    // Find all scripts matching the given location
     let scripts = this.dbg.findScripts(aLocation);
     if (scripts.length == 0) {
       return {
         error: "noScript",
         actor: actor.actorID
       };
     }
 
+   /**
+     * For each script, if the given line has at least one entry point, set
+     * breakpoint on the bytecode offet for each of them.
+     */
     let found = false;
     for (let script of scripts) {
       let offsets = script.getLineOffsets(aLocation.line);
       if (offsets.length > 0) {
         for (let offset of offsets) {
           script.setBreakpoint(offset, actor);
         }
         actor.addScript(script, this);
@@ -628,65 +634,93 @@ ThreadActor.prototype = {
       }
     }
     if (found) {
       return {
         actor: actor.actorID
       };
     }
 
+   /**
+     * If we get here, no breakpoint was set. This is because the given line
+     * has no entry points, for example because it is empty. As a fallback
+     * strategy, we try to set the breakpoint on the smallest line greater
+     * than or equal to the given line that as at least one entry point.
+     */
+
+    // Find all innermost scripts matching the given location
     let scripts = this.dbg.findScripts({
       url: aLocation.url,
       line: aLocation.line,
       innermost: true
     });
 
+    /**
+     * For each innermost script, look for the smallest line greater than or
+     * equal to the given line that has one or more entry points. If found, set
+     * a breakpoint on the bytecode offset for each of its entry points.
+     */
     let actualLocation;
     let found = false;
     for (let script of scripts) {
       let offsets = script.getAllOffsets();
       for (let line = aLocation.line; line < offsets.length; ++line) {
         if (offsets[line]) {
           for (let offset of offsets[line]) {
             script.setBreakpoint(offset, actor);
           }
           actor.addScript(script, this);
           if (!actualLocation) {
             actualLocation = {
               url: aLocation.url,
               line: line,
-              column: aLocation.column
+              column: 0
             };
           }
           found = true;
           break;
         }
       }
     }
     if (found) {
       if (breakpoints[actualLocation.line] &&
           breakpoints[actualLocation.line].actor) {
+        /**
+         * We already have a breakpoint actor for the actual location, so
+         * actor we created earlier is now redundant. Delete it, update the
+         * breakpoint store, and return the actor for the actual location.
+         */
         actor.onDelete();
         delete breakpoints[aLocation.line];
         return {
           actor: breakpoints[actualLocation.line].actor.actorID,
           actualLocation: actualLocation
         };
       } else {
+        /**
+         * We don't have a breakpoint actor for the actual location yet.
+         * Instead or creating a new actor, reuse the actor we created earlier,
+         * and update the breakpoint store.
+         */
         actor.location = actualLocation;
         breakpoints[actualLocation.line] = breakpoints[aLocation.line];
+        delete breakpoints[aLocation.line];
+        // WARNING: This overwrites aLocation.line
         breakpoints[actualLocation.line].line = actualLocation.line;
-        delete breakpoints[aLocation.line];
         return {
           actor: actor.actorID,
           actualLocation: actualLocation
         };
       }
     }
 
+    /**
+     * If we get here, no line matching the given line was found, so just
+     * epically.
+     */
     return {
       error: "noCodeAtLineColumn",
       actor: actor.actorID
     };
   },
 
   /**
    * Get the script and source lists from the debugger.
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -97,17 +97,17 @@ function initialize(event) {
     return;
   }
 
   // Default to the last selected category
   var view = gCategories.node.value;
 
   // Allow passing in a view through the window arguments
   if ("arguments" in window && window.arguments.length > 0 &&
-      "view" in window.arguments[0]) {
+      window.arguments[0] !== null && "view" in window.arguments[0]) {
     view = window.arguments[0].view;
   }
 
   gViewController.loadInitialView(view);
 }
 
 function notifyInitialized() {
   if (!gIsInitializing)