зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1634721 - [devtools] Preserve selected source context (original vs generated), even when stepping through non-source-mapped code. r=devtools-reviewers,bomsy
(Also removing source argument on the action as it is redundant with location.source) Differential Revision: https://phabricator.services.mozilla.com/D176899
This commit is contained in:
Родитель
921f58a1f0
Коммит
b188edf4f6
|
@ -224,6 +224,20 @@ describe("pause", () => {
|
|||
const store = createStore(client, {}, sourceMapLoaderMock);
|
||||
const { dispatch, getState } = store;
|
||||
|
||||
const originalSource = await dispatch(
|
||||
actions.newGeneratedSource(makeSource("foo-original"))
|
||||
);
|
||||
|
||||
const originalLocation = createLocation({
|
||||
source: originalSource,
|
||||
line: 3,
|
||||
column: 0,
|
||||
sourceActor: selectors.getFirstSourceActorForGeneratedSource(
|
||||
getState(),
|
||||
originalSource.id
|
||||
),
|
||||
});
|
||||
|
||||
const generatedSource = await dispatch(
|
||||
actions.newGeneratedSource(makeSource("foo"))
|
||||
);
|
||||
|
@ -241,19 +255,6 @@ describe("pause", () => {
|
|||
const { frames } = mockPauseInfo;
|
||||
client.getFrames = async () => frames;
|
||||
|
||||
const originalSource = await dispatch(
|
||||
actions.newGeneratedSource(makeSource("foo-original"))
|
||||
);
|
||||
|
||||
const originalLocation = createLocation({
|
||||
source: originalSource,
|
||||
line: 3,
|
||||
column: 0,
|
||||
sourceActor: selectors.getFirstSourceActorForGeneratedSource(
|
||||
getState(),
|
||||
originalSource.id
|
||||
),
|
||||
});
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
expect(selectors.getFrames(getState(), "FakeThread")).toEqual([
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
getSourceByURL,
|
||||
getPrettySource,
|
||||
getSelectedLocation,
|
||||
getSelectedSource,
|
||||
getShouldSelectOriginalLocation,
|
||||
canPrettyPrintSource,
|
||||
getIsCurrentThreadPaused,
|
||||
getSourceTextContent,
|
||||
|
@ -36,11 +36,15 @@ import {
|
|||
} from "../../selectors";
|
||||
|
||||
// This is only used by jest tests (and within this module)
|
||||
export const setSelectedLocation = (cx, source, location) => ({
|
||||
export const setSelectedLocation = (
|
||||
cx,
|
||||
location,
|
||||
shouldSelectOriginalLocation
|
||||
) => ({
|
||||
type: "SET_SELECTED_LOCATION",
|
||||
cx,
|
||||
source,
|
||||
location,
|
||||
shouldSelectOriginalLocation,
|
||||
});
|
||||
|
||||
// This is only used by jest tests (and within this module)
|
||||
|
@ -143,16 +147,24 @@ export function selectLocation(cx, location, { keepContext = true } = {}) {
|
|||
// If the currently selected source is original, we will
|
||||
// automatically map `location` to refer to the original source,
|
||||
// even if that used to refer only to the generated source.
|
||||
const selectedSource = getSelectedSource(getState());
|
||||
if (
|
||||
keepContext &&
|
||||
selectedSource &&
|
||||
selectedSource.isOriginal != isOriginalId(location.sourceId)
|
||||
) {
|
||||
// getRelatedMapLocation will just convert to the related generated/original location.
|
||||
// i.e if the original location is passed, the related generated location will be returned and vice versa.
|
||||
location = await getRelatedMapLocation(location, thunkArgs);
|
||||
source = location.source;
|
||||
let shouldSelectOriginalLocation = getShouldSelectOriginalLocation(
|
||||
getState()
|
||||
);
|
||||
if (keepContext) {
|
||||
if (shouldSelectOriginalLocation != isOriginalId(location.sourceId)) {
|
||||
// getRelatedMapLocation will convert to the related generated/original location.
|
||||
// i.e if the original location is passed, the related generated location will be returned and vice versa.
|
||||
location = await getRelatedMapLocation(location, thunkArgs);
|
||||
// Note that getRelatedMapLocation may return the exact same location.
|
||||
// For example, if the source-map is half broken, it may return a generated location
|
||||
// while we were selecting original locations. So we may be seeing bundles intermittently
|
||||
// when stepping through broken source maps. And we will see original sources when stepping
|
||||
// through functional original sources.
|
||||
|
||||
source = location.source;
|
||||
}
|
||||
} else {
|
||||
shouldSelectOriginalLocation = isOriginalId(location.sourceId);
|
||||
}
|
||||
|
||||
let sourceActor = location.sourceActor;
|
||||
|
@ -168,7 +180,7 @@ export function selectLocation(cx, location, { keepContext = true } = {}) {
|
|||
dispatch(addTab(source, sourceActor));
|
||||
}
|
||||
|
||||
dispatch(setSelectedLocation(cx, source, location));
|
||||
dispatch(setSelectedLocation(cx, location, shouldSelectOriginalLocation));
|
||||
|
||||
await dispatch(loadSourceText(cx, source, sourceActor));
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ describe("sources - new sources", () => {
|
|||
},
|
||||
],
|
||||
getOriginalLocations: async items => items,
|
||||
getOriginalLocation: location => location,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -104,6 +105,7 @@ describe("sources - new sources", () => {
|
|||
{
|
||||
getOriginalURLs,
|
||||
getOriginalLocations: async items => items,
|
||||
getOriginalLocation: location => location,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -119,6 +121,7 @@ describe("sources - new sources", () => {
|
|||
{
|
||||
getOriginalURLs: async () => new Promise(_ => {}),
|
||||
getOriginalLocations: async items => items,
|
||||
getOriginalLocation: location => location,
|
||||
}
|
||||
);
|
||||
await dispatch(
|
||||
|
|
|
@ -105,7 +105,7 @@ describe("sources", () => {
|
|||
it("should open a tab for the source", async () => {
|
||||
const { dispatch, getState, cx } = createStore(mockCommandClient);
|
||||
await dispatch(actions.newGeneratedSource(makeSource("foo.js")));
|
||||
dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
|
||||
const tabs = getSourceTabs(getState());
|
||||
expect(tabs).toHaveLength(1);
|
||||
|
@ -181,7 +181,7 @@ describe("sources", () => {
|
|||
const location = createLocation({ source });
|
||||
|
||||
// set value
|
||||
dispatch(actions.setSelectedLocation(cx, source, location));
|
||||
dispatch(actions.setSelectedLocation(cx, location));
|
||||
expect(getSelectedLocation(getState())).toEqual({
|
||||
sourceId: source.id,
|
||||
...location,
|
||||
|
|
|
@ -96,6 +96,16 @@ export function initialSourcesState(state) {
|
|||
* See `createLocation` for the definition of this object.
|
||||
*/
|
||||
selectedLocation: undefined,
|
||||
|
||||
/**
|
||||
* By default, if we have a source-mapped source, we would automatically try
|
||||
* to select and show the content of the original source. But, if we explicitly
|
||||
* select a generated source, we remember this choice. That, until we explicitly
|
||||
* select an original source.
|
||||
* Note that selections related to non-source-mapped sources should never
|
||||
* change this setting.
|
||||
*/
|
||||
shouldSelectOriginalLocation: true,
|
||||
};
|
||||
/* eslint-disable sort-keys */
|
||||
}
|
||||
|
@ -114,7 +124,7 @@ function update(state = initialSourcesState(), action) {
|
|||
case "SET_SELECTED_LOCATION": {
|
||||
let pendingSelectedLocation = null;
|
||||
|
||||
if (action.source.url) {
|
||||
if (action.location.source.url) {
|
||||
pendingSelectedLocation = createPendingSelectedLocation(
|
||||
action.location
|
||||
);
|
||||
|
@ -125,6 +135,7 @@ function update(state = initialSourcesState(), action) {
|
|||
...state,
|
||||
selectedLocation: action.location,
|
||||
pendingSelectedLocation,
|
||||
shouldSelectOriginalLocation: action.shouldSelectOriginalLocation,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,10 @@ export function getSelectedSourceId(state) {
|
|||
return source?.id;
|
||||
}
|
||||
|
||||
export function getShouldSelectOriginalLocation(state) {
|
||||
return state.sources.shouldSelectOriginalLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first source actor for the source and/or thread
|
||||
* provided.
|
||||
|
@ -150,6 +154,10 @@ export function getFirstSourceActorForGeneratedSource(
|
|||
threadId
|
||||
) {
|
||||
let source = getSource(state, sourceId);
|
||||
// The source may have been removed if we are being called by async code
|
||||
if (!source) {
|
||||
return null;
|
||||
}
|
||||
if (source.isOriginal) {
|
||||
source = getSource(state, originalToGeneratedId(source.id));
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ skip-if = http3 # Bug 1829298
|
|||
skip-if =
|
||||
win11_2009 # Bug 1798331
|
||||
http3 # Bug 1829298
|
||||
[browser_dbg-features-breakpoints.js]
|
||||
skip-if = http3 # Bug 1829298
|
||||
[browser_dbg-features-source-tree.js]
|
||||
skip-if = http3 # Bug 1829298
|
||||
[browser_dbg-features-browser-toolbox-source-tree.js]
|
||||
|
|
|
@ -32,13 +32,14 @@ add_task(async function testBreakableLinesOverReloads() {
|
|||
// because the sourcemap replaces the content of the original file
|
||||
// and appends a few lines with a "WEBPACK FOOTER" comment
|
||||
// All the appended lines are empty lines or comments, so none of them are breakable.
|
||||
await assertBreakableLines(dbg, "original.js", 13, [
|
||||
await assertBreakableLines(dbg, "original.js", 15, [
|
||||
...getRange(1, 3),
|
||||
...getRange(5, 8),
|
||||
5,
|
||||
...getRange(8, 10),
|
||||
]);
|
||||
|
||||
info("Assert breakable lines of the simple first load of script.js");
|
||||
await assertBreakableLines(dbg, "script.js", 3, [1, 3]);
|
||||
await assertBreakableLines(dbg, "script.js", 9, [1, 5, 7, 8, 9]);
|
||||
|
||||
info("Assert breakable lines of the first iframe page load");
|
||||
await assertBreakableLines(dbg, "iframe.html", 30, [
|
||||
|
|
|
@ -11,7 +11,7 @@ const TEST_URL = testServer.urlFor("index.html");
|
|||
|
||||
// getTokenFromPosition pauses 0.5s for each line,
|
||||
// so this test is quite slow to complete
|
||||
requestLongerTimeout(2);
|
||||
requestLongerTimeout(4);
|
||||
|
||||
/**
|
||||
* Cover the breakpoints positions/columns:
|
||||
|
@ -56,26 +56,32 @@ add_task(async function testBreakableLinesOverReloads() {
|
|||
// because the sourcemap replaces the content of the original file
|
||||
// and appends a few lines with a "WEBPACK FOOTER" comment
|
||||
// All the appended lines are empty lines or comments, so none of them are breakable.
|
||||
await assertBreakablePositions(dbg, "original.js", 13, [
|
||||
await assertBreakablePositions(dbg, "original.js", 15, [
|
||||
{ line: 1, columns: [] },
|
||||
{ line: 2, columns: [2, 9, 32] },
|
||||
{ line: 3, columns: [] },
|
||||
{ line: 5, columns: [] },
|
||||
{ line: 6, columns: [2, 8] },
|
||||
{ line: 7, columns: [2, 10] },
|
||||
{ line: 8, columns: [] },
|
||||
{ line: 8, columns: [2, 8] },
|
||||
{ line: 9, columns: [2, 10] },
|
||||
{ line: 10, columns: [] },
|
||||
]);
|
||||
|
||||
info("Assert breakable lines of the simple first load of script.js");
|
||||
await assertBreakablePositions(dbg, "script.js", 3, [
|
||||
await assertBreakablePositions(dbg, "script.js", 9, [
|
||||
{ line: 1, columns: [0, 8] },
|
||||
{ line: 3, columns: [] },
|
||||
{ line: 5, columns: [2, 10] },
|
||||
{ line: 7, columns: [2, 9] },
|
||||
{ line: 8, columns: [] },
|
||||
{ line: 9, columns: [] },
|
||||
]);
|
||||
|
||||
info("Pretty print first load of script.js and assert breakable lines");
|
||||
await prettyPrint(dbg);
|
||||
await assertBreakablePositions(dbg, "script.js:formatted", 3, [
|
||||
await assertBreakablePositions(dbg, "script.js:formatted", 8, [
|
||||
{ line: 1, columns: [0, 8] },
|
||||
{ line: 4, columns: [2, 10] },
|
||||
{ line: 6, columns: [2, 9] },
|
||||
{ line: 7, columns: [] },
|
||||
]);
|
||||
await closeTab(dbg, "script.js:formatted");
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Assert that breakpoints and stepping works in various conditions
|
||||
*/
|
||||
|
||||
const testServer = createVersionizedHttpTestServer(
|
||||
"examples/sourcemaps-reload-uncompressed"
|
||||
);
|
||||
const TEST_URL = testServer.urlFor("index.html");
|
||||
|
||||
add_task(
|
||||
async function testSteppingFromOriginalToGeneratedAndAnotherOriginal() {
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URL,
|
||||
"index.html",
|
||||
"script.js",
|
||||
"original.js"
|
||||
);
|
||||
|
||||
await selectSource(dbg, "original.js");
|
||||
await addBreakpoint(dbg, "original.js", 8);
|
||||
assertBreakpointSnippet(dbg, 1, "await nonSourceMappedFunction();");
|
||||
|
||||
info("Test pausing on an original source");
|
||||
invokeInTab("foo");
|
||||
await waitForPaused(dbg, "original.js");
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 8);
|
||||
|
||||
info("Then stepping into a generated source");
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 5);
|
||||
|
||||
info("Stepping another time within the same generated source");
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 7);
|
||||
|
||||
info("And finally stepping into another original source");
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(
|
||||
dbg,
|
||||
findSource(dbg, "removed-original.js").id,
|
||||
4
|
||||
);
|
||||
|
||||
info("Walk up the stack backward, until we resume execution");
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(
|
||||
dbg,
|
||||
findSource(dbg, "removed-original.js").id,
|
||||
5
|
||||
);
|
||||
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 8);
|
||||
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 9);
|
||||
|
||||
await stepIn(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 10);
|
||||
|
||||
// We can't use the `stepIn` helper as this last step will resume
|
||||
// and the helper is expecting to pause again
|
||||
await dbg.actions.stepIn(getThreadContext(dbg));
|
||||
await assertNotPaused(dbg);
|
||||
}
|
||||
);
|
|
@ -41,7 +41,7 @@ add_task(async function test() {
|
|||
await stepIn(dbg);
|
||||
await stepIn(dbg);
|
||||
|
||||
// Switch to original source
|
||||
await dbg.actions.jumpToMappedSelectedLocation(getContext(dbg));
|
||||
// Note that we are asserting against an original source here,
|
||||
// See earlier comment about paused in bundle.js
|
||||
assertPausedAtSourceAndLine(dbg, findSource(dbg, "step-in-test.js").id, 7679);
|
||||
});
|
||||
|
|
|
@ -19,13 +19,13 @@ add_task(async function() {
|
|||
|
||||
info("Test reloading the debugger");
|
||||
await reload(dbg, "simple1.js", "simple2.js");
|
||||
is(countTabs(dbg), 2);
|
||||
await waitForSelectedSource(dbg, "simple2.js");
|
||||
is(countTabs(dbg), 2);
|
||||
|
||||
info("Test reloading the debuggee a second time");
|
||||
await reload(dbg, "simple1.js", "simple2.js");
|
||||
is(countTabs(dbg), 2);
|
||||
await waitForSelectedSource(dbg, "simple2.js");
|
||||
is(countTabs(dbg), 2);
|
||||
});
|
||||
|
||||
add_task(async function() {
|
||||
|
|
|
@ -166,6 +166,7 @@ add_task(async function() {
|
|||
);
|
||||
dbg.actions.selectThread(getContext(dbg), iframeThread);
|
||||
await waitForPausedThread(dbg, iframeThread);
|
||||
await waitForSelectedSource(dbg, source);
|
||||
assertPausedAtSourceAndLine(dbg, source.id, 3);
|
||||
|
||||
info("Resume the iframe target");
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n,t){e.exports=t(1)},function(e,n){window.bar=function(){return new Promise(e=>setTimeout(e,100))},window.foo=async function(){await bar(),console.log("YO")}}]);
|
||||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n,t){e.exports=t(1)},function(e,n){window.bar=function(){return new Promise(e=>setTimeout(e,100))},window.foo=async function(){await nonSourceMappedFunction(),console.log("YO")}}]);
|
||||
//# sourceMappingURL=bundle.js.map
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -3,6 +3,8 @@ window.bar = function bar() {
|
|||
}
|
||||
|
||||
window.foo = async function foo() {
|
||||
await bar();
|
||||
// This will call a function from script.js, itself calling a function
|
||||
// from original-with-query.js
|
||||
await nonSourceMappedFunction();
|
||||
console.log("YO")
|
||||
}
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
console.log("only one breakable line");
|
||||
// And one non-breakable line
|
||||
|
||||
function nonSourceMappedFunction () {
|
||||
console.log("non source mapped function");
|
||||
// This will call a function from original-with-query.js
|
||||
return originalWithQuery();
|
||||
}
|
||||
|
|
|
@ -79,7 +79,9 @@ window.bar = function bar() {
|
|||
};
|
||||
|
||||
window.foo = async function foo() {
|
||||
await bar();
|
||||
// This will call a function from script.js, itself calling a function
|
||||
// from original-with-query.js
|
||||
await nonSourceMappedFunction();
|
||||
console.log("YO");
|
||||
};
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["webpack:///webpack/bootstrap 6fda1f7ea9ecbc1a2d5b","webpack:///./original.js"],"names":["window","bar","Promise","resolve","setTimeout","foo","console","log"],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,KAAK;QACL;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;QAEA;QACA;;;;;;;;;;;;;;AC7DAA,OAAOC,GAAP,GAAa,SAASA,GAAT,GAAe;AAC1B,SAAO,IAAIC,OAAJ,CAAYC,WAAWC,WAAWD,OAAX,EAAoB,GAApB,CAAvB,CAAP;AACD,CAFD;;AAIAH,OAAOK,GAAP,GAAa,eAAeA,GAAf,GAAqB;AAChC,QAAMJ,KAAN;AACAK,UAAQC,GAAR,CAAY,IAAZ;AACD,CAHD,C","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 6fda1f7ea9ecbc1a2d5b","window.bar = function bar() {\n return new Promise(resolve => setTimeout(resolve, 100))\n}\n\nwindow.foo = async function foo() {\n await bar();\n console.log(\"YO\")\n}\n\n\n\n// WEBPACK FOOTER //\n// ./original.js"],"sourceRoot":""}
|
||||
{"version":3,"sources":["webpack:///webpack/bootstrap d343aa81956b90d9f67e","webpack:///./original.js"],"names":["window","bar","Promise","resolve","setTimeout","foo","nonSourceMappedFunction","console","log"],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,KAAK;QACL;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;QAEA;QACA;;;;;;;;;;;;;;AC7DAA,OAAOC,GAAP,GAAa,SAASA,GAAT,GAAe;AAC1B,SAAO,IAAIC,OAAJ,CAAYC,WAAWC,WAAWD,OAAX,EAAoB,GAApB,CAAvB,CAAP;AACD,CAFD;;AAIAH,OAAOK,GAAP,GAAa,eAAeA,GAAf,GAAqB;AAChC;AACA;AACA,QAAMC,yBAAN;AACAC,UAAQC,GAAR,CAAY,IAAZ;AACD,CALD,C","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap d343aa81956b90d9f67e","window.bar = function bar() {\n return new Promise(resolve => setTimeout(resolve, 100))\n}\n\nwindow.foo = async function foo() {\n // This will call a function from script.js, itself calling a function\n // from original-with-query.js\n await nonSourceMappedFunction();\n console.log(\"YO\")\n}\n\n\n\n// WEBPACK FOOTER //\n// ./original.js"],"sourceRoot":""}
|
|
@ -3,6 +3,8 @@ window.bar = function bar() {
|
|||
}
|
||||
|
||||
window.foo = async function foo() {
|
||||
await bar();
|
||||
// This will call a function from script.js, itself calling a function
|
||||
// from original-with-query.js
|
||||
await nonSourceMappedFunction();
|
||||
console.log("YO")
|
||||
}
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
console.log("only one breakable line");
|
||||
// And one non-breakable line
|
||||
|
||||
function nonSourceMappedFunction () {
|
||||
console.log("non source mapped function");
|
||||
// This will call a function from removed-original.js
|
||||
return removedOriginal();
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ const INTEGRATION_TEST_PAGE_SOURCES = [
|
|||
// Webpack generated some extra sources:
|
||||
"bootstrap 3b1a221408fdde86aa49",
|
||||
"bootstrap a1ecee2f86e1d0ea3fb5",
|
||||
"bootstrap 6fda1f7ea9ecbc1a2d5b",
|
||||
"bootstrap d343aa81956b90d9f67e",
|
||||
// There is 3 occurences, one per target (main thread, worker and iframe).
|
||||
// But there is even more source actors (named evals and duplicated script tags).
|
||||
"same-url.sjs",
|
||||
|
|
|
@ -28,7 +28,7 @@ addIntegrationTask(async function testReloadingStableOriginalSource(
|
|||
|
||||
info("Add initial breakpoint");
|
||||
await selectSource(dbg, "original.js");
|
||||
await addBreakpoint(dbg, "original.js", 6);
|
||||
await addBreakpoint(dbg, "original.js", 8);
|
||||
|
||||
info("Check that only one breakpoint is set");
|
||||
is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists");
|
||||
|
@ -40,22 +40,24 @@ addIntegrationTask(async function testReloadingStableOriginalSource(
|
|||
|
||||
info("Check that the breakpoint location info is correct");
|
||||
let breakpoint = dbg.selectors.getBreakpointsList(dbg)[0];
|
||||
is(breakpoint.location.line, 6);
|
||||
is(breakpoint.location.line, 8);
|
||||
if (isCompressed) {
|
||||
is(breakpoint.generatedLocation.line, 1);
|
||||
is(breakpoint.generatedLocation.column, 1056);
|
||||
} else {
|
||||
is(breakpoint.generatedLocation.line, 82);
|
||||
is(breakpoint.generatedLocation.line, 84);
|
||||
}
|
||||
|
||||
const expectedOriginalFileContentOnBreakpointLine = "await bar();";
|
||||
const expectedGeneratedFileContentOnBreakpointLine = "await bar();";
|
||||
const expectedOriginalFileContentOnBreakpointLine =
|
||||
"await nonSourceMappedFunction();";
|
||||
const expectedGeneratedFileContentOnBreakpointLine =
|
||||
"await nonSourceMappedFunction();";
|
||||
|
||||
info("Check that the breakpoint is displayed on the correct line in the ui");
|
||||
await assertBreakpoint(dbg, 6);
|
||||
await assertBreakpoint(dbg, 8);
|
||||
|
||||
info("Check that breakpoint is on the first line within the function `foo`");
|
||||
assertTextContentOnLine(dbg, 6, expectedOriginalFileContentOnBreakpointLine);
|
||||
assertTextContentOnLine(dbg, 8, expectedOriginalFileContentOnBreakpointLine);
|
||||
|
||||
info(
|
||||
"Check that the breakpoint is displayed in correct location in bundle.js (generated source)"
|
||||
|
@ -64,10 +66,10 @@ addIntegrationTask(async function testReloadingStableOriginalSource(
|
|||
if (isCompressed) {
|
||||
await assertBreakpoint(dbg, 1);
|
||||
} else {
|
||||
await assertBreakpoint(dbg, 82);
|
||||
await assertBreakpoint(dbg, 84);
|
||||
assertTextContentOnLine(
|
||||
dbg,
|
||||
82,
|
||||
84,
|
||||
expectedGeneratedFileContentOnBreakpointLine
|
||||
);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче