Bug 683503 - GCLI needs commands to control the debugger; r=jwalker,dcamp

This commit is contained in:
Panos Astithas 2012-02-10 09:46:04 +02:00
Родитель e952c55717
Коммит 105b2271c1
6 изменённых файлов: 340 добавлений и 0 удалений

Просмотреть файл

@ -1092,6 +1092,17 @@ DebuggerView.Scripts = {
return script;
},
/**
* Returns the list of URIs for scripts in the page.
*/
scriptLocations: function DVS_scriptLocations() {
let locations = [];
for (let i = 0; i < this._scripts.itemCount; i++) {
locations.push(this._scripts.getItemAtIndex(i).value);
}
return locations;
},
/**
* The cached click listener for the scripts container.
*/

Просмотреть файл

@ -125,3 +125,139 @@ gcli.addCommand({
document.defaultView.InspectorUI.openInspectorUI(args.node);
}
});
let breakpoints = [];
/**
* 'break' command
*/
gcli.addCommand({
name: "break",
description: gcli.lookup("breakDesc"),
manual: gcli.lookup("breakManual")
});
/**
* 'break list' command
*/
gcli.addCommand({
name: "break list",
description: gcli.lookup("breaklistDesc"),
returnType: "html",
exec: function(args, context) {
if (breakpoints.length === 0) {
return gcli.lookup("breaklistNone");
}
let reply = gcli.lookup("breaklistIntro");
reply += "<ol>";
breakpoints.forEach(function(breakpoint) {
let text = gcli.lookupFormat("breaklistLineEntry",
[breakpoint.file, breakpoint.line]);
reply += "<li>" + text + "</li>";
});
reply += "</ol>";
return reply;
}
});
/**
* 'break add' command
*/
gcli.addCommand({
name: "break add",
description: gcli.lookup("breakaddDesc"),
manual: gcli.lookup("breakaddManual")
});
/**
* 'break add line' command
*/
gcli.addCommand({
name: "break add line",
description: gcli.lookup("breakaddlineDesc"),
params: [
{
name: "file",
type: {
name: "selection",
data: function() {
let win = HUDService.currentContext();
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
let files = [];
if (dbg) {
let scriptsView = dbg.frame.contentWindow.DebuggerView.Scripts;
for each (let script in scriptsView.scriptLocations()) {
files.push(script);
}
}
return files;
}
},
description: gcli.lookup("breakaddlineFileDesc")
},
{
name: "line",
type: { name: "number", min: 1, step: 10 },
description: gcli.lookup("breakaddlineLineDesc")
}
],
returnType: "html",
exec: function(args, context) {
args.type = "line";
let win = HUDService.currentContext();
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
if (!dbg) {
return gcli.lookup("breakaddDebuggerStopped");
}
var promise = context.createPromise();
let position = { url: args.file, line: args.line };
dbg.activeThread.setBreakpoint(position, function(aResponse, aBpClient) {
if (aResponse.error) {
promise.resolve(gcli.lookupFormat("breakaddFailed",
[ aResponse.error ]));
return;
}
args.client = aBpClient;
breakpoints.push(args);
promise.resolve(gcli.lookup("breakaddAdded"));
});
return promise;
}
});
/**
* 'break del' command
*/
gcli.addCommand({
name: "break del",
description: gcli.lookup("breakdelDesc"),
params: [
{
name: "breakid",
type: {
name: "number",
min: 0,
max: function() { return breakpoints.length - 1; }
},
description: gcli.lookup("breakdelBreakidDesc")
}
],
returnType: "html",
exec: function(args, context) {
let breakpoint = breakpoints.splice(args.breakid, 1)[0];
var promise = context.createPromise();
try {
breakpoint.client.remove(function(aResponse) {
promise.resolve(gcli.lookup("breakdelRemoved"));
});
} catch (ex) {
// If the debugger has been closed already, don't scare the user.
promise.resolve(gcli.lookup("breakdelRemoved"));
}
return promise;
}
});

Просмотреть файл

@ -154,6 +154,7 @@ _BROWSER_TEST_FILES = \
browser_webconsole_bug_622303_persistent_filters.js \
browser_webconsole_window_zombie.js \
browser_cached_messages.js \
browser_gcli_break.js \
head.js \
$(NULL)
@ -228,6 +229,7 @@ _BROWSER_TEST_PAGES = \
test-bug-658368-time-methods.html \
test-webconsole-error-observer.html \
test-for-of.html \
browser_gcli_break.html \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Browser GCLI break command test</title>
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript">
function firstCall() {
eval("window.line0 = Error().lineNumber; secondCall();");
}
function secondCall() {
eval("debugger;");
}
</script>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,104 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// For more information on GCLI see:
// - https://github.com/mozilla/gcli/blob/master/docs/index.md
// - https://wiki.mozilla.org/DevTools/Features/GCLI
// Tests that the break command works as it should
let tempScope = {};
Components.utils.import("resource:///modules/gcli.jsm", tempScope);
let gcli = tempScope.gcli;
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/browser_gcli_break.html";
registerCleanupFunction(function() {
gcliterm = undefined;
requisition = undefined;
Services.prefs.clearUserPref("devtools.gcli.enable");
});
function test() {
Services.prefs.setBoolPref("devtools.gcli.enable", true);
addTab(TEST_URI);
browser.addEventListener("DOMContentLoaded", onLoad, false);
}
let gcliterm;
let requisition;
function onLoad() {
browser.removeEventListener("DOMContentLoaded", onLoad, false);
try {
openConsole();
let hud = HUDService.getHudByWindow(content);
gcliterm = hud.gcliterm;
requisition = gcliterm.opts.requisition;
testSetup();
testCreateCommands();
}
catch (ex) {
ok(false, "Caught exception: " + ex)
gcli._internal.console.error("Test Failure", ex);
closeConsole();
finishTest();
}
}
function testSetup() {
ok(gcliterm, "We have a GCLI term");
ok(requisition, "We have a Requisition");
}
function testCreateCommands() {
type("brea");
is(gcliterm.completeNode.textContent, " break", "Completion for 'brea'");
is(requisition.getStatus().toString(), "ERROR", "brea is ERROR");
type("break");
is(requisition.getStatus().toString(), "ERROR", "break is ERROR");
type("break add");
is(requisition.getStatus().toString(), "ERROR", "break add is ERROR");
type("break add line");
is(requisition.getStatus().toString(), "ERROR", "break add line is ERROR");
let pane = DebuggerUI.toggleDebugger();
pane.onConnected = function test_onConnected(aPane) {
// Wait for the initial resume.
aPane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
delete aPane.onConnected;
aPane.debuggerWindow.gClient.activeThread.addOneTimeListener("scriptsadded", function() {
type("break add line " + TEST_URI + " " + content.wrappedJSObject.line0);
is(requisition.getStatus().toString(), "VALID", "break add line is VALID");
requisition.exec();
type("break list");
is(requisition.getStatus().toString(), "VALID", "break list is VALID");
requisition.exec();
aPane.debuggerWindow.gClient.activeThread.resume(function() {
type("break del 0");
is(requisition.getStatus().toString(), "VALID", "break del 0 is VALID");
requisition.exec();
closeConsole();
finishTest();
});
});
// Trigger newScript notifications using eval.
content.wrappedJSObject.firstCall();
});
}
}
function type(command) {
gcliterm.inputNode.value = command.slice(0, -1);
gcliterm.inputNode.focus();
EventUtils.synthesizeKey(command.slice(-1), {});
}

Просмотреть файл

@ -56,6 +56,75 @@ inspectNodeDesc=CSS selector
# on what it does.
inspectNodeManual=A CSS selector for use with Document.querySelector which identifies a single element
# LOCALIZATION NOTE (breakDesc) A very short string used to describe the
# function of the break command.
breakDesc=Manage breakpoints
# LOCALIZATION NOTE (breakManual) A longer description describing the
# set of commands that control breakpoints.
breakManual=Commands to list, add and remove breakpoints
# LOCALIZATION NOTE (breaklistDesc) A very short string used to describe the
# function of the 'break list' command.
breaklistDesc=Display known breakpoints
# LOCALIZATION NOTE (breaklistLineEntry) Used in the output of the 'break list'
# command to display a single line breakpoint.
# %1$S=script URL, %2$S=line number
breaklistLineEntry=Line breakpoint at %1$S:%2$S
# LOCALIZATION NOTE (breaklistNone) Used in the output of the 'break list'
# command to explain that the list is empty.
breaklistNone=No breakpoints set
# LOCALIZATION NOTE (breaklistIntro) Used in the output of the 'break list'
# command to preface the list contents.
breaklistIntro=The following breakpoints are set:
# LOCALIZATION NOTE (breakaddAdded) Used in the output of the 'break add'
# command to explain that a breakpoint was added.
breakaddAdded=Added breakpoint
# LOCALIZATION NOTE (breakaddFailed) Used in the output of the 'break add'
# command to explain that a breakpoint could not be added.
breakaddFailed=Could not set breakpoint: %S
# LOCALIZATION NOTE (breakaddDesc) A very short string used to describe the
# function of the 'break add' command.
breakaddDesc=Add a breakpoint
# LOCALIZATION NOTE (breakaddManual) A longer description describing the
# set of commands that are responsible for adding breakpoints.
breakaddManual=Breakpoint types supported: line
# LOCALIZATION NOTE (breakaddDebuggerStopped) Used in the output of the
# 'break add' command to explain that the debugger must be opened first.
breakaddDebuggerStopped=The debugger must be opened before setting breakpoints
# LOCALIZATION NOTE (breakaddlineDesc) A very short string used to describe the
# function of the 'break add line' command.
breakaddlineDesc=Add a line breakpoint
# LOCALIZATION NOTE (breakaddlineFileDesc) A very short string used to describe
# the function of the file parameter in the 'break add line' command.
breakaddlineFileDesc=JS file URI
# LOCALIZATION NOTE (breakaddlineLineDesc) A very short string used to describe
# the function of the line parameter in the 'break add line' command.
breakaddlineLineDesc=Line number
# LOCALIZATION NOTE (breakdelDesc) A very short string used to describe the
# function of the 'break del' command.
breakdelDesc=Remove a breakpoint
# LOCALIZATION NOTE (breakdelBreakidDesc) A very short string used to describe
# the function of the index parameter in the 'break del' command.
breakdelBreakidDesc=Index of breakpoint
# LOCALIZATION NOTE (breakdelRemoved) Used in the output of the 'break del'
# command to explain that a breakpoint was removed.
breakdelRemoved=Breakpoint removed
# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
# 'console close' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.