зеркало из https://github.com/mozilla/gecko-dev.git
Bug 849071 - Create some kind of chrome to turn source mapping on/off in the debugger, r=vporof
This commit is contained in:
Родитель
3400505bb7
Коммит
d3e7c334ed
|
@ -253,9 +253,7 @@ let DebuggerController = {
|
|||
if (aCallback) {
|
||||
aCallback();
|
||||
}
|
||||
}, {
|
||||
useSourceMaps: Services.prefs.getBoolPref("devtools.debugger.source-maps-enabled")
|
||||
});
|
||||
}, { useSourceMaps: Prefs.sourceMapsEnabled });
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -299,6 +297,29 @@ let DebuggerController = {
|
|||
if (aCallback) {
|
||||
aCallback();
|
||||
}
|
||||
}, { useSourceMaps: Prefs.sourceMapsEnabled });
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach and reattach to the thread actor with useSourceMaps true, blow
|
||||
* away old scripts and get sources again.
|
||||
*/
|
||||
reconfigureThread: function DC_reconfigureThread(aUseSourceMaps) {
|
||||
this.client.reconfigureThread(aUseSourceMaps, (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
let msg = "Couldn't reconfigure thread: " + aResponse.message;
|
||||
Cu.reportError(msg);
|
||||
dumpn(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the source list widget.
|
||||
DebuggerView.Sources.empty();
|
||||
SourceUtils.clearCache();
|
||||
this.SourceScripts._handleTabNavigation();
|
||||
// Update the stack frame list.
|
||||
this.activeThread._clearFrames();
|
||||
this.activeThread.fillFrames(CALL_STACK_PAGE_SIZE);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1659,6 +1680,7 @@ let Prefs = new ViewHelpers.Prefs("devtools.debugger", {
|
|||
variablesSortingEnabled: ["Bool", "ui.variables-sorting-enabled"],
|
||||
variablesOnlyEnumVisible: ["Bool", "ui.variables-only-enum-visible"],
|
||||
variablesSearchboxVisible: ["Bool", "ui.variables-searchbox-visible"],
|
||||
sourceMapsEnabled: ["Bool", "source-maps-enabled"],
|
||||
remoteHost: ["Char", "remote-host"],
|
||||
remotePort: ["Int", "remote-port"],
|
||||
remoteAutoConnect: ["Bool", "remote-autoconnect"],
|
||||
|
|
|
@ -187,6 +187,7 @@ function OptionsView() {
|
|||
this._toggleShowPanesOnStartup = this._toggleShowPanesOnStartup.bind(this);
|
||||
this._toggleShowVariablesOnlyEnum = this._toggleShowVariablesOnlyEnum.bind(this);
|
||||
this._toggleShowVariablesFilterBox = this._toggleShowVariablesFilterBox.bind(this);
|
||||
this._toggleShowOriginalSource = this._toggleShowOriginalSource.bind(this);
|
||||
}
|
||||
|
||||
OptionsView.prototype = {
|
||||
|
@ -201,11 +202,13 @@ OptionsView.prototype = {
|
|||
this._showPanesOnStartupItem = document.getElementById("show-panes-on-startup");
|
||||
this._showVariablesOnlyEnumItem = document.getElementById("show-vars-only-enum");
|
||||
this._showVariablesFilterBoxItem = document.getElementById("show-vars-filter-box");
|
||||
this._showOriginalSourceItem = document.getElementById("show-original-source");
|
||||
|
||||
this._pauseOnExceptionsItem.setAttribute("checked", Prefs.pauseOnExceptions);
|
||||
this._showPanesOnStartupItem.setAttribute("checked", Prefs.panesVisibleOnStartup);
|
||||
this._showVariablesOnlyEnumItem.setAttribute("checked", Prefs.variablesOnlyEnumVisible);
|
||||
this._showVariablesFilterBoxItem.setAttribute("checked", Prefs.variablesSearchboxVisible);
|
||||
this._showOriginalSourceItem.setAttribute("checked", Prefs.sourceMapsEnabled);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -262,10 +265,21 @@ OptionsView.prototype = {
|
|||
this._showVariablesFilterBoxItem.getAttribute("checked") == "true";
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener handling the 'show original source' menuitem command.
|
||||
*/
|
||||
_toggleShowOriginalSource: function DVO__toggleShowOriginalSource() {
|
||||
let pref = Prefs.sourceMapsEnabled =
|
||||
this._showOriginalSourceItem.getAttribute("checked") == "true";
|
||||
|
||||
DebuggerController.reconfigureThread(pref);
|
||||
},
|
||||
|
||||
_button: null,
|
||||
_pauseOnExceptionsItem: null,
|
||||
_showPanesOnStartupItem: null,
|
||||
_showVariablesOnlyEnumItem: null,
|
||||
_showOriginalSourceItem: null,
|
||||
_showVariablesFilterBoxItem: null
|
||||
};
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
oncommand="DebuggerView.Options._toggleShowVariablesOnlyEnum()"/>
|
||||
<command id="toggleShowVariablesFilterBox"
|
||||
oncommand="DebuggerView.Options._toggleShowVariablesFilterBox()"/>
|
||||
<command id="toggleShowOriginalSource"
|
||||
oncommand="DebuggerView.Options._toggleShowOriginalSource()"/>
|
||||
</commandset>
|
||||
|
||||
<popupset id="debuggerPopupset">
|
||||
|
@ -160,6 +162,11 @@
|
|||
label="&debuggerUI.showVarsFilter;"
|
||||
accesskey="&debuggerUI.showVarsFilter.key;"
|
||||
command="toggleShowVariablesFilterBox"/>
|
||||
<menuitem id="show-original-source"
|
||||
type="checkbox"
|
||||
label="&debuggerUI.showOriginalSource;"
|
||||
accesskey="&debuggerUI.showOriginalSource.key;"
|
||||
command="toggleShowOriginalSource"/>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_dbg_progress-listener-bug.js \
|
||||
browser_dbg_chrome-debugging.js \
|
||||
browser_dbg_source_maps-01.js \
|
||||
browser_dbg_source_maps-02.js \
|
||||
head.js \
|
||||
helpers.js \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we can toggle between the original and generated sources.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "binary_search.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
var gPrevPref = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
gPrevPref = Services.prefs.getBoolPref(
|
||||
"devtools.debugger.source-maps-enabled");
|
||||
Services.prefs.setBoolPref("devtools.debugger.source-maps-enabled", true);
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onSourceShown(aEvent) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", _onSourceShown);
|
||||
// Show original sources should be already enabled.
|
||||
is(gPrevPref, false,
|
||||
"The source maps functionality should be disabled by default.");
|
||||
is(gDebugger.Prefs.sourceMapsEnabled, true,
|
||||
"The source maps pref should be true from startup.");
|
||||
is(gDebugger.DebuggerView.Options._showOriginalSourceItem.getAttribute("checked"),
|
||||
"true", "Source maps should be enabled from startup. ")
|
||||
|
||||
ok(aEvent.detail.url.indexOf(".coffee") != -1,
|
||||
"The debugger should show the source mapped coffee script file.");
|
||||
ok(aEvent.detail.url.indexOf(".js") == -1,
|
||||
"The debugger should not show the generated js script file.");
|
||||
ok(gDebugger.editor.getText().search(/isnt/) != -1,
|
||||
"The debugger's editor should have the coffee script source displayed.");
|
||||
ok(gDebugger.editor.getText().search(/function/) == -1,
|
||||
"The debugger's editor should not have the JS source displayed.");
|
||||
|
||||
testToggleGeneratedSource();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testToggleGeneratedSource() {
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onSourceShown(aEvent) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", _onSourceShown);
|
||||
|
||||
is(gDebugger.Prefs.sourceMapsEnabled, false,
|
||||
"The source maps pref should have been set to false.");
|
||||
is(gDebugger.DebuggerView.Options._showOriginalSourceItem.getAttribute("checked"),
|
||||
"false", "Source maps should be enabled from startup. ")
|
||||
|
||||
ok(aEvent.detail.url.indexOf(".coffee") == -1,
|
||||
"The debugger should not show the source mapped coffee script file.");
|
||||
ok(aEvent.detail.url.indexOf(".js") != -1,
|
||||
"The debugger should show the generated js script file.");
|
||||
ok(gDebugger.editor.getText().search(/isnt/) == -1,
|
||||
"The debugger's editor should have the coffee script source displayed.");
|
||||
ok(gDebugger.editor.getText().search(/function/) != -1,
|
||||
"The debugger's editor should not have the JS source displayed.");
|
||||
|
||||
testSetBreakpoint();
|
||||
});
|
||||
|
||||
// Disable source maps.
|
||||
gDebugger.DebuggerView.Options._showOriginalSourceItem.setAttribute("checked",
|
||||
"false");
|
||||
gDebugger.DebuggerView.Options._toggleShowOriginalSource();
|
||||
}
|
||||
|
||||
function testSetBreakpoint() {
|
||||
let { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.setBreakpoint({
|
||||
url: EXAMPLE_URL + "binary_search.js",
|
||||
line: 7
|
||||
}, function (aResponse, bpClient) {
|
||||
ok(!aResponse.error,
|
||||
"Should be able to set a breakpoint in a JavaScript file.");
|
||||
testHitBreakpoint();
|
||||
});
|
||||
}
|
||||
|
||||
function testHitBreakpoint() {
|
||||
let { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.resume(function (aResponse) {
|
||||
ok(!aResponse.error, "Shouldn't get an error resuming");
|
||||
is(aResponse.type, "resumed", "Type should be 'resumed'");
|
||||
|
||||
activeThread.addOneTimeListener("framesadded", function (aEvent, aPacket) {
|
||||
// Make sure that we have JavaScript stack frames.
|
||||
let frames = gDebugger.DebuggerView.StackFrames._container._list;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Correct number of frames.");
|
||||
ok(frames.querySelector("#stackframe-0 .dbg-stackframe-details")
|
||||
.getAttribute("value").search(/js/),
|
||||
"First frame should be a JS frame.");
|
||||
|
||||
waitForCaretPos(6, testToggleOnPause);
|
||||
});
|
||||
|
||||
// This will cause the breakpoint to be hit, and put us back in the paused
|
||||
// stated.
|
||||
executeSoon(function() {
|
||||
gDebuggee.binary_search([0, 2, 3, 5, 7, 10], 5);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testToggleOnPause() {
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onSourceShown(aEvent) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", _onSourceShown);
|
||||
|
||||
is(gDebugger.Prefs.sourceMapsEnabled, true,
|
||||
"The source maps pref should have been set to true.");
|
||||
is(gDebugger.DebuggerView.Options._showOriginalSourceItem.getAttribute("checked"),
|
||||
"true", "Source maps should be enabled. ")
|
||||
|
||||
ok(aEvent.detail.url.indexOf(".coffee") != -1,
|
||||
"The debugger should show the source mapped coffee script file.");
|
||||
ok(aEvent.detail.url.indexOf(".js") == -1,
|
||||
"The debugger should not show the generated js script file.");
|
||||
ok(gDebugger.editor.getText().search(/isnt/) != -1,
|
||||
"The debugger's editor should not have the coffee script source displayed.");
|
||||
ok(gDebugger.editor.getText().search(/function/) == -1,
|
||||
"The debugger's editor should have the JS source displayed.");
|
||||
|
||||
// Make sure that we have coffee script stack frames.
|
||||
let frames = gDebugger.DebuggerView.StackFrames._container._list;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Correct number of frames.");
|
||||
ok(frames.querySelector("#stackframe-0 .dbg-stackframe-details")
|
||||
.getAttribute("value").search(/coffee/),
|
||||
"First frame should be a coffee script frame.");
|
||||
|
||||
waitForCaretPos(4, resumeAndFinish);
|
||||
});
|
||||
|
||||
// Enable source maps.
|
||||
gDebugger.DebuggerView.Options._showOriginalSourceItem.setAttribute("checked",
|
||||
"true");
|
||||
gDebugger.DebuggerView.Options._toggleShowOriginalSource();
|
||||
}
|
||||
|
||||
function resumeAndFinish()
|
||||
{
|
||||
let { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.resume(function (aResponse) {
|
||||
ok(!aResponse.error, "Shouldn't get an error resuming");
|
||||
is(aResponse.type, "resumed", "Type should be 'resumed'");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
}
|
||||
|
||||
function waitForCaretPos(number, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the source editor line is active.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the line.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gDebugger.DebuggerView.editor.getCaretPosition().line != number) {
|
||||
return;
|
||||
}
|
||||
is(gDebugger.DebuggerView.editor.getCaretPosition().line, number,
|
||||
"The right line is focused.")
|
||||
// We got the source editor at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setBoolPref("devtools.debugger.source-maps-enabled", false);
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gPrevPref = null;
|
||||
});
|
|
@ -65,6 +65,12 @@
|
|||
<!ENTITY debuggerUI.showOnlyEnum "Show only enumerable properties">
|
||||
<!ENTITY debuggerUI.showOnlyEnum.key "P">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.showOriginalSource): This is the label for
|
||||
- the checkbox that toggles the display of original or sourcemap-derived
|
||||
- sources. -->
|
||||
<!ENTITY debuggerUI.showOriginalSource "Show original sources">
|
||||
<!ENTITY debuggerUI.showOriginalSource.key "O">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.searchPanelTitle): This is the text that
|
||||
- appears in the filter panel popup as a description. -->
|
||||
<!ENTITY debuggerUI.searchPanelTitle "Operators">
|
||||
|
|
|
@ -486,6 +486,23 @@ DebuggerClient.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Reconfigure a thread actor.
|
||||
*
|
||||
* @param boolean aUseSourceMaps
|
||||
* A flag denoting whether to use source maps or not.
|
||||
* @param function aOnResponse
|
||||
* Called with the response packet.
|
||||
*/
|
||||
reconfigureThread: function DC_reconfigureThread(aUseSourceMaps, aOnResponse) {
|
||||
let packet = {
|
||||
to: this.activeThread._actor,
|
||||
type: "reconfigure",
|
||||
options: { useSourceMaps: aUseSourceMaps }
|
||||
};
|
||||
this.request(packet, aOnResponse);
|
||||
},
|
||||
|
||||
/**
|
||||
* Release an object actor.
|
||||
*
|
||||
|
|
|
@ -253,6 +253,18 @@ ThreadActor.prototype = {
|
|||
};
|
||||
},
|
||||
|
||||
onReconfigure: function TA_onReconfigure(aRequest) {
|
||||
if (this.state == "exited") {
|
||||
return { error: "wrongState" };
|
||||
}
|
||||
|
||||
update(this._options, aRequest.options || {});
|
||||
// Clear existing sources, so they can be recreated on next access.
|
||||
this._sources = null;
|
||||
|
||||
return {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Pause the debuggee, by entering a nested event loop, and return a 'paused'
|
||||
* packet to the client.
|
||||
|
@ -1281,6 +1293,7 @@ ThreadActor.prototype = {
|
|||
ThreadActor.prototype.requestTypes = {
|
||||
"attach": ThreadActor.prototype.onAttach,
|
||||
"detach": ThreadActor.prototype.onDetach,
|
||||
"reconfigure": ThreadActor.prototype.onReconfigure,
|
||||
"resume": ThreadActor.prototype.onResume,
|
||||
"clientEvaluate": ThreadActor.prototype.onClientEvaluate,
|
||||
"frames": ThreadActor.prototype.onFrames,
|
||||
|
|
Загрузка…
Ссылка в новой задаче