chrome-devtools-frontend 1.0.1009019 → 1.0.1010492
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extension-api/ExtensionAPI.d.ts +8 -6
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/i18n/locales/en-US.json +16 -4
- package/front_end/core/i18n/locales/en-XL.json +16 -4
- package/front_end/core/sdk/CSSProperty.ts +3 -3
- package/front_end/core/sdk/DebuggerModel.ts +12 -3
- package/front_end/core/sdk/EmulationModel.ts +9 -3
- package/front_end/core/sdk/Script.ts +3 -2
- package/front_end/models/bindings/BreakpointManager.ts +58 -22
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +72 -65
- package/front_end/models/bindings/ResourceMapping.ts +43 -10
- package/front_end/models/bindings/ResourceScriptMapping.ts +13 -1
- package/front_end/models/extensions/ExtensionAPI.ts +15 -4
- package/front_end/models/extensions/ExtensionServer.ts +3 -3
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +18 -1
- package/front_end/models/persistence/Automapping.ts +18 -12
- package/front_end/models/persistence/PersistenceImpl.ts +10 -2
- package/front_end/models/workspace/WorkspaceImpl.ts +16 -9
- package/front_end/panels/application/DOMStorageItemsView.ts +6 -0
- package/front_end/panels/console/ConsoleViewMessage.ts +2 -1
- package/front_end/panels/sources/CallStackSidebarPane.ts +11 -4
- package/front_end/panels/sources/DebuggerPlugin.ts +51 -1
- package/front_end/ui/components/data_grid/DataGrid.ts +5 -0
- package/front_end/ui/components/data_grid/DataGridController.ts +5 -0
- package/front_end/ui/legacy/Infobar.ts +1 -0
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -1
- package/front_end/ui/legacy/infobar.css +17 -0
- package/package.json +1 -1
@@ -172,7 +172,8 @@ export namespace Chrome {
|
|
172
172
|
}
|
173
173
|
|
174
174
|
export interface RecorderExtensionPlugin {
|
175
|
-
stringify(
|
175
|
+
stringify(recording: Record<string, any>): Promise<string>;
|
176
|
+
stringifyStep(step: Record<string, any>): Promise<string>;
|
176
177
|
}
|
177
178
|
|
178
179
|
export interface LanguageExtensionPlugin {
|
@@ -180,7 +181,8 @@ export namespace Chrome {
|
|
180
181
|
* A new raw module has been loaded. If the raw wasm module references an external debug info module, its URL will be
|
181
182
|
* passed as symbolsURL.
|
182
183
|
*/
|
183
|
-
addRawModule(rawModuleId: string, symbolsURL: string|undefined, rawModule: RawModule):
|
184
|
+
addRawModule(rawModuleId: string, symbolsURL: string|undefined, rawModule: RawModule):
|
185
|
+
Promise<string[]|{missingSymbolFiles: string[]}>;
|
184
186
|
|
185
187
|
/**
|
186
188
|
* Find locations in raw modules from a location in a source file.
|
@@ -241,9 +243,8 @@ export namespace Chrome {
|
|
241
243
|
/**
|
242
244
|
* Find locations in source files from a location in a raw module
|
243
245
|
*/
|
244
|
-
getFunctionInfo(rawLocation: RawLocation):
|
245
|
-
|
246
|
-
}>;
|
246
|
+
getFunctionInfo(rawLocation: RawLocation):
|
247
|
+
Promise<{frames: Array<FunctionInfo>}|{missingSymbolFiles: Array<string>}>;
|
247
248
|
|
248
249
|
/**
|
249
250
|
* Find locations in raw modules corresponding to the inline function
|
@@ -278,7 +279,8 @@ export namespace Chrome {
|
|
278
279
|
}
|
279
280
|
|
280
281
|
export interface RecorderExtensions {
|
281
|
-
registerRecorderExtensionPlugin(plugin: RecorderExtensionPlugin, pluginName: string):
|
282
|
+
registerRecorderExtensionPlugin(plugin: RecorderExtensionPlugin, pluginName: string, mediaType: string):
|
283
|
+
Promise<void>;
|
282
284
|
unregisterRecorderExtensionPlugin(plugin: RecorderExtensionPlugin): Promise<void>;
|
283
285
|
}
|
284
286
|
|
@@ -939,7 +939,9 @@ export enum RecordingEdited {
|
|
939
939
|
export enum RecordingExported {
|
940
940
|
ToPuppeteer = 1,
|
941
941
|
ToJSON = 2,
|
942
|
-
|
942
|
+
ToPuppeteerReplay = 3,
|
943
|
+
ToExtension = 4,
|
944
|
+
MaxValue = 5,
|
943
945
|
}
|
944
946
|
|
945
947
|
/* eslint-disable @typescript-eslint/naming-convention */
|
@@ -1241,6 +1241,9 @@
|
|
1241
1241
|
"models/bindings/ContentProviderBasedProject.ts | unknownErrorLoadingFile": {
|
1242
1242
|
"message": "Unknown error loading file"
|
1243
1243
|
},
|
1244
|
+
"models/bindings/DebuggerLanguagePlugins.ts | debugSymbolsIncomplete": {
|
1245
|
+
"message": "The debug information for function {PH1} is incomplete"
|
1246
|
+
},
|
1244
1247
|
"models/bindings/DebuggerLanguagePlugins.ts | errorInDebuggerLanguagePlugin": {
|
1245
1248
|
"message": "Error in debugger language plugin: {PH1}"
|
1246
1249
|
},
|
@@ -1248,7 +1251,7 @@
|
|
1248
1251
|
"message": "[{PH1}] Failed to load debug symbols for {PH2} ({PH3})"
|
1249
1252
|
},
|
1250
1253
|
"models/bindings/DebuggerLanguagePlugins.ts | failedToLoadDebugSymbolsForFunction": {
|
1251
|
-
"message": "
|
1254
|
+
"message": "No debug information for function \"{PH1}\""
|
1252
1255
|
},
|
1253
1256
|
"models/bindings/DebuggerLanguagePlugins.ts | loadedDebugSymbolsForButDidnt": {
|
1254
1257
|
"message": "[{PH1}] Loaded debug symbols for {PH2}, but didn't find any source files"
|
@@ -1262,9 +1265,6 @@
|
|
1262
1265
|
"models/bindings/DebuggerLanguagePlugins.ts | loadingDebugSymbolsForVia": {
|
1263
1266
|
"message": "[{PH1}] Loading debug symbols for {PH2} (via {PH3})..."
|
1264
1267
|
},
|
1265
|
-
"models/bindings/DebuggerLanguagePlugins.ts | symbolFileNotFound": {
|
1266
|
-
"message": "Symbol file \"{PH1}\" not found"
|
1267
|
-
},
|
1268
1268
|
"models/bindings/ResourceScriptMapping.ts | liveEditCompileFailed": {
|
1269
1269
|
"message": "LiveEdit compile failed: {PH1}"
|
1270
1270
|
},
|
@@ -3293,6 +3293,9 @@
|
|
3293
3293
|
"panels/application/DOMStorageItemsView.ts | domStorageItems": {
|
3294
3294
|
"message": "DOM Storage Items"
|
3295
3295
|
},
|
3296
|
+
"panels/application/DOMStorageItemsView.ts | domStorageItemsCleared": {
|
3297
|
+
"message": "{PH1} cleared"
|
3298
|
+
},
|
3296
3299
|
"panels/application/DOMStorageItemsView.ts | domStorageNumberEntries": {
|
3297
3300
|
"message": "Number of entries shown in table: {PH1}"
|
3298
3301
|
},
|
@@ -9515,6 +9518,9 @@
|
|
9515
9518
|
"panels/sources/CallStackSidebarPane.ts | copyStackTrace": {
|
9516
9519
|
"message": "Copy stack trace"
|
9517
9520
|
},
|
9521
|
+
"panels/sources/CallStackSidebarPane.ts | debugFileNotFound": {
|
9522
|
+
"message": "Failed to load debug file \"{PH1}\"."
|
9523
|
+
},
|
9518
9524
|
"panels/sources/CallStackSidebarPane.ts | notPaused": {
|
9519
9525
|
"message": "Not paused"
|
9520
9526
|
},
|
@@ -9650,6 +9656,12 @@
|
|
9650
9656
|
"panels/sources/DebuggerPlugin.ts | configure": {
|
9651
9657
|
"message": "Configure"
|
9652
9658
|
},
|
9659
|
+
"panels/sources/DebuggerPlugin.ts | debugFileNotFound": {
|
9660
|
+
"message": "Failed to load debug file \"{PH1}\"."
|
9661
|
+
},
|
9662
|
+
"panels/sources/DebuggerPlugin.ts | debugInfoNotFound": {
|
9663
|
+
"message": "Failed to load any debug info for {PH1}."
|
9664
|
+
},
|
9653
9665
|
"panels/sources/DebuggerPlugin.ts | disableBreakpoint": {
|
9654
9666
|
"message": "{n, plural, =1 {Disable breakpoint} other {Disable all breakpoints in line}}"
|
9655
9667
|
},
|
@@ -1241,6 +1241,9 @@
|
|
1241
1241
|
"models/bindings/ContentProviderBasedProject.ts | unknownErrorLoadingFile": {
|
1242
1242
|
"message": "Ûńk̂ńôẃn̂ ér̂ŕôŕ l̂óâd́îńĝ f́îĺê"
|
1243
1243
|
},
|
1244
|
+
"models/bindings/DebuggerLanguagePlugins.ts | debugSymbolsIncomplete": {
|
1245
|
+
"message": "T̂h́ê d́êb́ûǵ îńf̂ór̂ḿât́îón̂ f́ôŕ f̂ún̂ćt̂íôń {PH1} îś îńĉóm̂ṕl̂ét̂é"
|
1246
|
+
},
|
1244
1247
|
"models/bindings/DebuggerLanguagePlugins.ts | errorInDebuggerLanguagePlugin": {
|
1245
1248
|
"message": "Êŕr̂ór̂ ín̂ d́êb́ûǵĝér̂ ĺâńĝúâǵê ṕl̂úĝín̂: {PH1}"
|
1246
1249
|
},
|
@@ -1248,7 +1251,7 @@
|
|
1248
1251
|
"message": "[{PH1}] F̂áîĺêd́ t̂ó l̂óâd́ d̂éb̂úĝ śŷḿb̂ól̂ś f̂ór̂ {PH2} ({PH3})"
|
1249
1252
|
},
|
1250
1253
|
"models/bindings/DebuggerLanguagePlugins.ts | failedToLoadDebugSymbolsForFunction": {
|
1251
|
-
"message": "
|
1254
|
+
"message": "N̂ó d̂éb̂úĝ ín̂f́ôŕm̂át̂íôń f̂ór̂ f́ûńĉt́îón̂ \"{PH1}\""
|
1252
1255
|
},
|
1253
1256
|
"models/bindings/DebuggerLanguagePlugins.ts | loadedDebugSymbolsForButDidnt": {
|
1254
1257
|
"message": "[{PH1}] L̂óâd́êd́ d̂éb̂úĝ śŷḿb̂ól̂ś f̂ór̂ {PH2}, b́ût́ d̂íd̂ń't̂ f́îńd̂ án̂ý ŝóûŕĉé f̂íl̂éŝ"
|
@@ -1262,9 +1265,6 @@
|
|
1262
1265
|
"models/bindings/DebuggerLanguagePlugins.ts | loadingDebugSymbolsForVia": {
|
1263
1266
|
"message": "[{PH1}] L̂óâd́îńĝ d́êb́ûǵ ŝým̂b́ôĺŝ f́ôŕ {PH2} (v̂íâ {PH3})..."
|
1264
1267
|
},
|
1265
|
-
"models/bindings/DebuggerLanguagePlugins.ts | symbolFileNotFound": {
|
1266
|
-
"message": "Ŝým̂b́ôĺ f̂íl̂é \"{PH1}\" n̂ót̂ f́ôún̂d́"
|
1267
|
-
},
|
1268
1268
|
"models/bindings/ResourceScriptMapping.ts | liveEditCompileFailed": {
|
1269
1269
|
"message": "LiveEdit ĉóm̂ṕîĺê f́âíl̂éd̂: {PH1}"
|
1270
1270
|
},
|
@@ -3293,6 +3293,9 @@
|
|
3293
3293
|
"panels/application/DOMStorageItemsView.ts | domStorageItems": {
|
3294
3294
|
"message": "D̂ÓM̂ Śt̂ór̂áĝé Ît́êḿŝ"
|
3295
3295
|
},
|
3296
|
+
"panels/application/DOMStorageItemsView.ts | domStorageItemsCleared": {
|
3297
|
+
"message": "{PH1} ĉĺêár̂éd̂"
|
3298
|
+
},
|
3296
3299
|
"panels/application/DOMStorageItemsView.ts | domStorageNumberEntries": {
|
3297
3300
|
"message": "N̂úm̂b́êŕ ôf́ êńt̂ŕîéŝ śĥóŵń îń t̂áb̂ĺê: {PH1}"
|
3298
3301
|
},
|
@@ -9515,6 +9518,9 @@
|
|
9515
9518
|
"panels/sources/CallStackSidebarPane.ts | copyStackTrace": {
|
9516
9519
|
"message": "Ĉóp̂ý ŝt́âćk̂ t́r̂áĉé"
|
9517
9520
|
},
|
9521
|
+
"panels/sources/CallStackSidebarPane.ts | debugFileNotFound": {
|
9522
|
+
"message": "F̂áîĺêd́ t̂ó l̂óâd́ d̂éb̂úĝ f́îĺê \"{PH1}\"."
|
9523
|
+
},
|
9518
9524
|
"panels/sources/CallStackSidebarPane.ts | notPaused": {
|
9519
9525
|
"message": "N̂ót̂ ṕâúŝéd̂"
|
9520
9526
|
},
|
@@ -9650,6 +9656,12 @@
|
|
9650
9656
|
"panels/sources/DebuggerPlugin.ts | configure": {
|
9651
9657
|
"message": "Ĉón̂f́îǵûŕê"
|
9652
9658
|
},
|
9659
|
+
"panels/sources/DebuggerPlugin.ts | debugFileNotFound": {
|
9660
|
+
"message": "F̂áîĺêd́ t̂ó l̂óâd́ d̂éb̂úĝ f́îĺê \"{PH1}\"."
|
9661
|
+
},
|
9662
|
+
"panels/sources/DebuggerPlugin.ts | debugInfoNotFound": {
|
9663
|
+
"message": "F̂áîĺêd́ t̂ó l̂óâd́ âńŷ d́êb́ûǵ îńf̂ó f̂ór̂ {PH1}."
|
9664
|
+
},
|
9653
9665
|
"panels/sources/DebuggerPlugin.ts | disableBreakpoint": {
|
9654
9666
|
"message": "{n, plural, =1 {D̂íŝáb̂ĺê b́r̂éâḱp̂óîńt̂} other {D́îśâb́l̂é âĺl̂ b́r̂éâḱp̂óîńt̂ś îń l̂ín̂é}}"
|
9655
9667
|
},
|
@@ -188,7 +188,7 @@ export class CSSProperty {
|
|
188
188
|
if (insideProperty) {
|
189
189
|
result += propertyText;
|
190
190
|
}
|
191
|
-
result = result.substring(2, result.length - 1).
|
191
|
+
result = result.substring(2, result.length - 1).trimEnd();
|
192
192
|
return result + (indentation ? '\n' + endIndentation : '');
|
193
193
|
|
194
194
|
function processToken(token: string, tokenType: string|null): void {
|
@@ -230,8 +230,8 @@ export class CSSProperty {
|
|
230
230
|
}
|
231
231
|
if (cssMetadata().isGridAreaDefiningProperty(propertyName)) {
|
232
232
|
const rowResult = GridAreaRowRegex.exec(token);
|
233
|
-
if (rowResult && rowResult.index === 0 && !propertyText.
|
234
|
-
propertyText = propertyText.
|
233
|
+
if (rowResult && rowResult.index === 0 && !propertyText.trimEnd().endsWith(']')) {
|
234
|
+
propertyText = propertyText.trimEnd() + '\n' + doubleIndent;
|
235
235
|
}
|
236
236
|
}
|
237
237
|
if (!propertyName && token === ':') {
|
@@ -1242,6 +1242,11 @@ export class BreakLocation extends Location {
|
|
1242
1242
|
}
|
1243
1243
|
}
|
1244
1244
|
|
1245
|
+
export interface MissingDebugInfoDetails {
|
1246
|
+
details: string;
|
1247
|
+
resources: string[];
|
1248
|
+
}
|
1249
|
+
|
1245
1250
|
export class CallFrame {
|
1246
1251
|
debuggerModel: DebuggerModel;
|
1247
1252
|
readonly #scriptInternal: Script;
|
@@ -1253,7 +1258,7 @@ export class CallFrame {
|
|
1253
1258
|
readonly #functionNameInternal: string;
|
1254
1259
|
readonly #functionLocationInternal: Location|undefined;
|
1255
1260
|
#returnValueInternal: RemoteObject|null;
|
1256
|
-
|
1261
|
+
#missingDebugInfoDetails: MissingDebugInfoDetails|null = null;
|
1257
1262
|
|
1258
1263
|
readonly canBeRestarted: boolean;
|
1259
1264
|
|
@@ -1299,8 +1304,12 @@ export class CallFrame {
|
|
1299
1304
|
return new CallFrame(this.debuggerModel, this.#scriptInternal, this.payload, inlineFrameIndex, name);
|
1300
1305
|
}
|
1301
1306
|
|
1302
|
-
|
1303
|
-
this
|
1307
|
+
setMissingDebugInfoDetails(details: MissingDebugInfoDetails): void {
|
1308
|
+
this.#missingDebugInfoDetails = details;
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
get missingDebugInfoDetails(): MissingDebugInfoDetails|null {
|
1312
|
+
return this.#missingDebugInfoDetails;
|
1304
1313
|
}
|
1305
1314
|
|
1306
1315
|
get script(): Script {
|
@@ -21,6 +21,7 @@ export class EmulationModel extends SDKModel<void> {
|
|
21
21
|
readonly #mediaConfiguration: Map<string, string>;
|
22
22
|
#touchEnabled: boolean;
|
23
23
|
#touchMobile: boolean;
|
24
|
+
#touchEmulationAllowed: boolean;
|
24
25
|
#customTouchEnabled: boolean;
|
25
26
|
#touchConfiguration: {
|
26
27
|
enabled: boolean,
|
@@ -176,6 +177,7 @@ export class EmulationModel extends SDKModel<void> {
|
|
176
177
|
updateDisabledImageFormats();
|
177
178
|
}
|
178
179
|
|
180
|
+
this.#touchEmulationAllowed = true;
|
179
181
|
this.#touchEnabled = false;
|
180
182
|
this.#touchMobile = false;
|
181
183
|
this.#customTouchEnabled = false;
|
@@ -185,6 +187,10 @@ export class EmulationModel extends SDKModel<void> {
|
|
185
187
|
};
|
186
188
|
}
|
187
189
|
|
190
|
+
setTouchEmulationAllowed(touchEmulationAllowed: boolean): void {
|
191
|
+
this.#touchEmulationAllowed = touchEmulationAllowed;
|
192
|
+
}
|
193
|
+
|
188
194
|
supportsDeviceEmulation(): boolean {
|
189
195
|
return this.target().hasAllCapabilities(Capability.DeviceEmulation);
|
190
196
|
}
|
@@ -322,13 +328,13 @@ export class EmulationModel extends SDKModel<void> {
|
|
322
328
|
}
|
323
329
|
|
324
330
|
async emulateTouch(enabled: boolean, mobile: boolean): Promise<void> {
|
325
|
-
this.#touchEnabled = enabled;
|
326
|
-
this.#touchMobile = mobile;
|
331
|
+
this.#touchEnabled = enabled && this.#touchEmulationAllowed;
|
332
|
+
this.#touchMobile = mobile && this.#touchEmulationAllowed;
|
327
333
|
await this.updateTouch();
|
328
334
|
}
|
329
335
|
|
330
336
|
async overrideEmulateTouch(enabled: boolean): Promise<void> {
|
331
|
-
this.#customTouchEnabled = enabled;
|
337
|
+
this.#customTouchEnabled = enabled && this.#touchEmulationAllowed;
|
332
338
|
await this.updateTouch();
|
333
339
|
}
|
334
340
|
|
@@ -192,7 +192,6 @@ export class Script implements TextUtils.ContentProvider.ContentProvider, FrameA
|
|
192
192
|
|
193
193
|
originalContentProvider(): TextUtils.ContentProvider.ContentProvider {
|
194
194
|
if (!this.#originalContentProviderInternal) {
|
195
|
-
/* } */
|
196
195
|
let lazyContentPromise: Promise<TextUtils.ContentProvider.DeferredContent>|null;
|
197
196
|
this.#originalContentProviderInternal =
|
198
197
|
new TextUtils.StaticContentProvider.StaticContentProvider(this.contentURL(), this.contentType(), () => {
|
@@ -220,7 +219,9 @@ export class Script implements TextUtils.ContentProvider.ContentProvider, FrameA
|
|
220
219
|
return {content: bytecode, isEncoded: true};
|
221
220
|
}
|
222
221
|
let content: string = scriptSource || '';
|
223
|
-
if (this.hasSourceURL) {
|
222
|
+
if (this.hasSourceURL && this.sourceURL.startsWith('snippet://')) {
|
223
|
+
// TODO(crbug.com/1330846): Find a better way to establish the snippet automapping binding then adding
|
224
|
+
// a sourceURL comment before evaluation and removing it here.
|
224
225
|
content = Script.trimSourceURLComment(content);
|
225
226
|
}
|
226
227
|
return {content, isEncoded: false};
|
@@ -51,6 +51,7 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
51
51
|
readonly debuggerWorkspaceBinding: DebuggerWorkspaceBinding;
|
52
52
|
readonly #breakpointsForUISourceCode: Map<Workspace.UISourceCode.UISourceCode, Map<string, BreakpointLocation>>;
|
53
53
|
readonly #breakpointByStorageId: Map<string, Breakpoint>;
|
54
|
+
#updateBindingsCallbacks: ((uiSourceCode: Workspace.UISourceCode.UISourceCode) => Promise<void>)[];
|
54
55
|
|
55
56
|
private constructor(
|
56
57
|
targetManager: SDK.TargetManager.TargetManager, workspace: Workspace.Workspace.WorkspaceImpl,
|
@@ -69,6 +70,7 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
69
70
|
this.#workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this.projectRemoved, this);
|
70
71
|
|
71
72
|
this.targetManager.observeModels(SDK.DebuggerModel.DebuggerModel, this);
|
73
|
+
this.#updateBindingsCallbacks = [];
|
72
74
|
}
|
73
75
|
|
74
76
|
static instance(opts: {
|
@@ -108,6 +110,10 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
108
110
|
debuggerModel.setSynchronizeBreakpointsCallback(null);
|
109
111
|
}
|
110
112
|
|
113
|
+
addUpdateBindingsCallback(callback: ((uiSourceCode: Workspace.UISourceCode.UISourceCode) => Promise<void>)): void {
|
114
|
+
this.#updateBindingsCallbacks.push(callback);
|
115
|
+
}
|
116
|
+
|
111
117
|
async copyBreakpoints(fromURL: Platform.DevToolsPath.UrlString, toSourceCode: Workspace.UISourceCode.UISourceCode):
|
112
118
|
Promise<void> {
|
113
119
|
const breakpointItems = this.storage.breakpointItems(fromURL);
|
@@ -122,15 +128,13 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
122
128
|
if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.INSTRUMENTATION_BREAKPOINTS)) {
|
123
129
|
return;
|
124
130
|
}
|
131
|
+
if (!script.sourceURL) {
|
132
|
+
return;
|
133
|
+
}
|
134
|
+
|
125
135
|
const debuggerModel = script.debuggerModel;
|
136
|
+
const uiSourceCode = await this.getUpdatedUISourceCode(script);
|
126
137
|
if (this.#hasBreakpointsForUrl(script.sourceURL)) {
|
127
|
-
// Handle inline scripts without sourceURL comment separately:
|
128
|
-
// The UISourceCode of inline scripts without sourceURLs will not be availabe
|
129
|
-
// until a later point. Use the v8 script for setting the breakpoint.
|
130
|
-
const isInlineScriptWithoutSourceURL = script.isInlineScript() && !script.hasSourceURL;
|
131
|
-
const sourceURL =
|
132
|
-
isInlineScriptWithoutSourceURL ? DefaultScriptMapping.createV8ScriptURL(script) : script.sourceURL;
|
133
|
-
const uiSourceCode = await Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURLPromise(sourceURL);
|
134
138
|
await this.#restoreBreakpointsForUrl(uiSourceCode);
|
135
139
|
}
|
136
140
|
|
@@ -149,7 +153,7 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
149
153
|
const {pluginManager} = this.debuggerWorkspaceBinding;
|
150
154
|
if (pluginManager) {
|
151
155
|
const sourceUrls = await pluginManager.getSourcesForScript(script);
|
152
|
-
if (sourceUrls) {
|
156
|
+
if (Array.isArray(sourceUrls)) {
|
153
157
|
for (const sourceURL of sourceUrls) {
|
154
158
|
if (this.#hasBreakpointsForUrl(sourceURL)) {
|
155
159
|
const uiSourceCode =
|
@@ -161,6 +165,34 @@ export class BreakpointManager extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
161
165
|
}
|
162
166
|
}
|
163
167
|
|
168
|
+
async getUpdatedUISourceCode(script: SDK.Script.Script): Promise<Workspace.UISourceCode.UISourceCode> {
|
169
|
+
const isSnippet = script.sourceURL.startsWith('snippet://');
|
170
|
+
const projectType = isSnippet ? Workspace.Workspace.projectTypes.Network : undefined;
|
171
|
+
|
172
|
+
// Handle inline scripts without sourceURL comment separately:
|
173
|
+
// The UISourceCode of inline scripts without sourceURLs will not be availabe
|
174
|
+
// until a later point. Use the v8 script for setting the breakpoint.
|
175
|
+
const isInlineScriptWithoutSourceURL = script.isInlineScript() && !script.hasSourceURL;
|
176
|
+
const sourceURL =
|
177
|
+
isInlineScriptWithoutSourceURL ? DefaultScriptMapping.createV8ScriptURL(script) : script.sourceURL;
|
178
|
+
const uiSourceCode =
|
179
|
+
await Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURLPromise(sourceURL, projectType);
|
180
|
+
|
181
|
+
if (this.#updateBindingsCallbacks.length > 0) {
|
182
|
+
// It's possible to set breakpoints on files on the file system, and to have them
|
183
|
+
// hit whenever we navigate to a page that serves that file.
|
184
|
+
// To make sure that we have all breakpoint information moved from the file system
|
185
|
+
// to the served file, we need to update the bindings and await it. This will
|
186
|
+
// move the breakpoints from the FileSystem UISourceCode to the Network UiSourceCode.
|
187
|
+
const promises = [];
|
188
|
+
for (const callback of this.#updateBindingsCallbacks) {
|
189
|
+
promises.push(callback(uiSourceCode));
|
190
|
+
}
|
191
|
+
await Promise.all(promises);
|
192
|
+
}
|
193
|
+
return uiSourceCode;
|
194
|
+
}
|
195
|
+
|
164
196
|
async #restoreBreakpointsForUrl(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
165
197
|
this.restoreBreakpoints(uiSourceCode);
|
166
198
|
const breakpoints = this.#breakpointByStorageId.values();
|
@@ -713,20 +745,24 @@ export class ModelBreakpoint {
|
|
713
745
|
};
|
714
746
|
});
|
715
747
|
newState = new Breakpoint.State(positions, condition);
|
716
|
-
} else if (
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
748
|
+
} else if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.INSTRUMENTATION_BREAKPOINTS)) {
|
749
|
+
// Use this fallback if we do not have instrumentation breakpoints enabled yet. This currently makes
|
750
|
+
// sure that v8 knows about the breakpoint and is able to restore it whenever the script is parsed.
|
751
|
+
if (this.#breakpoint.currentState) {
|
752
|
+
newState = new Breakpoint.State(this.#breakpoint.currentState.positions, condition);
|
753
|
+
} else {
|
754
|
+
// TODO(bmeurer): This fallback doesn't make a whole lot of sense, we should
|
755
|
+
// at least signal a warning to the developer that this #breakpoint wasn't
|
756
|
+
// really resolved.
|
757
|
+
const position = {
|
758
|
+
url: this.#breakpoint.url(),
|
759
|
+
scriptId: '' as Protocol.Runtime.ScriptId,
|
760
|
+
scriptHash: '',
|
761
|
+
lineNumber,
|
762
|
+
columnNumber,
|
763
|
+
};
|
764
|
+
newState = new Breakpoint.State([position], condition);
|
765
|
+
}
|
730
766
|
}
|
731
767
|
}
|
732
768
|
|
@@ -59,12 +59,12 @@ const UIStrings = {
|
|
59
59
|
*@description Error message that is displayed in UI debugging information cannot be found for a call frame
|
60
60
|
*@example {main} PH1
|
61
61
|
*/
|
62
|
-
failedToLoadDebugSymbolsForFunction: '
|
62
|
+
failedToLoadDebugSymbolsForFunction: 'No debug information for function "{PH1}"',
|
63
63
|
/**
|
64
64
|
*@description Error message that is displayed in UI when a file needed for debugging information for a call frame is missing
|
65
|
-
*@example {
|
65
|
+
*@example {mainp.debug.wasm.dwp} PH1
|
66
66
|
*/
|
67
|
-
|
67
|
+
debugSymbolsIncomplete: 'The debug information for function {PH1} is incomplete',
|
68
68
|
};
|
69
69
|
const str_ = i18n.i18n.registerUIStrings('models/bindings/DebuggerLanguagePlugins.ts', UIStrings);
|
70
70
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
@@ -766,7 +766,7 @@ export class DebuggerLanguagePluginManager implements
|
|
766
766
|
rawModuleId: string,
|
767
767
|
plugin: DebuggerLanguagePlugin,
|
768
768
|
scripts: Array<SDK.Script.Script>,
|
769
|
-
addRawModulePromise: Promise<Array<Platform.DevToolsPath.UrlString
|
769
|
+
addRawModulePromise: Promise<Array<Platform.DevToolsPath.UrlString>|{missingSymbolFiles: string[]}>,
|
770
770
|
}>;
|
771
771
|
|
772
772
|
constructor(
|
@@ -819,17 +819,19 @@ export class DebuggerLanguagePluginManager implements
|
|
819
819
|
.all(callFrames.map(async callFrame => {
|
820
820
|
const functionInfo = await this.getFunctionInfo(callFrame.script, callFrame.location());
|
821
821
|
if (functionInfo) {
|
822
|
-
|
823
|
-
|
824
|
-
return frames.map(({name}, index) => callFrame.createVirtualCallFrame(index, name));
|
822
|
+
if ('frames' in functionInfo && functionInfo.frames.length) {
|
823
|
+
return functionInfo.frames.map(({name}, index) => callFrame.createVirtualCallFrame(index, name));
|
825
824
|
}
|
826
|
-
if (missingSymbolFiles && missingSymbolFiles.length) {
|
827
|
-
|
828
|
-
|
829
|
-
}
|
825
|
+
if ('missingSymbolFiles' in functionInfo && functionInfo.missingSymbolFiles.length) {
|
826
|
+
const resources = functionInfo.missingSymbolFiles;
|
827
|
+
const details = i18nString(UIStrings.debugSymbolsIncomplete, {PH1: callFrame.functionName});
|
828
|
+
callFrame.setMissingDebugInfoDetails({details, resources});
|
829
|
+
} else {
|
830
|
+
callFrame.setMissingDebugInfoDetails({
|
831
|
+
resources: [],
|
832
|
+
details: i18nString(UIStrings.failedToLoadDebugSymbolsForFunction, {PH1: callFrame.functionName}),
|
833
|
+
});
|
830
834
|
}
|
831
|
-
callFrame.addWarning(
|
832
|
-
i18nString(UIStrings.failedToLoadDebugSymbolsForFunction, {PH1: callFrame.functionName}));
|
833
835
|
}
|
834
836
|
return callFrame;
|
835
837
|
}))
|
@@ -1069,40 +1071,45 @@ export class DebuggerLanguagePluginManager implements
|
|
1069
1071
|
const rawModuleId = rawModuleIdForScript(script);
|
1070
1072
|
let rawModuleHandle = this.#rawModuleHandles.get(rawModuleId);
|
1071
1073
|
if (!rawModuleHandle) {
|
1072
|
-
const sourceFileURLsPromise =
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1074
|
+
const sourceFileURLsPromise =
|
1075
|
+
(async(): Promise<Platform.DevToolsPath.UrlString[]|{missingSymbolFiles: string[]}> => {
|
1076
|
+
const console = Common.Console.Console.instance();
|
1077
|
+
const url = script.sourceURL;
|
1078
|
+
const symbolsUrl = (script.debugSymbols && script.debugSymbols.externalURL) || '';
|
1079
|
+
if (symbolsUrl) {
|
1080
|
+
console.log(
|
1081
|
+
i18nString(UIStrings.loadingDebugSymbolsForVia, {PH1: plugin.name, PH2: url, PH3: symbolsUrl}));
|
1082
|
+
} else {
|
1083
|
+
console.log(i18nString(UIStrings.loadingDebugSymbolsFor, {PH1: plugin.name, PH2: url}));
|
1084
|
+
}
|
1085
|
+
try {
|
1086
|
+
const code = (!symbolsUrl && url.startsWith('wasm://')) ? await script.getWasmBytecode() : undefined;
|
1087
|
+
const addModuleResult = await plugin.addRawModule(rawModuleId, symbolsUrl, {url, code});
|
1088
|
+
// Check that the handle isn't stale by now. This works because the code that assigns to
|
1089
|
+
// `rawModuleHandle` below will run before this code because of the `await` in the preceding
|
1090
|
+
// line. This is primarily to avoid logging the message below, which would give the developer
|
1091
|
+
// the misleading information that we're done, while in reality it was a stale call that finished.
|
1092
|
+
if (rawModuleHandle !== this.#rawModuleHandles.get(rawModuleId)) {
|
1093
|
+
return [];
|
1094
|
+
}
|
1095
|
+
if ('missingSymbolFiles' in addModuleResult) {
|
1096
|
+
return {missingSymbolFiles: addModuleResult.missingSymbolFiles};
|
1097
|
+
}
|
1098
|
+
const sourceFileURLs = addModuleResult as Platform.DevToolsPath.UrlString[];
|
1099
|
+
if (sourceFileURLs.length === 0) {
|
1100
|
+
console.warn(i18nString(UIStrings.loadedDebugSymbolsForButDidnt, {PH1: plugin.name, PH2: url}));
|
1101
|
+
} else {
|
1102
|
+
console.log(i18nString(
|
1103
|
+
UIStrings.loadedDebugSymbolsForFound, {PH1: plugin.name, PH2: url, PH3: sourceFileURLs.length}));
|
1104
|
+
}
|
1105
|
+
return sourceFileURLs;
|
1106
|
+
} catch (error) {
|
1107
|
+
console.error(i18nString(
|
1108
|
+
UIStrings.failedToLoadDebugSymbolsFor, {PH1: plugin.name, PH2: url, PH3: error.message}));
|
1109
|
+
this.#rawModuleHandles.delete(rawModuleId);
|
1110
|
+
return [];
|
1111
|
+
}
|
1112
|
+
})();
|
1106
1113
|
rawModuleHandle = {rawModuleId, plugin, scripts: [script], addRawModulePromise: sourceFileURLsPromise};
|
1107
1114
|
this.#rawModuleHandles.set(rawModuleId, rawModuleHandle);
|
1108
1115
|
} else {
|
@@ -1114,12 +1121,14 @@ export class DebuggerLanguagePluginManager implements
|
|
1114
1121
|
// for the DebuggerModel again, which may disappear
|
1115
1122
|
// in the meantime...
|
1116
1123
|
void rawModuleHandle.addRawModulePromise.then(sourceFileURLs => {
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
modelData
|
1122
|
-
|
1124
|
+
if (!('missingSymbolFiles' in sourceFileURLs)) {
|
1125
|
+
// The script might have disappeared meanwhile...
|
1126
|
+
if (script.debuggerModel.scriptForId(script.scriptId) === script) {
|
1127
|
+
const modelData = this.#debuggerModelToData.get(script.debuggerModel);
|
1128
|
+
if (modelData) { // The DebuggerModel could have disappeared meanwhile...
|
1129
|
+
modelData.addSourceFiles(script, sourceFileURLs);
|
1130
|
+
void this.#debuggerWorkspaceBinding.updateLocations(script);
|
1131
|
+
}
|
1123
1132
|
}
|
1124
1133
|
}
|
1125
1134
|
});
|
@@ -1127,7 +1136,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1127
1136
|
}
|
1128
1137
|
}
|
1129
1138
|
|
1130
|
-
getSourcesForScript(script: SDK.Script.Script):
|
1139
|
+
getSourcesForScript(script: SDK.Script.Script):
|
1140
|
+
Promise<Array<Platform.DevToolsPath.UrlString>|{missingSymbolFiles: string[]}|undefined> {
|
1131
1141
|
const rawModuleId = rawModuleIdForScript(script);
|
1132
1142
|
const rawModuleHandle = this.#rawModuleHandles.get(rawModuleId);
|
1133
1143
|
if (rawModuleHandle) {
|
@@ -1173,10 +1183,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1173
1183
|
}
|
1174
1184
|
}
|
1175
1185
|
|
1176
|
-
async getFunctionInfo(script: SDK.Script.Script, location: SDK.DebuggerModel.Location):
|
1177
|
-
|
1178
|
-
missingSymbolFiles?: Array<string>,
|
1179
|
-
}|null> {
|
1186
|
+
async getFunctionInfo(script: SDK.Script.Script, location: SDK.DebuggerModel.Location):
|
1187
|
+
Promise<{frames: Array<Chrome.DevTools.FunctionInfo>}|{missingSymbolFiles: string[]}|null> {
|
1180
1188
|
const {rawModuleId, plugin} = await this.rawModuleIdAndPluginForScript(script);
|
1181
1189
|
if (!plugin) {
|
1182
1190
|
return null;
|
@@ -1189,7 +1197,8 @@ export class DebuggerLanguagePluginManager implements
|
|
1189
1197
|
};
|
1190
1198
|
|
1191
1199
|
try {
|
1192
|
-
|
1200
|
+
const functionInfo = await plugin.getFunctionInfo(rawLocation);
|
1201
|
+
return functionInfo;
|
1193
1202
|
} catch (error) {
|
1194
1203
|
Common.Console.Console.instance().warn(i18nString(UIStrings.errorInDebuggerLanguagePlugin, {PH1: error.message}));
|
1195
1204
|
return {frames: []};
|
@@ -1362,7 +1371,7 @@ class ModelData {
|
|
1362
1371
|
}
|
1363
1372
|
}
|
1364
1373
|
|
1365
|
-
export class DebuggerLanguagePlugin {
|
1374
|
+
export class DebuggerLanguagePlugin implements Chrome.DevTools.LanguageExtensionPlugin {
|
1366
1375
|
name: string;
|
1367
1376
|
constructor(name: string) {
|
1368
1377
|
this.name = name;
|
@@ -1378,7 +1387,7 @@ export class DebuggerLanguagePlugin {
|
|
1378
1387
|
/** Notify the #plugin about a new script
|
1379
1388
|
*/
|
1380
1389
|
async addRawModule(_rawModuleId: string, _symbolsURL: string, _rawModule: Chrome.DevTools.RawModule):
|
1381
|
-
Promise<string[]> {
|
1390
|
+
Promise<string[]|{missingSymbolFiles: string[]}> {
|
1382
1391
|
throw new Error('Not implemented yet');
|
1383
1392
|
}
|
1384
1393
|
|
@@ -1445,10 +1454,8 @@ export class DebuggerLanguagePlugin {
|
|
1445
1454
|
/**
|
1446
1455
|
* Find #locations in source files from a #location in a raw module
|
1447
1456
|
*/
|
1448
|
-
async getFunctionInfo(_rawLocation: Chrome.DevTools.RawLocation):
|
1449
|
-
|
1450
|
-
missingSymbolFiles?: Array<string>,
|
1451
|
-
}> {
|
1457
|
+
async getFunctionInfo(_rawLocation: Chrome.DevTools.RawLocation):
|
1458
|
+
Promise<{frames: Array<Chrome.DevTools.FunctionInfo>}|{missingSymbolFiles: string[]}> {
|
1452
1459
|
throw new Error('Not implemented yet');
|
1453
1460
|
}
|
1454
1461
|
|