diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index e9aee41b74a..c81081a81a9 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1035,6 +1035,7 @@ 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);
diff --git a/browser/devtools/debugger/debugger-controller.js b/browser/devtools/debugger/debugger-controller.js
index 5dd57ec2ea8..ba0cd874c20 100644
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -1733,6 +1733,7 @@ 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.
@@ -1820,7 +1821,7 @@ let Prefs = {
},
/**
- * 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
*/
@@ -1832,13 +1833,35 @@ let Prefs = {
},
/**
- * 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;
}
};
diff --git a/browser/devtools/debugger/debugger-view.js b/browser/devtools/debugger/debugger-view.js
index bbcd116d034..f9d4118c47e 100644
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -2585,9 +2585,16 @@ PropertiesView.prototype = {
// 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) {
@@ -2789,6 +2796,7 @@ PropertiesView.prototype = {
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);
@@ -2834,9 +2842,16 @@ PropertiesView.prototype = {
// 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) {
@@ -3112,6 +3127,7 @@ PropertiesView.prototype = {
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;
@@ -3131,6 +3147,7 @@ PropertiesView.prototype = {
// 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") {
@@ -3146,6 +3163,7 @@ PropertiesView.prototype = {
element.appendChild(title);
element.appendChild(details);
+ element.appendChild(nonEnum);
aParent.appendChild(element);
@@ -3192,12 +3210,19 @@ PropertiesView.prototype = {
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;
};
@@ -3210,9 +3235,12 @@ PropertiesView.prototype = {
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);
@@ -3240,9 +3268,12 @@ PropertiesView.prototype = {
* 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;
};
@@ -3327,13 +3358,19 @@ PropertiesView.prototype = {
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;
};
@@ -3431,7 +3468,7 @@ PropertiesView.prototype = {
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.
@@ -3549,10 +3586,31 @@ PropertiesView.prototype = {
*/
_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();
diff --git a/browser/devtools/debugger/debugger.xul b/browser/devtools/debugger/debugger.xul
index 87e32955354..cbea5982362 100644
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -90,6 +90,10 @@
type="checkbox"
tabindex="0"
label="&debuggerUI.pauseExceptions;"/>
+
#ifndef XP_MACOSX
.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.");
diff --git a/browser/devtools/debugger/test/browser_dbg_propertyview-09.js b/browser/devtools/debugger/test/browser_dbg_propertyview-09.js
index 78b037a820f..4cece3ef54d 100644
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-09.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-09.js
@@ -38,7 +38,7 @@ function testFrameParameters()
var frames = gDebugger.DebuggerView.StackFrames._frames,
globalScope = gDebugger.DebuggerView.Properties._vars.lastChild,
- globalNodes = globalScope.querySelector(".details").childNodes;
+ globalNodes = globalScope.childNodes[2].childNodes;
globalScope.expand();
@@ -55,11 +55,11 @@ function testFrameParameters()
"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);
diff --git a/browser/devtools/debugger/test/browser_dbg_propertyview-10.js b/browser/devtools/debugger/test/browser_dbg_propertyview-10.js
index 1da2d06f159..0885d3e4d93 100644
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-10.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-10.js
@@ -59,11 +59,11 @@ function testWithFrame()
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",
diff --git a/browser/locales/en-US/chrome/browser/devtools/debugger.dtd b/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
index d88efe3d023..4302a1eee34 100644
--- a/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/debugger.dtd
@@ -39,6 +39,11 @@
- checkbox that toggles pausing on exceptions. -->
+
+
+