зеркало из https://github.com/mozilla/gecko-dev.git
merge m-c to fx-team
This commit is contained in:
Коммит
a9b88a6aae
|
@ -100,6 +100,7 @@ let FormAssistant = {
|
|||
if (this.focusedElement) {
|
||||
sendAsyncMessage("Forms:Input", { "type": "blur" });
|
||||
this.setFocusedElement(null);
|
||||
this.isKeyboardOpened = false;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -90,6 +90,10 @@
|
|||
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"
|
||||
|
|
|
@ -63,6 +63,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
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 \
|
||||
|
@ -70,6 +71,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_dbg_menustatus.js \
|
||||
browser_dbg_bfcache.js \
|
||||
browser_dbg_breakpoint-new-script.js \
|
||||
browser_dbg_bug737803_editor_actual_location.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -160,17 +160,17 @@ function test()
|
|||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
|
@ -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;
|
||||
});
|
|
@ -26,8 +26,16 @@ function testSimpleCall() {
|
|||
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.");
|
||||
|
@ -39,8 +47,16 @@ function testSimpleCall() {
|
|||
"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.");
|
||||
|
|
|
@ -44,28 +44,32 @@ function testSimpleCall() {
|
|||
"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.");
|
||||
|
|
|
@ -45,20 +45,25 @@ function testSimpleCall() {
|
|||
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" } });
|
||||
|
|
|
@ -37,12 +37,14 @@ function testFrameParameters()
|
|||
|
||||
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.");
|
||||
|
@ -50,8 +52,8 @@ function testFrameParameters()
|
|||
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'.");
|
||||
|
@ -79,8 +81,8 @@ function testFrameParameters()
|
|||
}
|
||||
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.");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -4,4 +4,8 @@
|
|||
function secondCall() {
|
||||
// This comment is useful for browser_dbg_select-line.js. ☺
|
||||
eval("debugger;");
|
||||
function foo() {}
|
||||
if (true) {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,10 +350,12 @@ StyleEditorChrome.prototype = {
|
|||
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);
|
||||
}
|
||||
});
|
||||
|
@ -367,6 +369,7 @@ StyleEditorChrome.prototype = {
|
|||
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
|
||||
}
|
||||
}
|
||||
this.selectedStyleSheetIndex = aEditor.styleSheetIndex;
|
||||
}.bind(this);
|
||||
|
||||
if (!this.editors.length) {
|
||||
|
|
|
@ -900,6 +900,53 @@ WebConsole.prototype = {
|
|||
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.
|
||||
|
|
|
@ -109,6 +109,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
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 \
|
||||
|
@ -186,6 +187,9 @@ MOCHITEST_BROWSER_FILES += \
|
|||
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 \
|
||||
|
|
|
@ -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]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>
|
|
@ -1398,8 +1398,7 @@ WebConsoleFrame.prototype = {
|
|||
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;
|
||||
|
@ -2389,10 +2388,13 @@ WebConsoleFrame.prototype = {
|
|||
if (win) {
|
||||
win.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
let viewSourceUtils = this.owner.gViewSourceUtils;
|
||||
viewSourceUtils.viewSource(aSourceURL, null, this.document, aSourceLine);
|
||||
else if (locationNode.parentNode.category == CATEGORY_CSS) {
|
||||
this.owner.viewSourceInStyleEditor(aSourceURL, aSourceLine);
|
||||
}
|
||||
else {
|
||||
this.owner.viewSource(aSourceURL, aSourceLine);
|
||||
}
|
||||
}.bind(this), true);
|
||||
|
||||
return locationNode;
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
- 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">
|
||||
|
|
|
@ -43,10 +43,7 @@ li.container {
|
|||
.expander {
|
||||
position: absolute;
|
||||
-moz-appearance: treetwisty;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 11px 0;
|
||||
}
|
||||
|
||||
.expander[expanded] {
|
||||
|
|
Загрузка…
Ссылка в новой задаче