зеркало из https://github.com/mozilla/gecko-dev.git
Bug 762761 - part 2: front end changes for debugger pretty printing; r=vporof
This commit is contained in:
Родитель
72115182ca
Коммит
99320a9b6c
|
@ -1145,6 +1145,48 @@ SourceScripts.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Pretty print a source's text. All subsequent calls to |getText| will return
|
||||
* the pretty text.
|
||||
*
|
||||
* @param Object aSource
|
||||
* The source form from the RDP.
|
||||
* @returns Promise
|
||||
* A promise that resolves to [aSource, prettyText] or rejects to
|
||||
* [aSource, error].
|
||||
*/
|
||||
prettyPrint: function(aSource) {
|
||||
let textPromise = this._cache.get(aSource.url);
|
||||
// Only use the existing promise if it is pretty printed.
|
||||
if (textPromise && textPromise.pretty) {
|
||||
return textPromise;
|
||||
}
|
||||
|
||||
const deferred = promise.defer();
|
||||
this._cache.set(aSource.url, deferred.promise);
|
||||
|
||||
this.activeThread.source(aSource)
|
||||
.prettyPrint(Prefs.editorTabSize, ({ error, message, source }) => {
|
||||
if (error) {
|
||||
deferred.reject([aSource, message || error]);
|
||||
return;
|
||||
}
|
||||
|
||||
DebuggerController.Parser.clearSource(aSource.url);
|
||||
|
||||
if (this.activeThread.paused) {
|
||||
// Update the stack frame list.
|
||||
this.activeThread._clearFrames();
|
||||
this.activeThread.fillFrames(CALL_STACK_PAGE_SIZE);
|
||||
}
|
||||
|
||||
deferred.resolve([aSource, source]);
|
||||
});
|
||||
|
||||
deferred.promise.pretty = true;
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a specified source's text.
|
||||
*
|
||||
|
@ -1697,18 +1739,19 @@ let L10N = new ViewHelpers.L10N(DBG_STRINGS_URI);
|
|||
/**
|
||||
* Shortcuts for accessing various debugger preferences.
|
||||
*/
|
||||
let Prefs = new ViewHelpers.Prefs("devtools.debugger", {
|
||||
chromeDebuggingHost: ["Char", "chrome-debugging-host"],
|
||||
chromeDebuggingPort: ["Int", "chrome-debugging-port"],
|
||||
sourcesWidth: ["Int", "ui.panes-sources-width"],
|
||||
instrumentsWidth: ["Int", "ui.panes-instruments-width"],
|
||||
panesVisibleOnStartup: ["Bool", "ui.panes-visible-on-startup"],
|
||||
variablesSortingEnabled: ["Bool", "ui.variables-sorting-enabled"],
|
||||
variablesOnlyEnumVisible: ["Bool", "ui.variables-only-enum-visible"],
|
||||
variablesSearchboxVisible: ["Bool", "ui.variables-searchbox-visible"],
|
||||
pauseOnExceptions: ["Bool", "pause-on-exceptions"],
|
||||
ignoreCaughtExceptions: ["Bool", "ignore-caught-exceptions"],
|
||||
sourceMapsEnabled: ["Bool", "source-maps-enabled"]
|
||||
let Prefs = new ViewHelpers.Prefs("devtools", {
|
||||
chromeDebuggingHost: ["Char", "debugger.chrome-debugging-host"],
|
||||
chromeDebuggingPort: ["Int", "debugger.chrome-debugging-port"],
|
||||
sourcesWidth: ["Int", "debugger.ui.panes-sources-width"],
|
||||
instrumentsWidth: ["Int", "debugger.ui.panes-instruments-width"],
|
||||
panesVisibleOnStartup: ["Bool", "debugger.ui.panes-visible-on-startup"],
|
||||
variablesSortingEnabled: ["Bool", "debugger.ui.variables-sorting-enabled"],
|
||||
variablesOnlyEnumVisible: ["Bool", "debugger.ui.variables-only-enum-visible"],
|
||||
variablesSearchboxVisible: ["Bool", "debugger.ui.variables-searchbox-visible"],
|
||||
pauseOnExceptions: ["Bool", "debugger.pause-on-exceptions"],
|
||||
ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"],
|
||||
sourceMapsEnabled: ["Bool", "debugger.source-maps-enabled"],
|
||||
editorTabSize: ["Int", "editor.tabsize"]
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
function SourcesView() {
|
||||
dumpn("SourcesView was instantiated");
|
||||
|
||||
this.prettyPrint = this.prettyPrint.bind(this);
|
||||
this._onEditorLoad = this._onEditorLoad.bind(this);
|
||||
this._onEditorUnload = this._onEditorUnload.bind(this);
|
||||
this._onEditorSelection = this._onEditorSelection.bind(this);
|
||||
|
@ -51,6 +52,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this._cbTextbox = document.getElementById("conditional-breakpoint-panel-textbox");
|
||||
this._editorDeck = document.getElementById("editor-deck");
|
||||
this._stopBlackBoxButton = document.getElementById("black-boxed-message-button");
|
||||
this._prettyPrintButton = document.getElementById("pretty-print");
|
||||
|
||||
window.on(EVENTS.EDITOR_LOADED, this._onEditorLoad, false);
|
||||
window.on(EVENTS.EDITOR_UNLOADED, this._onEditorUnload, false);
|
||||
|
@ -58,6 +60,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this.widget.addEventListener("click", this._onSourceClick, false);
|
||||
this.widget.addEventListener("check", this._onSourceCheck, false);
|
||||
this._stopBlackBoxButton.addEventListener("click", this._onStopBlackBoxing, false);
|
||||
this._prettyPrintButton.addEventListener("click", this.prettyPrint, false);
|
||||
this._cbPanel.addEventListener("popupshowing", this._onConditionalPopupShowing, false);
|
||||
this._cbPanel.addEventListener("popupshown", this._onConditionalPopupShown, false);
|
||||
this._cbPanel.addEventListener("popuphiding", this._onConditionalPopupHiding, false);
|
||||
|
@ -82,6 +85,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this.widget.removeEventListener("click", this._onSourceClick, false);
|
||||
this.widget.removeEventListener("check", this._onSourceCheck, false);
|
||||
this._stopBlackBoxButton.removeEventListener("click", this._onStopBlackBoxing, false);
|
||||
this._prettyPrintButton.removeEventListener("click", this.prettyPrint, false);
|
||||
this._cbPanel.removeEventListener("popupshowing", this._onConditionalPopupShowing, false);
|
||||
this._cbPanel.removeEventListener("popupshowing", this._onConditionalPopupShown, false);
|
||||
this._cbPanel.removeEventListener("popuphiding", this._onConditionalPopupHiding, false);
|
||||
|
@ -371,6 +375,25 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this._hideConditionalPopup();
|
||||
},
|
||||
|
||||
/**
|
||||
* Pretty print the selected source.
|
||||
*/
|
||||
prettyPrint: function() {
|
||||
const resetEditor = () => {
|
||||
// Only set the text when the source is still selected.
|
||||
if (this.selectedValue === source.url) {
|
||||
DebuggerView.setEditorLocation(source.url, 0, { force: true });
|
||||
}
|
||||
};
|
||||
|
||||
let { source } = this.selectedItem.attachment;
|
||||
// Reset the editor even when we fail, so that we can give the user a clue
|
||||
// as to why the source isn't pretty printed and what happened.
|
||||
DebuggerController.SourceScripts.prettyPrint(source)
|
||||
.then(resetEditor,
|
||||
resetEditor);
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks a breakpoint as selected in this sources container.
|
||||
*
|
||||
|
|
|
@ -271,12 +271,16 @@ let DebuggerView = {
|
|||
*
|
||||
* @param object aSource
|
||||
* The source object coming from the active thread.
|
||||
* @param object aFlags
|
||||
* Additional options for setting the source. Supported options:
|
||||
* - force: boolean allowing whether we can get the selected url's
|
||||
* text again.
|
||||
* @return object
|
||||
* A promise that is resolved after the source text has been set.
|
||||
*/
|
||||
_setEditorSource: function(aSource) {
|
||||
_setEditorSource: function(aSource, aFlags={}) {
|
||||
// Avoid setting the same source text in the editor again.
|
||||
if (this._editorSource.url == aSource.url) {
|
||||
if (this._editorSource.url == aSource.url && !aFlags.force) {
|
||||
return this._editorSource.promise;
|
||||
}
|
||||
|
||||
|
@ -332,6 +336,8 @@ let DebuggerView = {
|
|||
* - columnOffset: column offset for the caret or debug location
|
||||
* - noCaret: don't set the caret location at the specified line
|
||||
* - noDebug: don't set the debug location at the specified line
|
||||
* - force: boolean allowing whether we can get the selected url's
|
||||
* text again.
|
||||
* @return object
|
||||
* A promise that is resolved after the source text has been set.
|
||||
*/
|
||||
|
@ -356,7 +362,7 @@ let DebuggerView = {
|
|||
|
||||
// Make sure the requested source client is shown in the editor, then
|
||||
// update the source editor's caret position and debug location.
|
||||
return this._setEditorSource(sourceForm).then(() => {
|
||||
return this._setEditorSource(sourceForm, aFlags).then(() => {
|
||||
// Line numbers in the source editor should start from 1. If invalid
|
||||
// or not specified, then don't do anything.
|
||||
if (aLine < 1) {
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
<commandset id="sourceEditorCommands"/>
|
||||
|
||||
<commandset id="debuggerCommands">
|
||||
<command id="prettyPrintCommand"
|
||||
oncommand="DebuggerView.Sources.prettyPrint()"/>
|
||||
<command id="unBlackBoxButton"
|
||||
oncommand="DebuggerView.Sources._onStopBlackBoxing()"/>
|
||||
<command id="nextSourceCommand"
|
||||
|
@ -139,6 +141,9 @@
|
|||
accesskey="&debuggerUI.focusVariables.key;"
|
||||
key="variablesFocusKey"
|
||||
command="variablesFocusCommand"/>
|
||||
<menuitem id="se-dbg-cMenu-prettyPrint"
|
||||
label="&debuggerUI.sources.prettyPrint;"
|
||||
command="prettyPrintCommand"/>
|
||||
</menupopup>
|
||||
<menupopup id="debuggerWatchExpressionsContextMenu">
|
||||
<menuitem id="add-watch-expression"
|
||||
|
@ -314,8 +319,18 @@
|
|||
<scrollbox id="globalsearch" orient="vertical" hidden="true"/>
|
||||
<splitter class="devtools-horizontal-splitter" hidden="true"/>
|
||||
<hbox flex="1">
|
||||
<vbox id="sources-pane">
|
||||
<vbox id="sources" flex="1"/>
|
||||
<vbox id="sources-container">
|
||||
<vbox id="sources-pane" flex="1">
|
||||
<vbox id="sources" flex="1"/>
|
||||
</vbox>
|
||||
<toolbar id="sources-toolbar" class="devtools-toolbar">
|
||||
<toolbarbutton id="pretty-print"
|
||||
tooltiptext="&debuggerUI.sources.prettyPrint;"
|
||||
class="devtools-toolbarbutton devtools-monospace"
|
||||
command="prettyPrintCommand"
|
||||
value="{}">
|
||||
</toolbarbutton>
|
||||
</toolbar>
|
||||
</vbox>
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
<deck id="editor-deck" flex="1" selectedIndex="0">
|
||||
|
|
|
@ -50,6 +50,10 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_dbg_pause-exceptions-02.js \
|
||||
browser_dbg_pause-resume.js \
|
||||
browser_dbg_pause-warning.js \
|
||||
browser_dbg_pretty-print-01.js \
|
||||
browser_dbg_pretty-print-02.js \
|
||||
browser_dbg_pretty-print-03.js \
|
||||
browser_dbg_pretty-print-04.js \
|
||||
browser_dbg_progress-listener-bug.js \
|
||||
browser_dbg_reload-preferred-script-01.js \
|
||||
browser_dbg_reload-preferred-script-02.js \
|
||||
|
@ -143,6 +147,7 @@ MOCHITEST_BROWSER_PAGES = \
|
|||
doc_large-array-buffer.html \
|
||||
doc_minified.html \
|
||||
doc_pause-exceptions.html \
|
||||
doc_pretty-print.html \
|
||||
doc_recursion-stack.html \
|
||||
doc_script-switching-01.html \
|
||||
doc_script-switching-02.html \
|
||||
|
@ -166,6 +171,7 @@ MOCHITEST_BROWSER_PAGES = \
|
|||
code_script-switching-01.js \
|
||||
code_script-switching-02.js \
|
||||
code_test-editor-mode \
|
||||
code_ugly.js \
|
||||
testactors.js \
|
||||
addon1.xpi \
|
||||
addon2.xpi \
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that clicking the pretty print button prettifies the source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceShown(gPanel, "code_ugly.js")
|
||||
.then(testSourceIsUgly)
|
||||
.then(() => {
|
||||
const finished = waitForSourceShown(gPanel, "code_ugly.js");
|
||||
clickPrettyPrintButton();
|
||||
return finished;
|
||||
})
|
||||
.then(testSourceIsPretty)
|
||||
.then(testSourceIsStillPretty)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
function clickPrettyPrintButton() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.getElementById("pretty-print"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
function testSourceIsStillPretty() {
|
||||
const deferred = promise.defer();
|
||||
|
||||
const { source } = gSources.selectedItem.attachment;
|
||||
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
|
||||
ok(text.contains("\n "),
|
||||
"Subsequent calls to getText return the pretty printed source.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that right clicking and selecting the pretty print context menu
|
||||
* item prettifies the source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gContextMenu;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
|
||||
|
||||
waitForSourceShown(gPanel, "code_ugly.js")
|
||||
.then(() => {
|
||||
const finished = waitForSourceShown(gPanel, "code_ugly.js");
|
||||
selectContextMenuItem();
|
||||
return finished;
|
||||
})
|
||||
.then(testSourceIsPretty)
|
||||
.then(closeDebuggerAndFinish.bind(null, gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function selectContextMenuItem() {
|
||||
once(gContextMenu, "popupshown").then(() => {
|
||||
const menuItem = gDebugger.document.getElementById("se-dbg-cMenu-prettyPrint");
|
||||
menuItem.click();
|
||||
});
|
||||
gContextMenu.openPopup(gEditor.editorElement, "overlap", 0, 0, true, false);
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gContextMenu = null;
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that we have the correct line selected after pretty printing.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_ugly.js")
|
||||
.then(runCodeAndPause)
|
||||
.then(() => {
|
||||
const sourceShown = waitForSourceShown(gPanel, "code_ugly.js");
|
||||
const caretUpdated = waitForCaretUpdated(gPanel, 7);
|
||||
const finished = promise.all([sourceShown, caretUpdated]);
|
||||
clickPrettyPrintButton();
|
||||
return finished;
|
||||
})
|
||||
.then(resumeDebuggerThenCloseAndFinish.bind(null, gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runCodeAndPause() {
|
||||
const deferred = promise.defer();
|
||||
once(gDebugger.gThreadClient, "paused").then(deferred.resolve);
|
||||
// Have to executeSoon so that we don't pause before this function returns.
|
||||
executeSoon(gDebuggee.foo);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function clickPrettyPrintButton() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.getElementById("pretty-print"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
|
@ -0,0 +1,74 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the function searching works with pretty printed sources.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSearchBox;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
|
||||
|
||||
waitForSourceShown(gPanel, "code_ugly.js")
|
||||
.then(testUglySearch)
|
||||
.then(() => {
|
||||
const finished = waitForSourceShown(gPanel, "code_ugly.js");
|
||||
clickPrettyPrintButton();
|
||||
return finished;
|
||||
})
|
||||
.then(testPrettyPrintedSearch)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testUglySearch() {
|
||||
const deferred = promise.defer();
|
||||
|
||||
once(gDebugger, "popupshown").then(() => {
|
||||
ok(isCaretPos(gPanel, 2, 10),
|
||||
"The bar function's non-pretty-printed location should be shown.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
setText(gSearchBox, "@bar");
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function clickPrettyPrintButton() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.getElementById("pretty-print"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testPrettyPrintedSearch() {
|
||||
const deferred = promise.defer();
|
||||
|
||||
once(gDebugger, "popupshown").then(() => {
|
||||
ok(isCaretPos(gPanel, 6, 10),
|
||||
"The bar function's pretty printed location should be shown.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
setText(gSearchBox, "@bar");
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSearchBox = null;
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
function foo() { var a=1; var b=2; bar(a, b); }
|
||||
function bar(c, d) { debugger; }
|
||||
foo();
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger Pretty Printing Test Page</title>
|
||||
</head>
|
||||
<script src="code_ugly.js"></script>
|
|
@ -16,6 +16,7 @@ let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
|||
let { Promise: promise } = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
|
||||
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
|
||||
let { BrowserDebuggerProcess } = Cu.import("resource:///modules/devtools/DebuggerProcess.jsm", {});
|
||||
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
|
||||
|
|
|
@ -93,6 +93,16 @@ Parser.prototype = {
|
|||
this._cache.clear();
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the AST for a particular source.
|
||||
*
|
||||
* @param String aUrl
|
||||
* The URL of the source that is being cleared.
|
||||
*/
|
||||
clearSource: function P_clearSource(aUrl) {
|
||||
this._cache.delete(aUrl);
|
||||
},
|
||||
|
||||
_cache: null
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
- the button that opens up an options context menu for the debugger UI. -->
|
||||
<!ENTITY debuggerUI.optsButton.tooltip "Debugger Options">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.sources.prettyPrint): This is the tooltip for the
|
||||
button that pretty prints the selected source. -->
|
||||
<!ENTITY debuggerUI.sources.prettyPrint "Prettify Source">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.pauseExceptions): This is the label for the
|
||||
- checkbox that toggles pausing on exceptions. -->
|
||||
<!ENTITY debuggerUI.pauseExceptions "Pause on exceptions">
|
||||
|
|
|
@ -13,10 +13,14 @@
|
|||
min-width: 50px;
|
||||
}
|
||||
|
||||
#sources-pane + .devtools-side-splitter {
|
||||
#sources-container + .devtools-side-splitter {
|
||||
-moz-border-start-color: transparent;
|
||||
}
|
||||
|
||||
#pretty-print {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox {
|
||||
-moz-appearance: none;
|
||||
-moz-margin-end: -6px;
|
||||
|
|
|
@ -15,10 +15,14 @@
|
|||
min-width: 50px;
|
||||
}
|
||||
|
||||
#sources-pane + .devtools-side-splitter {
|
||||
#sources-container + .devtools-side-splitter {
|
||||
-moz-border-start-color: transparent;
|
||||
}
|
||||
|
||||
#pretty-print {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox {
|
||||
-moz-appearance: none;
|
||||
-moz-margin-end: -6px;
|
||||
|
|
|
@ -13,10 +13,14 @@
|
|||
min-width: 50px;
|
||||
}
|
||||
|
||||
#sources-pane + .devtools-side-splitter {
|
||||
#sources-container + .devtools-side-splitter {
|
||||
-moz-border-start-color: transparent;
|
||||
}
|
||||
|
||||
#pretty-print {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox {
|
||||
-moz-appearance: none;
|
||||
-moz-margin-end: -6px;
|
||||
|
|
|
@ -12,6 +12,7 @@ var gSource;
|
|||
function run_test() {
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-pretty-print");
|
||||
gDebuggee.noop = x => x;
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function() {
|
||||
attachTestTabAndResume(gClient, "test-pretty-print", function(aResponse, aTabClient, aThreadClient) {
|
||||
|
@ -22,9 +23,15 @@ function run_test() {
|
|||
do_test_pending();
|
||||
}
|
||||
|
||||
const CODE = "" + function main() { debugger; return 10; };
|
||||
const CODE = "" + function main() { var a = 1; debugger; noop(a); return 10; };
|
||||
const CODE_URL = "data:text/javascript," + CODE;
|
||||
|
||||
const BP_LOCATION = {
|
||||
url: CODE_URL,
|
||||
line: 5,
|
||||
column: 2
|
||||
};
|
||||
|
||||
function evalCode() {
|
||||
gClient.addOneTimeListener("newSource", prettyPrintSource);
|
||||
Cu.evalInSandbox(
|
||||
|
@ -47,21 +54,41 @@ function runCode({ error }) {
|
|||
gDebuggee.main();
|
||||
}
|
||||
|
||||
function testDbgStatement(event, { frame }) {
|
||||
function testDbgStatement(event, { why, frame }) {
|
||||
do_check_eq(why.type, "debuggerStatement");
|
||||
const { url, line, column } = frame.where;
|
||||
do_check_eq(url, CODE_URL);
|
||||
do_check_eq(line, 2);
|
||||
do_check_eq(column, 2);
|
||||
testStepping();
|
||||
do_check_eq(line, 3);
|
||||
setBreakpoint();
|
||||
}
|
||||
|
||||
function setBreakpoint() {
|
||||
gThreadClient.setBreakpoint(BP_LOCATION, ({ error, actualLocation }) => {
|
||||
do_check_true(!error);
|
||||
do_check_true(!actualLocation);
|
||||
testStepping();
|
||||
});
|
||||
}
|
||||
|
||||
function testStepping() {
|
||||
gClient.addOneTimeListener("paused", (event, { frame }) => {
|
||||
const { url, line, column } = frame.where;
|
||||
gClient.addOneTimeListener("paused", (event, { why, frame }) => {
|
||||
do_check_eq(why.type, "resumeLimit");
|
||||
const { url, line } = frame.where;
|
||||
do_check_eq(url, CODE_URL);
|
||||
do_check_eq(line, 3);
|
||||
do_check_eq(column, 2);
|
||||
finishClient(gClient);
|
||||
do_check_eq(line, 4);
|
||||
testHitBreakpoint();
|
||||
});
|
||||
gThreadClient.stepIn();
|
||||
}
|
||||
|
||||
function testHitBreakpoint() {
|
||||
gClient.addOneTimeListener("paused", (event, { why, frame }) => {
|
||||
do_check_eq(why.type, "breakpoint");
|
||||
const { url, line, column } = frame.where;
|
||||
do_check_eq(url, CODE_URL);
|
||||
do_check_eq(line, BP_LOCATION.line);
|
||||
do_check_eq(column, BP_LOCATION.column);
|
||||
finishClient(gClient);
|
||||
});
|
||||
gThreadClient.resume();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче