merge m-c to fx-team
authorTim Taubert <ttaubert@mozilla.com>
Wed, 10 Oct 2012 09:32:35 +0200
changeset 109786 ec10630b1a5406c28d1ac84bd314938374404d04
parent 109780 5cca0408a73f5eddbf4eff3de318e73c99a57102 (current diff)
parent 109785 61e0ba0e9165dff3226e34581c9ab97e822091d9 (diff)
child 109787 2a0e2af364bc635500fc8fe7129b217119c5ff03
child 109856 4bfeb954d6d2a750f2cb473960e03cd00dc13165
child 110125 a8f4069538a6a93d0d82565bb808811e8a3835e2
child 110980 69307b7191e55e70dab3d5ebb01f71dbe12b7796
push id23653
push userttaubert@mozilla.com
push dateWed, 10 Oct 2012 07:33:01 +0000
treeherdermozilla-central@ec10630b1a54 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone19.0a1
first release with
nightly linux32
ec10630b1a54 / 19.0a1 / 20121010030605 / files
nightly linux64
ec10630b1a54 / 19.0a1 / 20121010030605 / files
nightly mac
ec10630b1a54 / 19.0a1 / 20121010030605 / files
nightly win32
ec10630b1a54 / 19.0a1 / 20121010030605 / files
nightly win64
ec10630b1a54 / 19.0a1 / 20121010030605 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge m-c to fx-team
b2g/chrome/content/forms.js
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -95,16 +95,17 @@ let FormAssistant = {
           this.setFocusedElement(target);
         }
         break;
 
       case "blur":
         if (this.focusedElement) {
           sendAsyncMessage("Forms:Input", { "type": "blur" });
           this.setFocusedElement(null);
+          this.isKeyboardOpened = false;
         }
         break;
 
       case 'mousedown':
         // We only listen for this event on the currently focused element.
         // When the mouse goes down, note the cursor/selection position
         this.selectionStart = this.focusedElement.selectionStart;
         this.selectionEnd = this.focusedElement.selectionEnd;
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1030,16 +1030,17 @@ pref("devtools.debugger.remote-timeout",
 // The default Debugger UI settings
 pref("devtools.debugger.ui.height", 250);
 pref("devtools.debugger.ui.remote-win.width", 900);
 pref("devtools.debugger.ui.remote-win.height", 400);
 pref("devtools.debugger.ui.stackframes-width", 200);
 pref("devtools.debugger.ui.stackframes-pane-visible", true);
 pref("devtools.debugger.ui.variables-width", 300);
 pref("devtools.debugger.ui.variables-pane-visible", true);
+pref("devtools.debugger.ui.non-enum-visible", true);
 
 // Enable the style inspector
 pref("devtools.styleinspector.enabled", true);
 
 // Enable the Tilt inspector
 pref("devtools.tilt.enabled", true);
 pref("devtools.tilt.intro_transition", true);
 pref("devtools.tilt.outro_transition", true);
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -1458,17 +1458,28 @@ Breakpoints.prototype = {
   _onEditorBreakpointAdd: function BP__onEditorBreakpointAdd(aBreakpoint) {
     let url = DebuggerView.Scripts.selected;
     if (!url) {
       return;
     }
 
     let line = aBreakpoint.line + 1;
 
-    this.addBreakpoint({ url: url, line: line }, null, true);
+    this.addBreakpoint({ url: url, line: line }, function (aBp) {
+      if (aBp.requestedLocation) {
+        this.editor.removeBreakpoint(aBp.requestedLocation.line - 1);
+
+        let breakpoints = this.getBreakpoints(url, aBp.location.line);
+        if (breakpoints.length > 1) {
+          this.removeBreakpoint(breakpoints[0], null, true, true);
+        } else {
+          this.updateEditorBreakpoints();
+        }
+      }
+    }.bind(this), true);
   },
 
   /**
    * Event handler for breakpoints that are removed from the editor.
    *
    * @private
    * @param object aBreakpoint
    *        The breakpoint object that was removed from the editor.
@@ -1550,16 +1561,28 @@ Breakpoints.prototype = {
   function BP_addBreakpoint(aLocation, aCallback, aNoEditorUpdate, aNoPaneUpdate) {
     let breakpoint = this.getBreakpoint(aLocation.url, aLocation.line);
     if (breakpoint) {
       aCallback && aCallback(breakpoint);
       return;
     }
 
     this.activeThread.setBreakpoint(aLocation, function(aResponse, aBpClient) {
+      let loc = aResponse.actualLocation;
+
+      if (loc) {
+        aBpClient.requestedLocation = {
+          line: aBpClient.location.line,
+          url: aBpClient.location.url
+        };
+
+        aBpClient.location.line = loc.line;
+        aBpClient.location.url = loc.url;
+      }
+
       this.store[aBpClient.actor] = aBpClient;
       this.displayBreakpoint(aBpClient, aNoEditorUpdate, aNoPaneUpdate);
       aCallback && aCallback(aBpClient, aResponse.error);
     }.bind(this));
   },
 
   /**
    * Update the editor to display the specified breakpoint in the gutter.
@@ -1650,16 +1673,28 @@ Breakpoints.prototype = {
    */
   getBreakpoint: function BP_getBreakpoint(aUrl, aLine) {
     for each (let breakpoint in this.store) {
       if (breakpoint.location.url == aUrl && breakpoint.location.line == aLine) {
         return breakpoint;
       }
     }
     return null;
+  },
+
+  getBreakpoints: function BP_getBreakpoints(aUrl, aLine) {
+    let breakpoints = [];
+
+    for each (let breakpoint in this.store) {
+      if (breakpoint.location.url == aUrl && breakpoint.location.line == aLine) {
+        breakpoints.push(breakpoint);
+      }
+    }
+
+    return breakpoints;
   }
 };
 
 /**
  * Localization convenience methods.
  */
 let L10N = {
 
@@ -1693,16 +1728,17 @@ const STACKFRAMES_WIDTH = "devtools.debu
 const STACKFRAMES_VISIBLE = "devtools.debugger.ui.stackframes-pane-visible";
 const VARIABLES_WIDTH = "devtools.debugger.ui.variables-width";
 const VARIABLES_PANE_VISIBLE = "devtools.debugger.ui.variables-pane-visible";
 const REMOTE_AUTO_CONNECT = "devtools.debugger.remote-autoconnect";
 const REMOTE_HOST = "devtools.debugger.remote-host";
 const REMOTE_PORT = "devtools.debugger.remote-port";
 const REMOTE_CONNECTION_RETRIES = "devtools.debugger.remote-connection-retries";
 const REMOTE_TIMEOUT = "devtools.debugger.remote-timeout";
+const NON_ENUM_VISIBLE = "devtools.debugger.ui.non-enum-visible";
 
 /**
  * Shortcuts for accessing various debugger preferences.
  */
 let Prefs = {
 
   /**
    * Gets the preferred stackframes pane width.
@@ -1780,35 +1816,57 @@ let Prefs = {
    * @param boolean value
    */
   set variablesPaneVisible(value) {
     Services.prefs.setBoolPref(VARIABLES_PANE_VISIBLE, value);
     this._variablesVisible = value;
   },
 
   /**
-   * Gets a flag specifying if the the debugger should automatically connect to
+   * Gets a flag specifying if the debugger should automatically connect to
    * the default host and port number.
    * @return boolean
    */
   get remoteAutoConnect() {
     if (this._autoConnect === undefined) {
       this._autoConnect = Services.prefs.getBoolPref(REMOTE_AUTO_CONNECT);
     }
     return this._autoConnect;
   },
 
   /**
-   * Sets a flag specifying if the the debugger should automatically connect to
+   * Sets a flag specifying if the debugger should automatically connect to
    * the default host and port number.
    * @param boolean value
    */
   set remoteAutoConnect(value) {
     Services.prefs.setBoolPref(REMOTE_AUTO_CONNECT, value);
     this._autoConnect = value;
+  },
+
+  /**
+   * Gets a flag specifying if the debugger should show non-enumerable
+   * properties and variables in the scope view.
+   * @return boolean
+   */
+  get nonEnumVisible() {
+    if (this._nonEnumVisible === undefined) {
+      this._nonEnumVisible = Services.prefs.getBoolPref(NON_ENUM_VISIBLE);
+    }
+    return this._nonEnumVisible;
+  },
+
+  /**
+   * Sets a flag specifying if the debugger should show non-enumerable
+   * properties and variables in the scope view.
+   * @param boolean value
+   */
+  set nonEnumVisible(value) {
+    Services.prefs.setBoolPref(NON_ENUM_VISIBLE, value);
+    this._nonEnumVisible = value;
   }
 };
 
 /**
  * Gets the preferred default remote debugging host.
  * @return string
  */
 XPCOMUtils.defineLazyGetter(Prefs, "remoteHost", function() {
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -2102,17 +2102,17 @@ BreakpointsView.prototype = {
    * @param boolean aNoCheckboxUpdate
    *        Pass true to not update the checkbox checked state.
    *        This is usually necessary when the checked state will be updated
    *        automatically (e.g: on a checkbox click).
    */
   enableBreakpoint:
   function DVB_enableBreakpoint(aTarget, aCallback, aNoCheckboxUpdate) {
     let { breakpointUrl: url, breakpointLine: line } = aTarget;
-    let breakpoint = DebuggerController.Breakpoints.getBreakpoint(url, line)
+    let breakpoint = DebuggerController.Breakpoints.getBreakpoint(url, line);
 
     if (!breakpoint) {
       if (!aNoCheckboxUpdate) {
         aTarget.getElementsByTagName("checkbox")[0].setAttribute("checked", "true");
       }
       DebuggerController.Breakpoints.
         addBreakpoint({ url: url, line: line }, aCallback);
 
@@ -2580,19 +2580,26 @@ PropertiesView.prototype = {
     // Make sure the scope container exists.
     if (!aScope) {
       return null;
     }
 
     // Compute the id of the element if not specified.
     aId = aId || (aScope.id + "->" + aName + "-variable");
 
+    let parent;
+    if (aFlags && !aFlags.enumerable) {
+      parent = aScope.childNodes[2];
+    }
+    else {
+      parent = aScope.childNodes[1];
+    }
+
     // Contains generic nodes and functionality.
-    let element = this._createPropertyElement(aName, aId, "variable",
-                                              aScope.getElementsByClassName("details")[0]);
+    let element = this._createPropertyElement(aName, aId, "variable", parent);
 
     // Make sure the element was created successfully.
     if (!element) {
       return null;
     }
     element._identifier = aName;
 
     /**
@@ -2784,16 +2791,17 @@ PropertiesView.prototype = {
         // contained in 'get' and 'set' properties.
         let getter = desc["get"];
         let setter = desc["set"];
 
         // Handle data property and accessor property descriptors.
         if (value !== undefined) {
           this._addProperty(aVar, [i, value], desc);
         }
+
         if (getter !== undefined || setter !== undefined) {
           let prop = this._addProperty(aVar, [i]).expand();
           prop.getter = this._addProperty(prop, ["get", getter], desc);
           prop.setter = this._addProperty(prop, ["set", setter], desc);
         }
       }
     }
     return aVar;
@@ -2829,19 +2837,26 @@ PropertiesView.prototype = {
     // Make sure the variable container exists.
     if (!aVar) {
       return null;
     }
 
     // Compute the id of the element if not specified.
     aId = aId || (aVar.id + "->" + aProperty[0] + "-property");
 
+    let parent;
+    if (aFlags && !aFlags.enumerable) {
+      parent = aVar.childNodes[2];
+    }
+    else {
+      parent = aVar.childNodes[1];
+    }
+
     // Contains generic nodes and functionality.
-    let element = this._createPropertyElement(aName, aId, "property",
-                                              aVar.getElementsByClassName("details")[0]);
+    let element = this._createPropertyElement(aName, aId, "property", parent);
 
     // Make sure the element was created successfully.
     if (!element) {
       return null;
     }
     element._identifier = aName;
 
     /**
@@ -3107,16 +3122,17 @@ PropertiesView.prototype = {
     }
 
     let element = document.createElement("vbox");
     let arrow = document.createElement("box");
     let name = document.createElement("label");
 
     let title = document.createElement("box");
     let details = document.createElement("vbox");
+    let nonEnum = document.createElement("vbox");
 
     // Create a scope node to contain all the elements.
     element.id = aId;
     element.className = aClass;
 
     // The expand/collapse arrow.
     arrow.className = "arrow";
     arrow.style.visibility = "hidden";
@@ -3126,31 +3142,33 @@ PropertiesView.prototype = {
     name.setAttribute("value", aName || "");
 
     // The title element, containing the arrow and the name.
     title.className = "title";
     title.setAttribute("align", "center")
 
     // The node element which will contain any added scope variables.
     details.className = "details";
+    nonEnum.className = "details nonenum";
 
     // Add the click event handler for the title, or arrow and name.
     if (aClass === "scope") {
       title.addEventListener("click", function() element.toggle(), false);
     } else {
       arrow.addEventListener("click", function() element.toggle(), false);
       name.addEventListener("click", function() element.toggle(), false);
       name.addEventListener("mouseover", function() element.updateTooltip(name), false);
     }
 
     title.appendChild(arrow);
     title.appendChild(name);
 
     element.appendChild(title);
     element.appendChild(details);
+    element.appendChild(nonEnum);
 
     aParent.appendChild(element);
 
     /**
      * Shows the element, setting the display style to "block".
      * @return object
      *         The same element.
      */
@@ -3187,37 +3205,47 @@ PropertiesView.prototype = {
      */
     element.expand = function DVP_element_expand(aSkipAnimationFlag) {
       if (element._preventExpand) {
         return;
       }
       arrow.setAttribute("open", "");
       details.setAttribute("open", "");
 
+      if (Prefs.nonEnumVisible) {
+        nonEnum.setAttribute("open", "");
+      }
+
       if (!aSkipAnimationFlag) {
         details.setAttribute("animated", "");
+        nonEnum.setAttribute("animated", "");
       }
+
       if ("function" === typeof element.onexpand) {
         element.onexpand(element);
       }
+
       return element;
     };
 
     /**
      * Collapses the element, hiding all the added details.
      * @return object
      *         The same element.
      */
     element.collapse = function DVP_element_collapse() {
       if (element._preventCollapse) {
         return;
       }
+
       arrow.removeAttribute("open");
       details.removeAttribute("open");
       details.removeAttribute("animated");
+      nonEnum.removeAttribute("open");
+      nonEnum.removeAttribute("animated");
 
       if ("function" === typeof element.oncollapse) {
         element.oncollapse(element);
       }
       return element;
     };
 
     /**
@@ -3235,19 +3263,22 @@ PropertiesView.prototype = {
     };
 
     /**
      * Shows the element expand/collapse arrow (only if necessary!).
      * @return object
      *         The same element.
      */
     element.showArrow = function DVP_element_showArrow() {
-      if (element._forceShowArrow || details.childNodes.length) {
+      let len = details.childNodes.length + nonEnum.childNodes.length;
+
+      if (element._forceShowArrow || len) {
         arrow.style.visibility = "visible";
       }
+
       return element;
     };
 
     /**
      * Hides the element expand/collapse arrow.
      * @return object
      *         The same element.
      */
@@ -3322,23 +3353,29 @@ PropertiesView.prototype = {
     /**
      * Removes all added children in the details container tree.
      * @return object
      *         The same element.
      */
     element.empty = function DVP_element_empty() {
       // This details node won't have any elements, so hide the arrow.
       arrow.style.visibility = "hidden";
+
       while (details.firstChild) {
         details.removeChild(details.firstChild);
       }
 
+      while (nonEnum.firstChild) {
+        nonEnum.removeChild(nonEnum.firstChild);
+      }
+
       if ("function" === typeof element.onempty) {
         element.onempty(element);
       }
+
       return element;
     };
 
     /**
      * Removes the element from the parent node details container tree.
      * @return object
      *         The same element.
      */
@@ -3426,17 +3463,17 @@ PropertiesView.prototype = {
      */
     element.refresh = function DVP_element_refresh(aFunction, aArguments) {
       if ("function" === typeof aFunction) {
         aFunction.apply(this, aArguments);
       }
 
       let node = aParent.parentNode;
       let arrow = node.getElementsByClassName("arrow")[0];
-      let children = node.getElementsByClassName("details")[0].childNodes.length;
+      let children = node.querySelectorAll(".details > vbox").length;
 
       // If the parent details node has at least one element, set the
       // expand/collapse arrow visible.
       if (children) {
         arrow.style.visibility = "visible";
       } else {
         arrow.style.visibility = "hidden";
       }
@@ -3544,20 +3581,41 @@ PropertiesView.prototype = {
   _currHierarchy: null,
   _prevHierarchy: null,
 
   /**
    * The cached variable properties container.
    */
   _vars: null,
 
+  _onShowNonEnums: function DVP__onShowNonEnums() {
+    let option = document.getElementById("show-nonenum");
+    Prefs.nonEnumVisible = option.checked;
+
+    let els = document.getElementsByClassName("nonenum").iterator();
+    for (let el of els) {
+      if (el.parentNode.expanded) {
+        if (Prefs.nonEnumVisible) {
+          el.setAttribute("open", "");
+        } else {
+          el.removeAttribute("open");
+          el.removeAttribute("animated");
+        }
+      }
+    }
+  },
+
   /**
    * Initialization function, called when the debugger is initialized.
    */
   initialize: function DVP_initialize() {
+    let showNonEnums = document.getElementById("show-nonenum");
+    showNonEnums.addEventListener("click", this._onShowNonEnums, false);
+    showNonEnums.checked = Prefs.nonEnumVisible;
+
     this._vars = DebuggerView._variables;
 
     this.emptyText();
     this.createHierarchyStore();
   },
 
   /**
    * Destruction function, called when the debugger is shut down.
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -85,16 +85,20 @@
       <menulist id="scripts" class="devtools-menulist"
                 sizetopopup="always"/>
       <textbox id="scripts-search" type="search"
                class="devtools-searchinput"/>
       <checkbox id="pause-exceptions"
                 type="checkbox"
                 tabindex="0"
                 label="&debuggerUI.pauseExceptions;"/>
+      <checkbox id="show-nonenum"
+                type="checkbox"
+                tabindex="0"
+                label="&debuggerUI.showNonEnums;"/>
       <spacer flex="1"/>
 #ifndef XP_MACOSX
       <toolbarbutton id="close"
                      tooltiptext="&debuggerUI.closeButton.tooltip;"
                      class="devtools-closebutton"/>
 #endif
     </toolbar>
     <panel id="scripts-search-panel"
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -58,23 +58,25 @@ MOCHITEST_BROWSER_TESTS = \
 	browser_dbg_scripts-searching-popup.js \
 	browser_dbg_pause-resume.js \
 	browser_dbg_update-editor-mode.js \
 	$(warning browser_dbg_select-line.js temporarily disabled due to oranges, see bug 726609) \
 	browser_dbg_clean-exit.js \
 	browser_dbg_bug723069_editor-breakpoints.js \
 	browser_dbg_bug723071_editor-breakpoints-pane.js \
 	browser_dbg_bug731394_editor-contextmenu.js \
+	browser_dbg_bug786070_hide_nonenums.js \
 	browser_dbg_displayName.js \
 	browser_dbg_iframes.js \
 	browser_dbg_pause-exceptions.js \
 	browser_dbg_multiple-windows.js \
 	browser_dbg_menustatus.js \
 	browser_dbg_bfcache.js \
 	browser_dbg_breakpoint-new-script.js \
+	browser_dbg_bug737803_editor_actual_location.js \
 	head.js \
 	$(NULL)
 
 # Disabled on Windows for frequent intermittent failures
 ifneq ($(OS_ARCH), WINNT)
 MOCHITEST_BROWSER_TESTS += \
 	browser_dbg_createRemote.js \
 	$(NULL)
--- a/browser/devtools/debugger/test/browser_dbg_bug723071_editor-breakpoints-pane.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723071_editor-breakpoints-pane.js
@@ -155,27 +155,27 @@ function test()
     }, true);
 
     function addBreakpoints(callback, increment)
     {
       let line;
 
       executeSoon(function()
       {
-        line = 4;
+        line = 6;
         gPane.addBreakpoint({url: gScripts.selected, line: line},
           function(cl, err) {
           onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
 
-          line = 5;
+          line = 7;
           gPane.addBreakpoint({url: gScripts.selected, line: line},
             function(cl, err) {
             onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
 
-            line = 6;
+            line = 8;
             gPane.addBreakpoint({url: gScripts.selected, line: line},
               function(cl, err) {
               onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
 
               executeSoon(function() {
                 callback();
               });
             });
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_bug737803_editor_actual_location.js
@@ -0,0 +1,109 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Bug 737803: Setting a breakpoint in a line without code should move
+ * the icon to the actual location.
+ */
+
+const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
+
+let gPane = null;
+let gTab = null;
+let gDebuggee = null;
+let gDebugger = null;
+let gScripts = null;
+let gEditor = null;
+let gBreakpoints = null;
+
+function test() {
+  let tempScope = {};
+  Cu.import("resource:///modules/source-editor.jsm", tempScope);
+  let SourceEditor = tempScope.SourceEditor;
+
+  let scriptShown = false;
+  let framesAdded = false;
+  let testStarted = false;
+  let resumed = false;
+
+  debug_tab_pane(TAB_URL, function (aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gPane = aPane;
+    gDebuggee = aDebuggee;
+    gDebugger = gPane.contentWindow;
+    resumed = true;
+
+    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function () {
+      framesAdded = true;
+      executeSoon(startTest);
+    });
+
+    executeSoon(function () {
+      gDebuggee.firstCall();
+    });
+  });
+
+  function onScriptShown(aEvent) {
+    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
+    executeSoon(startTest);
+  }
+
+  window.addEventListener("Debugger:ScriptShown", onScriptShown);
+
+  function startTest() {
+    if (scriptShown && framesAdded && resumed && !testStarted) {
+      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
+      testStarted = true;
+      Services.tm.currentThread.dispatch({ run: performTest }, 0);
+    }
+  }
+
+  function performTest() {
+    gScripts = gDebugger.DebuggerView.Scripts;
+    gEditor = gDebugger.editor;
+    gBreakpoints = gPane.breakpoints;
+    is(Object.keys(gBreakpoints), 0, "There are no breakpoints");
+
+    gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
+      onEditorBreakpointAdd);
+
+    let location = { url: gScripts.selected, line: 4 };
+    executeSoon(function () {
+      gPane.addBreakpoint(location, onBreakpointAdd);
+    });
+  }
+
+  function onBreakpointAdd(aBpClient) {
+    is(aBpClient.location.url, gScripts.selected, "URL is the same");
+    is(aBpClient.location.line, 6, "Line number is new");
+    is(aBpClient.requestedLocation.line, 4, "Requested location is correct");
+  }
+
+  function onEditorBreakpointAdd(aEvent) {
+    gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
+      onEditorBreakpointAdd);
+
+    is(gEditor.getBreakpoints().length, 1,
+      "There is only one breakpoint in the editor");
+
+    ok(!gPane.getBreakpoint(gScripts.selected, 4),
+      "There are no breakpoints on an invalid line");
+
+    let br = gPane.getBreakpoint(gScripts.selected, 6);
+    is(br.location.url, gScripts.selected, "URL is correct");
+    is(br.location.line, 6, "Line number is correct");
+
+    closeDebuggerAndFinish();
+  }
+
+  registerCleanupFunction(function () {
+    removeTab(gTab);
+    gPane = null;
+    gTab = null;
+    gDebuggee = null;
+    gDebugger = null;
+    gScripts = null;
+    gEditor = null;
+    gBreakpoints = null;
+  });
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_bug786070_hide_nonenums.js
@@ -0,0 +1,107 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+var gPane = null;
+var gTab = null;
+var gDebuggee = null;
+var gDebugger = null;
+
+function test() {
+  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPane = aPane;
+    gDebugger = gPane.contentWindow;
+
+    testNonEnumProperties();
+  });
+}
+
+function testNonEnumProperties() {
+  gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
+    Services.tm.currentThread.dispatch({ run: function() {
+      let testScope = gDebugger.DebuggerView.Properties._addScope("test-scope");
+      let testVar = testScope.addVar("foo");
+      testVar.addProperties({
+        foo: {
+          value: "bar",
+          enumerable: true
+        },
+
+        bar: {
+          value: "foo",
+          enumerable: false
+        }
+      });
+
+      testVar.expand();
+
+      let details = testVar.childNodes[1];
+      let nonenum = testVar.childNodes[2];
+
+      is(details.childNodes.length, 1,
+        "There should be just one property in the .details container.");
+
+      ok(details.hasAttribute("open"),
+        ".details container should be visible.");
+
+      is(nonenum.childNodes.length, 1,
+        "There should be just one property in the .nonenum container.");
+
+      ok(nonenum.hasAttribute("open"),
+        ".nonenum container should be visible.");
+
+      let option = gDebugger.document.getElementById("show-nonenum");
+
+      // Uncheck 'show hidden properties'.
+      EventUtils.sendMouseEvent({ type: "click" }, option, gDebugger);
+
+      ok(details.hasAttribute("open"),
+        ".details container should stay visible.");
+
+      ok(!nonenum.hasAttribute("open"),
+        ".nonenum container should become hidden.");
+
+      // Check 'show hidden properties'.
+      EventUtils.sendMouseEvent({ type: "click" }, option, gDebugger);
+
+      ok(details.hasAttribute("open"),
+        ".details container should stay visible.");
+
+      ok(nonenum.hasAttribute("open"),
+        ".nonenum container should become visible.");
+
+      testVar.collapse();
+
+      ok(!details.hasAttribute("open"),
+        ".details container should be hidden.");
+
+      ok(!nonenum.hasAttribute("open"),
+        ".nonenum container should be hidden.");
+
+      EventUtils.sendMouseEvent({ type: "click" }, option, gDebugger);
+
+      ok(!details.hasAttribute("open"),
+        ".details container should stay hidden.");
+
+      ok(!nonenum.hasAttribute("open"),
+        ".nonenum container should stay hidden.");
+
+      gDebugger.DebuggerController.activeThread.resume(function() {
+        closeDebuggerAndFinish();
+      });
+    }}, 0);
+  });
+
+  gDebuggee.simpleCall();
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gPane = null;
+  gTab = null;
+  gDebuggee = null;
+  gDebugger = null;
+});
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-04.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-04.js
@@ -21,31 +21,47 @@ function test() {
 
 function testSimpleCall() {
   gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
     Services.tm.currentThread.dispatch({ run: function() {
 
       let testScope = gDebugger.DebuggerView.Properties._addScope("test");
       let testVar = testScope.addVar("something");
 
-      let properties = testVar.addProperties({ "child": { "value": { "type": "object",
-                                                                     "class": "Object" } } });
+      let properties = testVar.addProperties({
+        "child": {
+          "value": {
+            "type": "object",
+            "class": "Object"
+          },
+
+          "enumerable": true
+        }
+      });
 
       is(testVar.querySelector(".details").childNodes.length, 1,
         "A new detail node should have been added in the variable tree.");
 
       ok(testVar.child,
         "The added detail property should be accessible from the variable.");
 
       is(testVar.child, properties.child,
         "Adding a detail property should return that exact property.");
 
 
-      let properties2 = testVar.child.addProperties({ "grandchild": { "value": { "type": "object",
-                                                                      "class": "Object" } } });
+      let properties2 = testVar.child.addProperties({
+        "grandchild": {
+          "value": {
+            "type": "object",
+            "class": "Object"
+          },
+
+          "enumerable": true
+        }
+      });
 
       is(testVar.child.querySelector(".details").childNodes.length, 1,
         "A new detail node should have been added in the variable tree.");
 
       ok(testVar.child.grandchild,
         "The added detail property should be accessible from the variable.");
 
       is(testVar.child.grandchild, properties2.grandchild,
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-05.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-05.js
@@ -39,38 +39,42 @@ function testSimpleCall() {
 
       is(testVar.querySelector(".details").childNodes.length, 0,
         "Adding type and class properties shouldn't add any new tree nodes.");
 
       is(testVar.querySelector(".value").getAttribute("value"), "[object Window]",
         "The information for the variable wasn't set correctly.");
 
 
-      testVar.addProperties({ "helloWorld": { "value": "hello world" } });
+      testVar.addProperties({ "helloWorld": { "value": "hello world", "enumerable": true } });
 
       is(testVar.querySelector(".details").childNodes.length, 1,
         "A new detail node should have been added in the variable tree.");
 
 
-      testVar.addProperties({ "helloWorld": { "value": "hello jupiter" } });
+      testVar.addProperties({ "helloWorld": { "value": "hello jupiter", "enumerable": true } });
 
       is(testVar.querySelector(".details").childNodes.length, 1,
         "Shouldn't be able to duplicate nodes added in the variable tree.");
 
 
-      testVar.addProperties({ "someProp0": { "value": "random string" },
-                              "someProp1": { "value": "another string" } });
+      testVar.addProperties({ "someProp0": { "value": "random string", "enumerable": true },
+                              "someProp1": { "value": "another string", "enumerable": true } });
 
       is(testVar.querySelector(".details").childNodes.length, 3,
         "Two new detail nodes should have been added in the variable tree.");
 
 
-      testVar.addProperties({ "someProp2": { "value": { "type": "null" } },
-                              "someProp3": { "value": { "type": "undefined" } },
-                              "someProp4": { "value": { "type": "object", "class": "Object" } } });
+      testVar.addProperties({ "someProp2": { "value": { "type": "null" }, "enumerable": true },
+                              "someProp3": { "value": { "type": "undefined" }, "enumerable": true },
+                              "someProp4": {
+                                "value": { "type": "object", "class": "Object" },
+                                "enumerable": true
+                              }
+                            });
 
       is(testVar.querySelector(".details").childNodes.length, 6,
         "Three new detail nodes should have been added in the variable tree.");
 
 
       testVar.empty();
 
       is(testVar.querySelector(".details").childNodes.length, 0,
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-06.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-06.js
@@ -40,30 +40,35 @@ function testSimpleCall() {
       localVar0.setGrip(42);
       localVar1.setGrip(true);
       localVar2.setGrip("nasu");
 
       localVar3.setGrip({ "type": "undefined" });
       localVar4.setGrip({ "type": "null" });
       localVar5.setGrip({ "type": "object", "class": "Object" });
 
-      localVar5.addProperties({ "someProp0": { "value": 42 },
-                                "someProp1": { "value": true },
-                                "someProp2": { "value": "nasu" },
-                                "someProp3": { "value": { "type": "undefined" } },
-                                "someProp4": { "value": { "type": "null" } },
-                                "someProp5": { "value": { "type": "object", "class": "Object" } } });
+      localVar5.addProperties({ "someProp0": { "value": 42, "enumerable": true },
+                                "someProp1": { "value": true , "enumerable": true},
+                                "someProp2": { "value": "nasu", "enumerable": true},
+                                "someProp3": { "value": { "type": "undefined" }, "enumerable": true},
+                                "someProp4": { "value": { "type": "null" }, "enumerable": true },
+                                "someProp5": {
+                                  "value": { "type": "object", "class": "Object" },
+                                  "enumerable": true
+                                }
+                              });
 
-      localVar5.someProp5.addProperties({ "someProp0": { "value": 42 },
-                                          "someProp1": { "value": true },
-                                          "someProp2": { "value": "nasu" },
-                                          "someProp3": { "value": { "type": "undefined" } },
-                                          "someProp4": { "value": { "type": "null" } },
+      localVar5.someProp5.addProperties({ "someProp0": { "value": 42, "enumerable": true },
+                                          "someProp1": { "value": true, "enumerable": true },
+                                          "someProp2": { "value": "nasu", "enumerable": true },
+                                          "someProp3": { "value": { "type": "undefined" }, "enumerable": true },
+                                          "someProp4": { "value": { "type": "null" }, "enumerable": true },
                                           "someAccessor": { "get": { "type": "object", "class": "Function" },
-                                                            "set": { "type": "undefined" } } });
+                                                            "set": { "type": "undefined" },
+                                                            "enumerable": true } });
 
       windowVar.setGrip({ "type": "object", "class": "Window" });
       windowVar.addProperties({ "helloWorld": { "value": "hello world" } });
 
       documentVar.setGrip({ "type": "object", "class": "HTMLDocument" });
       documentVar.addProperties({ "onload": { "value": { "type": "null" } },
                                   "onunload": { "value": { "type": "null" } },
                                   "onfocus": { "value": { "type": "null" } },
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
@@ -32,31 +32,33 @@ function testFrameParameters()
 
     gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       dump("After currentThread.dispatch!\n");
 
       var frames = gDebugger.DebuggerView.StackFrames._frames,
           localScope = gDebugger.DebuggerView.Properties._vars.firstChild,
-          localNodes = localScope.querySelector(".details").childNodes;
+          localNodes = localScope.childNodes[1].childNodes,
+          localNonEnums = localScope.childNodes[2].childNodes; // .nonenums
 
       dump("Got our variables:\n");
       dump("frames     - " + frames.constructor + "\n");
       dump("localScope - " + localScope.constructor + "\n");
       dump("localNodes - " + localNodes.constructor + "\n");
+      dump("localNonEnums - " + localNonEnums.constructor + "\n");
 
       is(gDebugger.DebuggerController.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 3,
         "Should have three frames.");
 
-      is(localNodes.length, 11,
-        "The localScope should contain all the created variable elements.");
+      is(localNodes.length + localNonEnums.length, 11,
+        "The localScope and localNonEnums should contain all the created variable elements.");
 
       is(localNodes[0].querySelector(".value").getAttribute("value"), "[object Proxy]",
         "Should have the right property value for 'this'.");
 
       // Expand the 'this', 'arguments' and 'c' tree nodes. This causes
       // their properties to be retrieved and displayed.
       localNodes[0].expand();
       localNodes[8].expand();
@@ -74,18 +76,18 @@ function testFrameParameters()
         }
         if (!localNodes[0].fetched ||
             !localNodes[8].fetched ||
             !localNodes[10].fetched) {
           return;
         }
         window.clearInterval(intervalID);
         is(localNodes[0].querySelector(".property > .title > .key")
-                        .getAttribute("value"), "Array",
-          "Should have the right property name for Array.");
+                        .getAttribute("value"), "InstallTrigger",
+          "Should have the right property name for InstallTrigger.");
         ok(localNodes[0].querySelector(".property > .title > .value")
                         .getAttribute("value").search(/object/) != -1,
           "Array should be an object.");
 
         is(localNodes[8].querySelector(".value")
                         .getAttribute("value"), "[object Arguments]",
          "Should have the right property value for 'arguments'.");
         ok(localNodes[8].querySelector(".property > .title > .value")
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-09.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-09.js
@@ -33,38 +33,38 @@ function testFrameParameters()
       info("Number of received Debugger:FetchedVariables events: " + count);
       return;
     }
     gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       var frames = gDebugger.DebuggerView.StackFrames._frames,
           globalScope = gDebugger.DebuggerView.Properties._vars.lastChild,
-          globalNodes = globalScope.querySelector(".details").childNodes;
+          globalNodes = globalScope.childNodes[2].childNodes;
 
       globalScope.expand();
 
       is(gDebugger.DebuggerController.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 3,
         "Should have three frames.");
 
       is(globalNodes[0].querySelector(".name").getAttribute("value"), "Array",
         "Should have the right property name for |Array|.");
 
       is(globalNodes[0].querySelector(".value").getAttribute("value"), "[object Function]",
         "Should have the right property value for |Array|.");
 
       let len = globalNodes.length - 1;
-      is(globalNodes[len].querySelector(".name").getAttribute("value"), "window",
-        "Should have the right property name for |window|.");
+      is(globalNodes[len].querySelector(".name").getAttribute("value"), "uneval",
+        "Should have the right property name for |uneval|.");
 
-      is(globalNodes[len].querySelector(".value").getAttribute("value"), "[object Proxy]",
-        "Should have the right property value for |window|.");
+      is(globalNodes[len].querySelector(".value").getAttribute("value"), "[object Function]",
+        "Should have the right property value for |uneval|.");
 
       resumeAndFinish();
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-10.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-10.js
@@ -54,21 +54,21 @@ function testWithFrame()
       is(scopes.children.length, 5, "Should have 5 variable scopes.");
 
       is(innerNodes[1].querySelector(".name").getAttribute("value"), "one",
         "Should have the right property name for |one|.");
 
       is(innerNodes[1].querySelector(".value").getAttribute("value"), "1",
         "Should have the right property value for |one|.");
 
-      is(globalNodes[0].querySelector(".name").getAttribute("value"), "Array",
+      is(globalNodes[0].querySelector(".name").getAttribute("value"), "InstallTrigger",
         "Should have the right property name for |Array|.");
 
-      is(globalNodes[0].querySelector(".value").getAttribute("value"), "[object Function]",
-        "Should have the right property value for |Array|.");
+      is(globalNodes[0].querySelector(".value").getAttribute("value"), "undefined",
+        "Should have the right property value for |InstallTrigger|.");
 
       let len = globalNodes.length - 1;
       is(globalNodes[len].querySelector(".name").getAttribute("value"), "window",
         "Should have the right property name for |window|.");
 
       is(globalNodes[len].querySelector(".value").getAttribute("value"), "[object Proxy]",
         "Should have the right property value for |window|.");
 
--- a/browser/devtools/debugger/test/test-script-switching-02.js
+++ b/browser/devtools/debugger/test/test-script-switching-02.js
@@ -1,7 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function secondCall() {
   // This comment is useful for browser_dbg_select-line.js. ☺
   eval("debugger;");
+  function foo() {}
+  if (true) {
+    foo();
+  }
 }
--- a/browser/devtools/styleeditor/StyleEditorChrome.jsm
+++ b/browser/devtools/styleeditor/StyleEditorChrome.jsm
@@ -345,33 +345,36 @@ StyleEditorChrome.prototype = {
       if (aLine || aCol) {
         aLine = aLine || 1;
         aCol = aCol || 1;
         setCaret = true;
       }
       if (!aEditor.sourceEditor) {
         // If a line or column was specified we move the caret appropriately.
         if (setCaret) {
+          let self = this;
           aEditor.addActionListener({
             onAttach: function SEC_selectSheet_onAttach()
             {
               aEditor.removeActionListener(this);
+              self.selectedStyleSheetIndex = aEditor.styleSheetIndex;
               aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
             }
           });
         }
         this._view.activeSummary = summary;
       } else {
         this._view.activeSummary = summary;
 
         // If a line or column was specified we move the caret appropriately.
         if (setCaret) {
           aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
         }
       }
+      this.selectedStyleSheetIndex = aEditor.styleSheetIndex;
     }.bind(this);
 
     if (!this.editors.length) {
       // We are in the main initialization phase so we wait for the editor
       // containing the target stylesheet to be added and select the target
       // stylesheet, optionally moving the cursor to a selected line.
       this.addChromeListener({
         onEditorAdded: function SEC_selectSheet_onEditorAdded(aChrome, aEditor) {
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -896,16 +896,63 @@ WebConsole.prototype = {
    *        The URL you want to open in a new tab.
    */
   openLink: function WC_openLink(aLink)
   {
     this.chromeWindow.openUILinkIn(aLink, "tab");
   },
 
   /**
+   * Open a link in Firefox's view source.
+   *
+   * @param string aSourceURL
+   *        The URL of the file.
+   * @param integer aSourceLine
+   *        The line number which should be highlighted.
+   */
+  viewSource: function WC_viewSource(aSourceURL, aSourceLine)
+  {
+    this.gViewSourceUtils.viewSource(aSourceURL, null,
+                                     this.iframeWindow.document, aSourceLine);
+  },
+
+  /**
+   * Tries to open a Stylesheet file related to the web page for the web console
+   * instance in the Style Editor. If the file is not found, it is opened in
+   * source view instead.
+   *
+   * @param string aSourceURL
+   *        The URL of the file.
+   * @param integer aSourceLine
+   *        The line number which you want to place the caret.
+   * TODO: This function breaks the client-server boundaries.
+   *       To be fixed in bug 793259.
+   */
+  viewSourceInStyleEditor:
+  function WC_viewSourceInStyleEditor(aSourceURL, aSourceLine)
+  {
+    let styleSheets = this.tab.linkedBrowser.contentWindow.document.styleSheets;
+    for each (let style in styleSheets) {
+      if (style.href == aSourceURL) {
+        let SEM = this.chromeWindow.StyleEditor.StyleEditorManager;
+        let win = SEM.getEditorForWindow(this.chromeWindow.content.window);
+        if (win) {
+          SEM.selectEditor(win, style, aSourceLine);
+        }
+        else {
+          this.chromeWindow.StyleEditor.openChrome(style, aSourceLine);
+        }
+        return;
+      }
+    }
+    // Open view source if style editor fails.
+    this.viewSource(aSourceURL, aSourceLine);
+  },
+
+  /**
    * Destroy the object. Call this method to avoid memory leaks when the Web
    * Console is closed.
    *
    * @param function [aOnDestroy]
    *        Optional function to invoke when the Web Console instance is
    *        destroyed.
    */
   destroy: function WC_destroy(aOnDestroy)
--- a/browser/devtools/webconsole/test/Makefile.in
+++ b/browser/devtools/webconsole/test/Makefile.in
@@ -104,16 +104,17 @@ MOCHITEST_BROWSER_FILES = \
 	browser_webconsole_bug_659907_console_dir.js \
 	browser_webconsole_bug_664131_console_group.js \
 	browser_webconsole_bug_704295.js \
 	browser_webconsole_bug_658368_time_methods.js \
 	browser_webconsole_bug_764572_output_open_url.js \
 	browser_webconsole_bug_622303_persistent_filters.js \
         browser_webconsole_bug_770099_bad_policyuri.js \
         browser_webconsole_bug_770099_violation.js \
+	browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js \
 	browser_webconsole_window_zombie.js \
 	browser_cached_messages.js \
 	browser_bug664688_sandbox_update_after_navigation.js \
 	browser_webconsole_menustatus.js \
 	browser_result_format_as_string.js \
 	browser_webconsole_bug_737873_mixedcontent.js \
 	browser_output_breaks_after_console_dir_uninspectable.js \
 	browser_console_log_inspectable_object.js \
@@ -181,16 +182,19 @@ MOCHITEST_BROWSER_FILES += \
 	test-bug-618078-network-exceptions.html \
 	test-bug-630733-response-redirect-headers.sjs \
 	test-bug-621644-jsterm-dollar.html \
 	test-bug-632347-iterators-generators.html \
 	test-bug-585956-console-trace.html \
 	test-bug-644419-log-limits.html \
 	test-bug-632275-getters.html \
 	test-bug-646025-console-file-location.html \
+	test-bug-782653-css-errors.html \
+	test-bug-782653-css-errors-1.css \
+	test-bug-782653-css-errors-2.css \
 	test-file-location.js \
 	test-bug-658368-time-methods.html \
 	test-webconsole-error-observer.html \
 	test-for-of.html \
         test_bug_770099_violation.html \
         test_bug_770099_violation.html^headers^ \
         test_bug_770099_bad_policy_uri.html \
         test_bug_770099_bad_policy_uri.html^headers^ \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js
@@ -0,0 +1,133 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * ***** END LICENSE BLOCK ***** */
+
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test" +
+                 "/test-bug-782653-css-errors.html";
+
+let nodes;
+
+let styleEditorWin;
+
+function test() {
+  addTab(TEST_URI);
+  browser.addEventListener("load", function onLoad() {
+    browser.removeEventListener("load", onLoad, true);
+    openConsole(null, testViewSource);
+  }, true);
+}
+
+function testViewSource(hud) {
+
+  waitForSuccess({
+    name: "find the location node",
+    validatorFn: function()
+    {
+      return hud.outputNode.querySelector(".webconsole-location");
+    },
+    successFn: function()
+    {
+      nodes = hud.outputNode.querySelectorAll(".webconsole-location");
+
+      Services.ww.registerNotification(observer);
+
+      EventUtils.sendMouseEvent({ type: "click" }, nodes[0]);
+    },
+    failureFn: finishTest,
+  });
+}
+
+function checkStyleEditorForSheetAndLine(aStyleSheetIndex, aLine, aCallback) {
+
+  function doCheck(aEditor) {
+    if (aEditor.styleSheetIndex != aStyleSheetIndex) {
+      ok(false, "Correct Style Sheet was not selected.");
+      if (aCallback) {
+        executeSoon(aCallback);
+      }
+      return;
+    }
+
+    ok(true, "Correct Style Sheet is selected in the editor");
+
+    // Editor is already loaded, check the current line of caret.
+    if (aEditor.sourceEditor) {
+      executeSoon(function() {
+        is(aEditor.sourceEditor.getCaretPosition().line, aLine,
+           "Correct line is selected");
+        if (aCallback) {
+          aCallback();
+        }
+      });
+      return;
+    }
+
+    // Wait for source editor to be loaded.
+    aEditor.addActionListener({
+      onAttach: function onAttach() {
+        aEditor.removeActionListener(this);
+
+        executeSoon(function() {
+          is(aEditor.sourceEditor.getCaretPosition().line, aLine,
+             "Correct line is selected");
+          if (aCallback) {
+            aCallback();
+          }
+        });
+      }
+    });
+  }
+
+  let SEC = styleEditorWin.styleEditorChrome;
+  ok(SEC, "Syle Editor Chrome is defined properly while calling for [" +
+          aStyleSheetIndex + ", " + aLine + "]");
+
+  // Editors are not ready, so wait for them.
+  if (!SEC.editors.length) {
+    SEC.addChromeListener({
+      onEditorAdded: function onEditorAdded(aChrome, aEditor) {
+        aChrome.removeChromeListener(this);
+        doCheck(aEditor);
+      }
+    });
+  }
+  // Execute soon so that selectedStyleSheetIndex has correct value.
+  else {
+    executeSoon(function() {
+      let aEditor = SEC.editors[SEC.selectedStyleSheetIndex];
+      doCheck(aEditor);
+    });
+  }
+}
+
+let observer = {
+  observe: function(aSubject, aTopic, aData) {
+    if (aTopic != "domwindowopened") {
+      return;
+    }
+    Services.ww.unregisterNotification(observer);
+    ok(true, "Style Editor window was opened in response to clicking " +
+             "the location node");
+
+    executeSoon(function() {
+      styleEditorWin = window.StyleEditor
+                             .StyleEditorManager
+                             .getEditorForWindow(content.window);
+      ok(styleEditorWin, "Style Editor Window is defined");
+      styleEditorWin.addEventListener("load", function onStyleEditorWinLoad() {
+        styleEditorWin.removeEventListener("load", onStyleEditorWinLoad);
+
+        checkStyleEditorForSheetAndLine(0, 7, function() {
+          checkStyleEditorForSheetAndLine(1, 6, function() {
+            window.StyleEditor.toggle();
+            styleEditorWin = null;
+            finishTest();
+          });
+          EventUtils.sendMouseEvent({ type: "click" }, nodes[1]);
+        });
+      });
+    });
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-782653-css-errors-1.css
@@ -0,0 +1,10 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+body {
+  color: #0f0;
+  font-weight: green;
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-782653-css-errors-2.css
@@ -0,0 +1,10 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+body {
+  color: #0fl;
+  font-weight: bold;
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-782653-css-errors.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Web Console test for bug 782653 : Open CSS Links in Style Editor</title>
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+    <link rel="stylesheet" href="test-bug-782653-css-errors-1.css">
+    <link rel="stylesheet" href="test-bug-782653-css-errors-2.css">
+  </head>
+  <body>
+    <p>Web Console test for bug 782653 : Open CSS Links in Style Editor.</p>
+  </body>
+</html>
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -1393,18 +1393,17 @@ WebConsoleFrame.prototype = {
     urlNode.setAttribute("value", aFileURI);
     urlNode.classList.add("hud-clickable");
     urlNode.classList.add("webconsole-msg-url");
 
     let outputNode = this.createMessageNode(CATEGORY_NETWORK, SEVERITY_LOG,
                                             urlNode, null, null, aFileURI);
 
     this.makeOutputMessageLink(outputNode, function WCF__onFileClick() {
-      let viewSourceUtils = this.owner.gViewSourceUtils;
-      viewSourceUtils.viewSource(aFileURI, null, this.document);
+      this.owner.viewSource(aFileURI);
     }.bind(this));
 
     return outputNode;
   },
 
   /**
    * Handle the file activity messages coming from the remote Web Console.
    *
@@ -2384,20 +2383,23 @@ WebConsoleFrame.prototype = {
 
     // Make the location clickable.
     locationNode.addEventListener("click", function() {
       if (aSourceURL == "Scratchpad") {
         let win = Services.wm.getMostRecentWindow("devtools:scratchpad");
         if (win) {
           win.focus();
         }
-        return;
+      }
+      else if (locationNode.parentNode.category == CATEGORY_CSS) {
+        this.owner.viewSourceInStyleEditor(aSourceURL, aSourceLine);
       }
-      let viewSourceUtils = this.owner.gViewSourceUtils;
-      viewSourceUtils.viewSource(aSourceURL, null, this.document, aSourceLine);
+      else {
+        this.owner.viewSource(aSourceURL, aSourceLine);
+      }
     }.bind(this), true);
 
     return locationNode;
   },
 
   /**
    * Adjusts the category and severity of the given message, clearing the old
    * category and severity if present.
--- a/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
@@ -34,11 +34,16 @@
 <!-- LOCALIZATION NOTE (debuggerUI.closeButton.tooltip): This is the tooltip for
   -  the button that closes the debugger UI. -->
 <!ENTITY debuggerUI.closeButton.tooltip "Close">
 
 <!-- LOCALIZATION NOTE (debuggerUI.pauseExceptions): This is the label for the
   -  checkbox that toggles pausing on exceptions. -->
 <!ENTITY debuggerUI.pauseExceptions     "Pause on exceptions">
 
+<!-- LOCALIZATION NOTE (debuggerUI.showNonEnums): This is the label for the
+  -  checkbox that toggles visibility of hidden (non-enumerable) variables and
+  -  properties in stack views. -->
+<!ENTITY debuggerUI.showNonEnums        "Show hidden properties">
+
 <!-- LOCALIZATION NOTE (debuggerUI.searchPanelTitle): This is the text that
   -  appears in the filter panel popup as a description. -->
 <!ENTITY debuggerUI.searchPanelTitle    "Operators">
--- a/browser/themes/gnomestripe/devtools/markup-view.css
+++ b/browser/themes/gnomestripe/devtools/markup-view.css
@@ -38,20 +38,17 @@ li.container {
 
 .codebox {
   padding-left: 14px;
 }
 
 .expander {
   position: absolute;
   -moz-appearance: treetwisty;
-  top: 0;
-  left: 0;
-  width: 14px;
-  height: 14px;
+  padding: 11px 0;
 }
 
 .expander[expanded] {
   -moz-appearance: treetwistyopen;
 }
 
 .styleinspector-propertyeditor {
   border: 1px solid #CCC;