chrome-devtools-frontend 1.0.971140 → 1.0.973253

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.
Files changed (107) hide show
  1. package/config/gni/devtools_grd_files.gni +10 -8
  2. package/front_end/core/common/ParsedURL.ts +9 -3
  3. package/front_end/core/host/UserMetrics.ts +2 -1
  4. package/front_end/core/i18n/locales/en-US.json +24 -0
  5. package/front_end/core/i18n/locales/en-XL.json +24 -0
  6. package/front_end/core/sdk/CSSModel.ts +21 -0
  7. package/front_end/core/sdk/CSSStyleSheetHeader.ts +10 -10
  8. package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +6 -4
  9. package/front_end/core/sdk/DOMDebuggerModel.ts +4 -3
  10. package/front_end/core/sdk/DebuggerModel.ts +17 -16
  11. package/front_end/core/sdk/NetworkManager.ts +17 -9
  12. package/front_end/core/sdk/NetworkRequest.ts +18 -16
  13. package/front_end/core/sdk/Resource.ts +10 -10
  14. package/front_end/core/sdk/ResourceTreeModel.ts +16 -13
  15. package/front_end/core/sdk/Script.ts +10 -10
  16. package/front_end/core/sdk/SourceMap.ts +8 -6
  17. package/front_end/entrypoints/lighthouse_worker/{LighthouseService.ts → LighthouseWorkerService.ts} +69 -38
  18. package/front_end/entrypoints/lighthouse_worker/lighthouse_worker.ts +1 -1
  19. package/front_end/entrypoints/main/MainImpl.ts +5 -0
  20. package/front_end/generated/InspectorBackendCommands.js +14 -8
  21. package/front_end/generated/SupportedCSSProperties.js +2 -0
  22. package/front_end/generated/protocol-mapping.d.ts +5 -0
  23. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  24. package/front_end/generated/protocol.ts +20 -12
  25. package/front_end/models/bindings/BreakpointManager.ts +7 -5
  26. package/front_end/models/bindings/CSSWorkspaceBinding.ts +2 -16
  27. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +2 -1
  28. package/front_end/models/bindings/ResourceMapping.ts +2 -1
  29. package/front_end/models/bindings/ResourceScriptMapping.ts +2 -1
  30. package/front_end/models/bindings/SASSSourceMapping.ts +4 -3
  31. package/front_end/models/bindings/StylesSourceMapping.ts +2 -1
  32. package/front_end/models/har/HARFormat.ts +4 -2
  33. package/front_end/models/har/Importer.ts +0 -1
  34. package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +12 -12
  35. package/front_end/models/issues_manager/descriptions/{federatedAuthRequestClientIdMetadataHttpNotFound.md → federatedAuthRequestClientMetadataHttpNotFound.md} +0 -0
  36. package/front_end/models/issues_manager/descriptions/{federatedAuthRequestClientIdMetadataInvalidResponse.md → federatedAuthRequestClientMetadataInvalidResponse.md} +0 -0
  37. package/front_end/models/issues_manager/descriptions/{federatedAuthRequestClientIdMetadataNoResponse.md → federatedAuthRequestClientMetadataNoResponse.md} +0 -0
  38. package/front_end/models/issues_manager/descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
  39. package/front_end/models/issues_manager/descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
  40. package/front_end/models/issues_manager/descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
  41. package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +5 -5
  42. package/front_end/models/persistence/IsolatedFileSystem.ts +10 -13
  43. package/front_end/models/persistence/PersistenceActions.ts +1 -4
  44. package/front_end/models/persistence/PlatformFileSystem.ts +3 -3
  45. package/front_end/{panels/sources/SourceMapNamesResolver.ts → models/source_map_scopes/NamesResolver.ts} +5 -5
  46. package/front_end/models/source_map_scopes/source_map_scopes.ts +7 -0
  47. package/front_end/models/text_utils/ContentProvider.ts +2 -1
  48. package/front_end/models/text_utils/StaticContentProvider.ts +7 -5
  49. package/front_end/models/workspace/UISourceCode.ts +7 -7
  50. package/front_end/models/workspace/WorkspaceImpl.ts +1 -3
  51. package/front_end/models/workspace_diff/WorkspaceDiff.ts +20 -8
  52. package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -2
  53. package/front_end/panels/changes/ChangesView.ts +4 -4
  54. package/front_end/panels/console/ConsolePrompt.ts +25 -2
  55. package/front_end/panels/console/ConsoleViewMessage.ts +41 -8
  56. package/front_end/panels/coverage/CoverageModel.ts +1 -1
  57. package/front_end/panels/elements/ElementsTreeElement.ts +0 -6
  58. package/front_end/panels/elements/StylesSidebarPane.ts +43 -33
  59. package/front_end/panels/elements/components/LayoutPane.ts +1 -1
  60. package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
  61. package/front_end/panels/issues/AffectedSourcesView.ts +1 -1
  62. package/front_end/panels/lighthouse/LighthouseController.ts +13 -2
  63. package/front_end/panels/lighthouse/LighthousePanel.ts +57 -8
  64. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +94 -30
  65. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +0 -5
  66. package/front_end/panels/lighthouse/LighthouseStartView.ts +6 -2
  67. package/front_end/panels/lighthouse/LighthouseStartViewFR.ts +61 -0
  68. package/front_end/panels/lighthouse/LighthouseTimespanView.ts +99 -0
  69. package/front_end/panels/network/NetworkDataGridNode.ts +1 -1
  70. package/front_end/panels/profiler/CPUProfileView.ts +1 -1
  71. package/front_end/panels/profiler/HeapProfileView.ts +0 -2
  72. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +0 -1
  73. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -3
  74. package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +1 -1
  75. package/front_end/panels/sources/DebuggerPlugin.ts +5 -4
  76. package/front_end/panels/sources/NavigatorView.ts +5 -5
  77. package/front_end/panels/sources/ScopeChainSidebarPane.ts +6 -3
  78. package/front_end/panels/sources/SourcesNavigator.ts +7 -1
  79. package/front_end/panels/sources/sources-legacy.ts +5 -3
  80. package/front_end/panels/sources/sources.ts +0 -2
  81. package/front_end/panels/timeline/TimelineUIUtils.ts +4 -47
  82. package/front_end/third_party/codemirror.next/bundle.ts +1 -1
  83. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  84. package/front_end/third_party/codemirror.next/chunk/json.js +2 -1
  85. package/front_end/third_party/codemirror.next/codemirror.next.d.ts +28 -2
  86. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  87. package/front_end/third_party/codemirror.next/package.json +10 -10
  88. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1047 -1158
  89. package/front_end/third_party/lighthouse/locales/en-US.json +7 -1
  90. package/front_end/third_party/lighthouse/locales/en-XL.json +7 -1
  91. package/front_end/third_party/lighthouse/report/bundle.d.ts +0 -3
  92. package/front_end/third_party/lighthouse/report/bundle.js +38 -24
  93. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +1 -1
  94. package/front_end/ui/components/expandable_list/expandableList.css +1 -1
  95. package/front_end/ui/components/text_editor/config.ts +1 -0
  96. package/front_end/ui/legacy/ViewManager.ts +2 -1
  97. package/front_end/ui/legacy/components/source_frame/BinaryResourceViewFactory.ts +7 -4
  98. package/front_end/ui/legacy/components/source_frame/FontView.ts +1 -1
  99. package/front_end/ui/legacy/components/source_frame/ImageView.ts +1 -1
  100. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +2 -3
  101. package/front_end/ui/legacy/components/utils/Linkifier.ts +20 -59
  102. package/front_end/ui/legacy/tabbedPane.css +1 -0
  103. package/package.json +1 -1
  104. package/scripts/hosted_mode/server.js +13 -0
  105. package/front_end/models/issues_manager/descriptions/federatedAuthRequestWellKnownHttpNotFound.md +0 -1
  106. package/front_end/models/issues_manager/descriptions/federatedAuthRequestWellKnownInvalidResponse.md +0 -1
  107. package/front_end/models/issues_manager/descriptions/federatedAuthRequestWellKnownNoResponse.md +0 -1
@@ -13,6 +13,11 @@ interface DiffRequestOptions {
13
13
  shouldFormatDiff: boolean;
14
14
  }
15
15
 
16
+ interface DiffResponse {
17
+ diff: Diff.Diff.DiffArray;
18
+ formattedCurrentMapping?: FormatterModule.ScriptFormatter.FormatterSourceMapping;
19
+ }
20
+
16
21
  export class WorkspaceDiffImpl extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
17
22
  private readonly uiSourceCodeDiffs: WeakMap<Workspace.UISourceCode.UISourceCode, UISourceCodeDiff>;
18
23
  private readonly loadingUISourceCodes:
@@ -35,7 +40,7 @@ export class WorkspaceDiffImpl extends Common.ObjectWrapper.ObjectWrapper<EventT
35
40
  }
36
41
 
37
42
  requestDiff(uiSourceCode: Workspace.UISourceCode.UISourceCode, diffRequestOptions: DiffRequestOptions):
38
- Promise<Diff.Diff.DiffArray|null> {
43
+ Promise<DiffResponse|null> {
39
44
  return this.uiSourceCodeDiff(uiSourceCode).requestDiff(diffRequestOptions);
40
45
  }
41
46
 
@@ -185,7 +190,7 @@ export type EventTypes = {
185
190
 
186
191
  export class UISourceCodeDiff extends Common.ObjectWrapper.ObjectWrapper<UISourceCodeDiffEventTypes> {
187
192
  private uiSourceCode: Workspace.UISourceCode.UISourceCode;
188
- private requestDiffPromise: Promise<Diff.Diff.DiffArray|null>|null;
193
+ private requestDiffPromise: Promise<DiffResponse|null>|null;
189
194
  private pendingChanges: number|null;
190
195
  dispose: boolean;
191
196
  constructor(uiSourceCode: Workspace.UISourceCode.UISourceCode) {
@@ -218,7 +223,7 @@ export class UISourceCodeDiff extends Common.ObjectWrapper.ObjectWrapper<UISourc
218
223
  }
219
224
  }
220
225
 
221
- requestDiff(diffRequestOptions: DiffRequestOptions): Promise<Diff.Diff.DiffArray|null> {
226
+ requestDiff(diffRequestOptions: DiffRequestOptions): Promise<DiffResponse|null> {
222
227
  if (!this.requestDiffPromise) {
223
228
  this.requestDiffPromise = this.innerRequestDiff(diffRequestOptions);
224
229
  }
@@ -237,7 +242,7 @@ export class UISourceCodeDiff extends Common.ObjectWrapper.ObjectWrapper<UISourc
237
242
  return content.content || ('error' in content && content.error) || '';
238
243
  }
239
244
 
240
- private async innerRequestDiff({shouldFormatDiff}: DiffRequestOptions): Promise<Diff.Diff.DiffArray|null> {
245
+ private async innerRequestDiff({shouldFormatDiff}: DiffRequestOptions): Promise<DiffResponse|null> {
241
246
  if (this.dispose) {
242
247
  return null;
243
248
  }
@@ -270,15 +275,22 @@ export class UISourceCodeDiff extends Common.ObjectWrapper.ObjectWrapper<UISourc
270
275
  if (current === null || baseline === null) {
271
276
  return null;
272
277
  }
278
+ let formattedCurrentMapping;
273
279
  if (shouldFormatDiff) {
274
280
  baseline = (await FormatterModule.ScriptFormatter.format(
275
281
  this.uiSourceCode.contentType(), this.uiSourceCode.mimeType(), baseline))
276
282
  .formattedContent;
277
- current = (await FormatterModule.ScriptFormatter.format(
278
- this.uiSourceCode.contentType(), this.uiSourceCode.mimeType(), current))
279
- .formattedContent;
283
+ const formatCurrentResult = await FormatterModule.ScriptFormatter.format(
284
+ this.uiSourceCode.contentType(), this.uiSourceCode.mimeType(), current);
285
+ current = formatCurrentResult.formattedContent;
286
+ formattedCurrentMapping = formatCurrentResult.formattedMapping;
280
287
  }
281
- return Diff.Diff.DiffWrapper.lineDiff(baseline.split(/\r\n|\n|\r/), current.split(/\r\n|\n|\r/));
288
+ const reNewline = /\r\n?|\n/;
289
+ const diff = Diff.Diff.DiffWrapper.lineDiff(baseline.split(reNewline), current.split(reNewline));
290
+ return {
291
+ diff,
292
+ formattedCurrentMapping,
293
+ };
282
294
  }
283
295
  }
284
296
 
@@ -381,7 +381,8 @@ export class ServiceWorkerCacheView extends UI.View.SimpleView {
381
381
 
382
382
  private createRequest(entry: Protocol.CacheStorage.DataEntry): SDK.NetworkRequest.NetworkRequest {
383
383
  const request = SDK.NetworkRequest.NetworkRequest.createWithoutBackendRequest(
384
- 'cache-storage-' + entry.requestURL, entry.requestURL, '', null);
384
+ 'cache-storage-' + entry.requestURL, entry.requestURL as Platform.DevToolsPath.UrlString,
385
+ '' as Platform.DevToolsPath.UrlString, null);
385
386
  request.requestMethod = entry.requestMethod;
386
387
  request.setRequestHeaders(entry.requestHeaders);
387
388
  request.statusCode = entry.responseStatus;
@@ -454,7 +455,7 @@ export class DataGridNode extends DataGrid.DataGrid.DataGridNode<DataGridNode> {
454
455
  createCell(columnId: string): HTMLElement {
455
456
  const cell = this.createTD(columnId);
456
457
  let value;
457
- let tooltip = this.request.url();
458
+ let tooltip = this.request.url() as string;
458
459
  if (columnId === 'number') {
459
460
  value = String(this.number);
460
461
  } else if (columnId === 'name') {
@@ -173,7 +173,7 @@ export class ChangesView extends UI.Widget.VBox {
173
173
  }
174
174
 
175
175
  if (!this.selectedUISourceCode) {
176
- this.renderDiffRows(null);
176
+ this.renderDiffRows();
177
177
  return;
178
178
  }
179
179
  const uiSourceCode = this.selectedUISourceCode;
@@ -181,12 +181,12 @@ export class ChangesView extends UI.Widget.VBox {
181
181
  this.hideDiff(i18nString(UIStrings.binaryData));
182
182
  return;
183
183
  }
184
- const diff = await this.workspaceDiff.requestDiff(
184
+ const diffResponse = await this.workspaceDiff.requestDiff(
185
185
  uiSourceCode, {shouldFormatDiff: Root.Runtime.experiments.isEnabled('preciseChanges')});
186
186
  if (this.selectedUISourceCode !== uiSourceCode) {
187
187
  return;
188
188
  }
189
- this.renderDiffRows(diff);
189
+ this.renderDiffRows(diffResponse?.diff);
190
190
  }
191
191
 
192
192
  private hideDiff(message: string): void {
@@ -197,7 +197,7 @@ export class ChangesView extends UI.Widget.VBox {
197
197
  this.emptyWidget.showWidget();
198
198
  }
199
199
 
200
- private renderDiffRows(diff: Diff.Diff.DiffArray|null): void {
200
+ private renderDiffRows(diff?: Diff.Diff.DiffArray): void {
201
201
  if (!diff || (diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal)) {
202
202
  this.hideDiff(i18nString(UIStrings.noChanges));
203
203
  } else {
@@ -5,7 +5,9 @@
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
+ import * as Root from '../../core/root/root.js';
8
9
  import * as SDK from '../../core/sdk/sdk.js';
10
+ import * as SourceMapScopes from '../../models/source_map_scopes/source_map_scopes.js';
9
11
  import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
10
12
  import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
11
13
  import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
@@ -280,14 +282,35 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
280
282
  const executionContext = currentExecutionContext;
281
283
  const message = SDK.ConsoleModel.ConsoleModel.instance().addCommandMessage(executionContext, text);
282
284
  const expression = ObjectUI.JavaScriptREPL.JavaScriptREPL.preprocessExpression(text);
283
- void SDK.ConsoleModel.ConsoleModel.instance().evaluateCommandInConsole(
284
- executionContext, message, expression, useCommandLineAPI);
285
+ void this.evaluateCommandInConsole(executionContext, message, expression, useCommandLineAPI);
285
286
  if (ConsolePanel.instance().isShowing()) {
286
287
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.CommandEvaluatedInConsolePanel);
287
288
  }
288
289
  }
289
290
  }
290
291
 
292
+ private async evaluateCommandInConsole(
293
+ executionContext: SDK.RuntimeModel.ExecutionContext, message: SDK.ConsoleModel.ConsoleMessage, expression: string,
294
+ useCommandLineAPI: boolean): Promise<void> {
295
+ if (Root.Runtime.experiments.isEnabled('evaluateExpressionsWithSourceMaps')) {
296
+ const callFrame = executionContext.debuggerModel.selectedCallFrame();
297
+ if (callFrame) {
298
+ const nameMap = await SourceMapScopes.NamesResolver.allVariablesInCallFrame(callFrame);
299
+ expression = this.substituteNames(expression, nameMap);
300
+ }
301
+ }
302
+
303
+ await SDK.ConsoleModel.ConsoleModel.instance().evaluateCommandInConsole(
304
+ executionContext, message, expression, useCommandLineAPI);
305
+ }
306
+
307
+ private substituteNames(expression: string, mapping: Map<string, string>): string {
308
+ // TODO(jarin) Build a more reliable replacer, based on the parsed AST.
309
+ // Here, we just replace exact occurrences.
310
+ const replacement = mapping.get(expression);
311
+ return replacement ?? expression;
312
+ }
313
+
291
314
  private editorUpdate(update: CodeMirror.ViewUpdate): void {
292
315
  if (update.docChanged ||
293
316
  CodeMirror.selectedCompletion(update.state) !== CodeMirror.selectedCompletion(update.startState)) {
@@ -548,8 +548,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
548
548
  return null;
549
549
  }
550
550
  return this.linkifier.linkifyScriptLocation(
551
- runtimeModel.target(), /* scriptId */ null, url, lineNumber,
552
- {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
551
+ runtimeModel.target(), /* scriptId */ null, url, lineNumber, {columnNumber, inlineFrameIndex: 0});
553
552
  }
554
553
 
555
554
  private linkifyStackTraceTopFrame(stackTrace: Protocol.Runtime.StackTrace): HTMLElement|null {
@@ -567,8 +566,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
567
566
  return null;
568
567
  }
569
568
  return this.linkifier.linkifyScriptLocation(
570
- runtimeModel.target(), scriptId, url, lineNumber,
571
- {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: 0});
569
+ runtimeModel.target(), scriptId, url, lineNumber, {columnNumber, inlineFrameIndex: 0});
572
570
  }
573
571
 
574
572
  private format(rawParameters: (string|SDK.RemoteObject.RemoteObject|Protocol.Runtime.RemoteObject|undefined)[]):
@@ -1435,8 +1433,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1435
1433
  const formattedLine = document.createElement('span');
1436
1434
  formattedLine.appendChild(this.linkifyStringAsFragment(`${prefix} ${name} (`));
1437
1435
  const scriptLocationLink = this.linkifier.linkifyScriptLocation(
1438
- debuggerModel.target(), null, url, lineNumber,
1439
- {columnNumber, className: undefined, tabStop: undefined, inlineFrameIndex: f});
1436
+ debuggerModel.target(), null, url, lineNumber, {columnNumber, inlineFrameIndex: f});
1440
1437
  scriptLocationLink.tabIndex = -1;
1441
1438
  this.selectableChildren.push({element: scriptLocationLink, forceSelect: (): void => scriptLocationLink.focus()});
1442
1439
  formattedLine.appendChild(scriptLocationLink);
@@ -1446,6 +1443,30 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1446
1443
  return true;
1447
1444
  }
1448
1445
 
1446
+ private createScriptLocationLinkForSyntaxError(
1447
+ debuggerModel: SDK.DebuggerModel.DebuggerModel, exceptionDetails: Protocol.Runtime.ExceptionDetails): HTMLElement
1448
+ |undefined {
1449
+ const {scriptId, lineNumber, columnNumber} = exceptionDetails;
1450
+ if (!scriptId) {
1451
+ return;
1452
+ }
1453
+
1454
+ // SyntaxErrors might not populate the URL field. Try to resolve it via scriptId.
1455
+ const url = exceptionDetails.url || debuggerModel.scriptForId(scriptId)?.sourceURL;
1456
+ if (!url) {
1457
+ return;
1458
+ }
1459
+
1460
+ const scriptLocationLink = this.linkifier.linkifyScriptLocation(
1461
+ debuggerModel.target(), exceptionDetails.scriptId || null, url, lineNumber, {
1462
+ columnNumber,
1463
+ inlineFrameIndex: 0,
1464
+ showColumnNumber: true,
1465
+ });
1466
+ scriptLocationLink.tabIndex = -1;
1467
+ return scriptLocationLink;
1468
+ }
1469
+
1449
1470
  private tryFormatAsError(string: string, exceptionDetails?: Protocol.Runtime.ExceptionDetails): HTMLElement|null {
1450
1471
  const runtimeModel = this.message.runtimeModel();
1451
1472
  if (!runtimeModel) {
@@ -1465,6 +1486,20 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1465
1486
  for (let i = 0; i < linkInfos.length; ++i) {
1466
1487
  const newline = i < linkInfos.length - 1 ? '\n' : '';
1467
1488
  const {line, link} = linkInfos[i];
1489
+ // Syntax errors don't have a stack frame that points to the source position
1490
+ // where the error occurred. We use the source location from the
1491
+ // exceptionDetails and append it to the end of the message instead.
1492
+ if (!link && exceptionDetails && line.startsWith('SyntaxError')) {
1493
+ formattedResult.appendChild(this.linkifyStringAsFragment(line));
1494
+ const maybeScriptLocation = this.createScriptLocationLinkForSyntaxError(debuggerModel, exceptionDetails);
1495
+ if (maybeScriptLocation) {
1496
+ formattedResult.append(' (at ');
1497
+ formattedResult.appendChild(maybeScriptLocation);
1498
+ formattedResult.append(')');
1499
+ }
1500
+ formattedResult.append(newline);
1501
+ continue;
1502
+ }
1468
1503
  if (!link) {
1469
1504
  formattedResult.appendChild(this.linkifyStringAsFragment(`${line}${newline}`));
1470
1505
  continue;
@@ -1475,8 +1510,6 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1475
1510
  const scriptLocationLink = this.linkifier.linkifyScriptLocation(
1476
1511
  debuggerModel.target(), link.scriptId || null, link.url, link.lineNumber, {
1477
1512
  columnNumber: link.columnNumber,
1478
- className: undefined,
1479
- tabStop: undefined,
1480
1513
  inlineFrameIndex: 0,
1481
1514
  showColumnNumber: true,
1482
1515
  });
@@ -746,7 +746,7 @@ export class CoverageInfo {
746
746
  return this.contentProvider;
747
747
  }
748
748
 
749
- url(): string {
749
+ url(): Platform.DevToolsPath.UrlString {
750
750
  return this.contentProvider.contentURL();
751
751
  }
752
752
 
@@ -1514,14 +1514,8 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1514
1514
  Components.Linkifier.Linkifier.linkifyURL(rewrittenHref, {
1515
1515
  text: value,
1516
1516
  preventClick: true,
1517
- className: undefined,
1518
- lineNumber: undefined,
1519
- columnNumber: undefined,
1520
1517
  showColumnNumber: false,
1521
1518
  inlineFrameIndex: 0,
1522
- maxLength: undefined,
1523
- tabStop: undefined,
1524
- bypassURLTrimming: undefined,
1525
1519
  });
1526
1520
  return ImagePreviewPopover.setImageUrl(link, rewrittenHref);
1527
1521
  }
@@ -1043,16 +1043,22 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1043
1043
  if (!url) {
1044
1044
  return false;
1045
1045
  }
1046
- const changedLines = this.#urlToChangeTracker.get(url)?.changedLines;
1047
- if (!changedLines) {
1046
+ const changeTracker = this.#urlToChangeTracker.get(url);
1047
+ if (!changeTracker) {
1048
1048
  return false;
1049
1049
  }
1050
+ const {changedLines, formattedCurrentMapping} = changeTracker;
1050
1051
  const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().propertyUILocation(property, true);
1051
1052
  if (!uiLocation) {
1052
1053
  return false;
1053
1054
  }
1054
- // UILocation's lineNumber starts at 0, but changedLines start at 1.
1055
- return changedLines.has(uiLocation.lineNumber + 1);
1055
+ if (!formattedCurrentMapping) {
1056
+ // UILocation's lineNumber starts at 0, but changedLines start at 1.
1057
+ return changedLines.has(uiLocation.lineNumber + 1);
1058
+ }
1059
+ const formattedLineNumber =
1060
+ formattedCurrentMapping.originalToFormatted(uiLocation.lineNumber, uiLocation.columnNumber)[0];
1061
+ return changedLines.has(formattedLineNumber + 1);
1056
1062
  }
1057
1063
 
1058
1064
  private async refreshChangedLines(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
@@ -1060,28 +1066,33 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1060
1066
  if (!changeTracker) {
1061
1067
  return;
1062
1068
  }
1063
- const diff = await WorkspaceDiff.WorkspaceDiff.workspaceDiff().requestDiff(uiSourceCode, {shouldFormatDiff: true});
1069
+ const diffResponse =
1070
+ await WorkspaceDiff.WorkspaceDiff.workspaceDiff().requestDiff(uiSourceCode, {shouldFormatDiff: true});
1064
1071
  const changedLines = new Set<number>();
1065
- if (diff && diff.length > 0) {
1066
- const {rows} = DiffView.DiffView.buildDiffRows(diff);
1067
- for (const row of rows) {
1068
- if (row.type === DiffView.DiffView.RowType.Addition) {
1069
- changedLines.add(row.currentLineNumber);
1070
- }
1072
+ changeTracker.changedLines = changedLines;
1073
+ if (!diffResponse) {
1074
+ return;
1075
+ }
1076
+ const {diff, formattedCurrentMapping} = diffResponse;
1077
+ const {rows} = DiffView.DiffView.buildDiffRows(diff);
1078
+ for (const row of rows) {
1079
+ if (row.type === DiffView.DiffView.RowType.Addition) {
1080
+ changedLines.add(row.currentLineNumber);
1071
1081
  }
1072
1082
  }
1073
- changeTracker.changedLines = changedLines;
1083
+ changeTracker.formattedCurrentMapping = formattedCurrentMapping;
1074
1084
  }
1075
1085
 
1076
1086
  private async getFormattedChanges(): Promise<string> {
1077
1087
  let allChanges = '';
1078
1088
  for (const [url, {uiSourceCode}] of this.#urlToChangeTracker) {
1079
- const diff =
1089
+ const diffResponse =
1080
1090
  await WorkspaceDiff.WorkspaceDiff.workspaceDiff().requestDiff(uiSourceCode, {shouldFormatDiff: true});
1081
- if (!diff || diff.length < 2) {
1091
+ // Diff array with real diff will contain at least 2 lines.
1092
+ if (!diffResponse || diffResponse?.diff.length < 2) {
1082
1093
  continue;
1083
1094
  }
1084
- const changes = await formatCSSChangesFromDiff(diff);
1095
+ const changes = await formatCSSChangesFromDiff(diffResponse.diff);
1085
1096
  if (changes.length > 0) {
1086
1097
  allChanges += `/* ${escapeUrlAsCssComment(url)} */\n\n${changes}\n\n`;
1087
1098
  }
@@ -1231,6 +1242,7 @@ type ChangeTracker = {
1231
1242
  uiSourceCode: Workspace.UISourceCode.UISourceCode,
1232
1243
  changedLines: Set<number>,
1233
1244
  diffChangeCallback: () => Promise<void>,
1245
+ formattedCurrentMapping?: Formatter.ScriptFormatter.FormatterSourceMapping,
1234
1246
  };
1235
1247
 
1236
1248
  export async function formatCSSChangesFromDiff(diff: Diff.Diff.DiffArray): Promise<string> {
@@ -2465,9 +2477,9 @@ export class StylePropertiesSection {
2465
2477
  return true;
2466
2478
  }
2467
2479
 
2468
- private editingMediaCommitted(
2480
+ private async editingMediaCommitted(
2469
2481
  query: SDK.CSSQuery.CSSQuery, element: Element, newContent: string, _oldContent: string,
2470
- _context: Context|undefined, _moveDirection: string): void {
2482
+ _context: Context|undefined, _moveDirection: string): Promise<void> {
2471
2483
  this.parentPane.setEditingStyle(false);
2472
2484
  this.editingMediaFinished(element);
2473
2485
 
@@ -2475,7 +2487,20 @@ export class StylePropertiesSection {
2475
2487
  newContent = newContent.trim();
2476
2488
  }
2477
2489
 
2478
- function userCallback(this: StylePropertiesSection, success: boolean): void {
2490
+ // This gets deleted in finishOperation(), which is called both on success and failure.
2491
+ this.parentPane.setUserOperation(true);
2492
+ const cssModel = this.parentPane.cssModel();
2493
+ if (cssModel && query.styleSheetId) {
2494
+ const range = query.range as TextUtils.TextRange.TextRange;
2495
+ let success = false;
2496
+ if (query instanceof SDK.CSSContainerQuery.CSSContainerQuery) {
2497
+ success = await cssModel.setContainerQueryText(query.styleSheetId, range, newContent);
2498
+ } else if (query instanceof SDK.CSSSupports.CSSSupports) {
2499
+ success = await cssModel.setSupportsText(query.styleSheetId, range, newContent);
2500
+ } else {
2501
+ success = await cssModel.setMediaText(query.styleSheetId, range, newContent);
2502
+ }
2503
+
2479
2504
  if (success) {
2480
2505
  this.matchedStyles.resetActiveProperties();
2481
2506
  this.parentPane.refreshUpdate(this);
@@ -2483,16 +2508,6 @@ export class StylePropertiesSection {
2483
2508
  this.parentPane.setUserOperation(false);
2484
2509
  this.editingMediaTextCommittedForTest();
2485
2510
  }
2486
-
2487
- // This gets deleted in finishOperation(), which is called both on success and failure.
2488
- this.parentPane.setUserOperation(true);
2489
- const cssModel = this.parentPane.cssModel();
2490
- if (cssModel && query.styleSheetId) {
2491
- const setQueryText =
2492
- query instanceof SDK.CSSMedia.CSSMedia ? cssModel.setMediaText : cssModel.setContainerQueryText;
2493
- void setQueryText.call(cssModel, query.styleSheetId, (query.range as TextUtils.TextRange.TextRange), newContent)
2494
- .then(userCallback.bind(this));
2495
- }
2496
2511
  }
2497
2512
 
2498
2513
  private editingMediaTextCommittedForTest(): void {
@@ -3389,13 +3404,8 @@ export class StylesSidebarPropertyRenderer {
3389
3404
  // so that we don't have to keep two versions (original vs. trimmed) of URL
3390
3405
  // at the same time, which complicates both StylesSidebarPane and StylePropertyTreeElement.
3391
3406
  bypassURLTrimming: true,
3392
- className: undefined,
3393
- lineNumber: undefined,
3394
- columnNumber: undefined,
3395
3407
  showColumnNumber: false,
3396
3408
  inlineFrameIndex: 0,
3397
- maxLength: undefined,
3398
- tabStop: undefined,
3399
3409
  }),
3400
3410
  hrefUrl || url);
3401
3411
  container.appendChild(link);
@@ -270,7 +270,7 @@ export class LayoutPane extends HTMLElement {
270
270
  </span>
271
271
  </label>
272
272
  <label @keyup=${onColorLabelKeyUp} @keydown=${onColorLabelKeyDown} tabindex="0" title=${i18nString(UIStrings.chooseElementOverlayColor)} class="color-picker-label" style="background: ${element.color};">
273
- <input @change=${onColorChange} @input=${onColorChange} class="color-picker" type="color" value=${element.color} />
273
+ <input @change=${onColorChange} @input=${onColorChange} tabindex="-1" class="color-picker" type="color" value=${element.color} />
274
274
  </label>
275
275
  <button tabindex="0" @click=${onElementClick} title=${i18nString(UIStrings.showElementInTheElementsPanel)} class="show-element"></button>
276
276
  </div>`;
@@ -256,7 +256,7 @@ export abstract class AffectedResourcesView extends UI.TreeOutline.TreeElement {
256
256
  const linkifier = new Components.Linkifier.Linkifier(maxLengthForDisplayedURLs);
257
257
  const sourceAnchor = linkifier.linkifyScriptLocation(
258
258
  target || null, sourceLocation.scriptId || null, sourceLocation.url, sourceLocation.lineNumber,
259
- {columnNumber: sourceLocation.columnNumber, inlineFrameIndex: 0, className: undefined, tabStop: undefined});
259
+ {columnNumber: sourceLocation.columnNumber, inlineFrameIndex: 0});
260
260
  sourceCodeLocation.appendChild(sourceAnchor);
261
261
  }
262
262
  element.appendChild(sourceCodeLocation);
@@ -36,7 +36,7 @@ export class AffectedSourcesView extends AffectedResourcesView {
36
36
  const cellElement = document.createElement('td');
37
37
  // TODO(chromium:1072331): Check feasibility of plumping through scriptId for `linkifyScriptLocation`
38
38
  // to support source maps and formatted scripts.
39
- const linkifierURLOptions = ({columnNumber, lineNumber, tabStop: true} as Components.Linkifier.LinkifyURLOptions);
39
+ const linkifierURLOptions = {columnNumber, lineNumber, tabStop: true, showColumnNumber: false, inlineFrameIndex: 0};
40
40
  // An element created with linkifyURL can subscribe to the events
41
41
  // 'click' neither 'keydown' if that key is the 'Enter' key.
42
42
  // Also, this element has a context menu, so we should be able to
@@ -113,11 +113,15 @@ const UIStrings = {
113
113
  */
114
114
  runLighthouseInMode: 'Run Lighthouse in navigation, timespan, or snapshot mode',
115
115
  /**
116
- * @description Text for Lighthouse navigation mode.
116
+ * @description Label of a radio option for a Lighthouse mode that audits a page navigation.
117
117
  */
118
118
  navigation: 'Navigation',
119
119
  /**
120
- * @description Text for Lighthouse snapshot mode.
120
+ * @description Label of a radio option for a Lighthouse mode that audits user interactions over a period of time.
121
+ */
122
+ timespan: 'Timespan',
123
+ /**
124
+ * @description Label of a radio option for a Lighthouse mode that audits the current page state.
121
125
  */
122
126
  snapshot: 'Snapshot',
123
127
  /**
@@ -305,6 +309,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
305
309
  internalDisableDeviceScreenEmulation: boolean,
306
310
  emulatedFormFactor: (string|undefined),
307
311
  legacyNavigation: boolean,
312
+ mode: string,
308
313
  } {
309
314
  const flags = {
310
315
  // DevTools handles all the emulation. This tells Lighthouse to not bother with emulation.
@@ -317,6 +322,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
317
322
  internalDisableDeviceScreenEmulation: boolean,
318
323
  emulatedFormFactor: (string | undefined),
319
324
  legacyNavigation: boolean,
325
+ mode: string,
320
326
  };
321
327
  }
322
328
 
@@ -447,6 +453,7 @@ export const RuntimeSettings: RuntimeSetting[] = [
447
453
  },
448
454
  options: [
449
455
  {label: i18nLazyString(UIStrings.navigation), value: 'navigation'},
456
+ {label: i18nLazyString(UIStrings.timespan), value: 'timespan'},
450
457
  {label: i18nLazyString(UIStrings.snapshot), value: 'snapshot'},
451
458
  ],
452
459
  learnMore: undefined,
@@ -495,6 +502,8 @@ export enum Events {
495
502
  PageAuditabilityChanged = 'PageAuditabilityChanged',
496
503
  PageWarningsChanged = 'PageWarningsChanged',
497
504
  AuditProgressChanged = 'AuditProgressChanged',
505
+ RequestLighthouseTimespanStart = 'RequestLighthouseTimespanStart',
506
+ RequestLighthouseTimespanEnd = 'RequestLighthouseTimespanEnd',
498
507
  RequestLighthouseStart = 'RequestLighthouseStart',
499
508
  RequestLighthouseCancel = 'RequestLighthouseCancel',
500
509
  }
@@ -515,6 +524,8 @@ export type EventTypes = {
515
524
  [Events.PageAuditabilityChanged]: PageAuditabilityChangedEvent,
516
525
  [Events.PageWarningsChanged]: PageWarningsChangedEvent,
517
526
  [Events.AuditProgressChanged]: AuditProgressChangedEvent,
527
+ [Events.RequestLighthouseTimespanStart]: boolean,
528
+ [Events.RequestLighthouseTimespanEnd]: boolean,
518
529
  [Events.RequestLighthouseStart]: boolean,
519
530
  [Events.RequestLighthouseCancel]: void,
520
531
  };