diff --git a/b2g/chrome/content/forms.js b/b2g/chrome/content/forms.js index c7d7776c4e56..ae24dd26512e 100644 --- a/b2g/chrome/content/forms.js +++ b/b2g/chrome/content/forms.js @@ -100,6 +100,7 @@ let FormAssistant = { if (this.focusedElement) { sendAsyncMessage("Forms:Input", { "type": "blur" }); this.setFocusedElement(null); + this.isKeyboardOpened = false; } break; diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index e9aee41b74ac..c81081a81a97 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 57d770deb6ae..ba0cd874c209 100644 --- a/browser/devtools/debugger/debugger-controller.js +++ b/browser/devtools/debugger/debugger-controller.js @@ -1463,7 +1463,18 @@ Breakpoints.prototype = { 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); }, /** @@ -1555,6 +1566,18 @@ Breakpoints.prototype = { } 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); @@ -1655,6 +1678,18 @@ Breakpoints.prototype = { } } 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; } }; @@ -1698,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. @@ -1785,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 */ @@ -1797,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 4e9a9613bb9e..f9d4118c47eb 100644 --- a/browser/devtools/debugger/debugger-view.js +++ b/browser/devtools/debugger/debugger-view.js @@ -2107,7 +2107,7 @@ BreakpointsView.prototype = { 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) { @@ -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 87e329553542..cbea5982362f 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