Bug 1587839 - Pass the sourceId to sourcemap service subscribe callback. r=loganfsmyth.

The sourceId is then used in the various places where we call the sourcemap service.
A test is added in the console to make sure that we do navigate to the mapped
location in the debugger.

Differential Revision: https://phabricator.services.mozilla.com/D49103

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Chevobbe 2019-10-16 00:16:55 +00:00
Родитель 0b6d9f7d9c
Коммит 3469d5121d
14 изменённых файлов: 145 добавлений и 13 удалений

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

@ -321,10 +321,10 @@ SourceMapURLService.prototype._callOneCallback = async function(
const resolvedLocation = await subscriptionEntry.promise;
if (resolvedLocation) {
const { line, column, sourceUrl } = resolvedLocation;
const { line, column, sourceUrl, sourceId } = resolvedLocation;
// In case we're racing a pref change, pass the current value
// here, not plain "true".
callback(this._prefValue, sourceUrl, line, column);
callback(this._prefValue, sourceUrl, line, column, sourceId);
}
};

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

@ -29,8 +29,18 @@ add_task(async function() {
const service = toolbox.sourceMapURLService;
const cbCalls = [];
const cb = (...args) => cbCalls.push(args);
const expectedArgs = [true, ORIGINAL_URL, ORIGINAL_LINE, 0];
let sourceId;
const sourceIdIndex = 4;
const expectedArgs = [true, ORIGINAL_URL, ORIGINAL_LINE, 0, sourceId];
// There's no way we can know the sourceId, so we retrieve it from the subscribe
// callback.
const cb = (...args) => {
if (!sourceId) {
sourceId = args[sourceIdIndex];
expectedArgs[sourceIdIndex] = sourceId;
}
cbCalls.push(args);
};
const unsubscribe1 = service.subscribe(JS_URL, GENERATED_LINE, 1, cb);
await waitForSubscribtionsPromise(service);

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

@ -1474,8 +1474,10 @@ SelectorView.prototype = {
* The original line number
* @param {number} column
* The original column number
* @param {number} sourceId
* The original sourceId
*/
_updateLocation: function(enabled, url, line, column) {
_updateLocation: function(enabled, url, line, column, sourceId) {
if (!this.tree.element) {
return;
}
@ -1483,7 +1485,7 @@ SelectorView.prototype = {
// Update |currentLocation| to be whichever location is being
// displayed at the moment.
if (enabled) {
this.currentLocation = { href: url, line, column };
this.currentLocation = { href: url, line, column, sourceId };
} else {
this.currentLocation = this.generatedLocation;
}

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

@ -909,10 +909,15 @@ class Rule {
url,
line,
column,
(enabled, sourceUrl, sourceLine, sourceColumn) => {
(enabled, sourceUrl, sourceLine, sourceColumn, sourceId) => {
if (enabled) {
// Only update the source location if source map is in use.
this.updateSourceLocation(sourceUrl, sourceLine, sourceColumn);
this.updateSourceLocation(
sourceUrl,
sourceLine,
sourceColumn,
sourceId
);
}
}
);
@ -931,12 +936,15 @@ class Rule {
* The original line number.
* @param {number} column
* The original column number.
* @param {number} sourceId
* The original sourceId.
*/
updateSourceLocation(url, line, column) {
updateSourceLocation(url, line, column, sourceId) {
this._sourceLocation = {
column,
line,
url,
sourceId,
};
this.store.dispatch(
updateSourceLink(this.domRule.actorID, this.sourceLink)

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

@ -335,8 +335,10 @@ RuleEditor.prototype = {
* The original line number
* @param {number} column
* The original column number
* @param {number} sourceId
* The original sourceId
*/
_updateLocation: function(enabled, url, line, column) {
_updateLocation: function(enabled, url, line, column, sourceId) {
let displayURL = url;
if (!enabled) {
url = null;
@ -353,6 +355,7 @@ RuleEditor.prototype = {
url,
line,
column,
sourceId,
};
let sourceTextContent = CssLogic.shortSource({ href: displayURL });

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

@ -91,7 +91,7 @@ class Frame extends Component {
}
}
_locationChanged(isSourceMapped, url, line, column) {
_locationChanged(isSourceMapped, url, line, column, sourceId) {
const newState = {
isSourceMapped,
};
@ -101,6 +101,7 @@ class Frame extends Component {
line,
column,
functionDisplayName: this.props.frame.functionDisplayName,
sourceId,
};
}

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

@ -73,12 +73,19 @@ class SmartTrace extends Component {
new Promise(resolve => {
const { lineNumber, columnNumber, filename } = frame;
const source = filename.split(" -> ").pop();
const subscribeCallback = (isSourceMapped, url, line, column) => {
const subscribeCallback = (
isSourceMapped,
url,
line,
column,
sourceId
) => {
this.onSourceMapServiceChange(
isSourceMapped,
url,
line,
column,
sourceId,
index
);
resolve();
@ -171,6 +178,7 @@ class SmartTrace extends Component {
filename,
lineNumber,
columnNumber,
sourceId,
index
) {
if (isSourceMapped) {
@ -189,6 +197,7 @@ class SmartTrace extends Component {
filename,
lineNumber,
columnNumber,
sourceId,
})
.concat(stacktrace.slice(index + 1));

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

@ -101,7 +101,7 @@ EventTooltip.prototype = {
} else {
const location = this._parseLocation(text);
if (location) {
const callback = (enabled, url, line, column) => {
const callback = (enabled, url, line, column, sourceId) => {
// Do nothing if the tooltip was destroyed while we were
// waiting for a response.
if (this._tooltip) {

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

@ -49,6 +49,7 @@ support-files =
test-console-filter-by-regex-input.html
test-console-group.html
test-console-iframes.html
test-console-stacktrace-mapped.html
test-console-table.html
test-console-workers.html
test-console.html
@ -141,6 +142,9 @@ support-files =
test-sourcemap-error-01.js
test-sourcemap-error-02.html
test-sourcemap-error-02.js
test-sourcemap-original.js
test-sourcemap.min.js
test-sourcemap.min.js.map
test-stacktrace-location-debugger-link.html
test-subresource-security-error.html
test-subresource-security-error.js
@ -473,6 +477,7 @@ skip-if = verify
[browser_webconsole_split_persist.js]
[browser_webconsole_stacktrace_location_debugger_link.js]
[browser_webconsole_stacktrace_location_scratchpad_link.js]
[browser_webconsole_stacktrace_mapped_location_debugger_link.js]
[browser_webconsole_strict_mode_errors.js]
[browser_webconsole_string.js]
[browser_webconsole_stubs_console_api.js]

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

@ -0,0 +1,61 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that clicking on a location in a stacktrace for a source-mapped file displays its
// original source in the debugger. See Bug 1587839.
"use strict";
requestLongerTimeout(2);
const TEST_URI =
"http://example.com/browser/devtools/client/webconsole/test/browser/" +
"test-console-stacktrace-mapped.html";
const TEST_ORIGINAL_FILENAME = "test-sourcemap-original.js";
const TEST_ORIGINAL_URI =
"http://example.com/browser/devtools/client/webconsole/test/browser/" +
TEST_ORIGINAL_FILENAME;
add_task(async function() {
const hud = await openNewTabAndConsole(TEST_URI);
info("Print a stacktrace");
const onLoggedStacktrace = waitForMessage(hud, "console.trace");
ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
content.wrappedJSObject.logTrace();
});
const { node } = await onLoggedStacktrace;
info("Wait until the original frames are displayed");
await waitFor(() =>
Array.from(node.querySelectorAll(".stacktrace .filename"))
.map(frameEl => frameEl.textContent)
.includes(TEST_ORIGINAL_FILENAME)
);
info("Click on the frame.");
EventUtils.sendMouseEvent(
{ type: "mousedown" },
node.querySelector(".stacktrace .location")
);
info("Wait for the Debugger panel to open.");
const toolbox = hud.toolbox;
await toolbox.getPanelWhenReady("jsdebugger");
const dbg = createDebuggerContext(toolbox);
info("Wait for selected source");
await waitForSelectedSource(dbg, TEST_ORIGINAL_URI);
await waitForSelectedLocation(dbg, 15);
const pendingLocation = dbg.selectors.getPendingSelectedLocation();
const { url, line } = pendingLocation;
is(url, TEST_ORIGINAL_URI, "Debugger is open at the expected file");
is(line, 15, "Debugger is open at the expected line");
});

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

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf-8">
<title>Click on stacktrace location should point to source</title>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript" src="test-sourcemap.min.js"></script>
</head>
<body></body>
</html>

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

@ -0,0 +1,18 @@
/* eslint-disable */
/**
* this
* is
* a
* function
*/
function logString(str) {
console.log(str);
}
function logTrace() {
var logTraceInner = function() {
console.trace();
};
logTraceInner();
}

3
devtools/client/webconsole/test/browser/test-sourcemap.min.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
/* eslint-disable */
function logString(str){console.log(str)}function logTrace(){var logTraceInner=function(){console.trace()};logTraceInner()}
//# sourceMappingURL=test-sourcemap.min.js.map

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

@ -0,0 +1 @@
{"version":3,"sources":["test-sourcemap-original.js"],"names":["logString","str","console","log","logTrace","logTraceInner","trace"],"mappings":";AAQA,SAASA,UAAUC,KACjBC,QAAQC,IAAIF,KAGd,SAASG,WACP,IAAIC,cAAgB,WAClBH,QAAQI,SAEVD"}