chrome-devtools-frontend 1.0.1003647 → 1.0.1004895

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 (53) hide show
  1. package/config/gni/devtools_grd_files.gni +2 -0
  2. package/front_end/core/common/ParsedURL.ts +7 -3
  3. package/front_end/core/host/UserMetrics.ts +1 -1
  4. package/front_end/core/i18n/locales/en-US.json +48 -6
  5. package/front_end/core/i18n/locales/en-XL.json +48 -6
  6. package/front_end/core/sdk/DOMModel.ts +15 -0
  7. package/front_end/core/sdk/DebuggerModel.ts +12 -0
  8. package/front_end/core/sdk/NetworkManager.ts +2 -2
  9. package/front_end/core/sdk/ResourceTreeModel.ts +32 -6
  10. package/front_end/core/sdk/RuntimeModel.ts +5 -3
  11. package/front_end/core/sdk/WebAuthnModel.ts +1 -1
  12. package/front_end/entrypoints/main/MainImpl.ts +2 -2
  13. package/front_end/generated/InspectorBackendCommands.js +8 -2
  14. package/front_end/generated/SupportedCSSProperties.js +4 -0
  15. package/front_end/generated/protocol-mapping.d.ts +14 -2
  16. package/front_end/generated/protocol-proxy-api.d.ts +14 -2
  17. package/front_end/generated/protocol.ts +24 -1
  18. package/front_end/models/extensions/ExtensionPanel.ts +1 -1
  19. package/front_end/models/extensions/ExtensionServer.ts +12 -14
  20. package/front_end/models/har/Log.ts +4 -3
  21. package/front_end/models/issues_manager/DeprecationIssue.ts +3 -11
  22. package/front_end/panels/application/components/FrameDetailsView.ts +28 -0
  23. package/front_end/panels/console/ErrorStackParser.ts +2 -5
  24. package/front_end/panels/elements/ElementsTreeElement.ts +41 -0
  25. package/front_end/panels/elements/ElementsTreeOutline.ts +5 -0
  26. package/front_end/panels/elements/components/AdornerManager.ts +7 -0
  27. package/front_end/panels/elements/elementsTreeOutline.css +9 -0
  28. package/front_end/panels/issues/AffectedDirectivesView.ts +4 -3
  29. package/front_end/panels/lighthouse/LighthouseController.ts +6 -6
  30. package/front_end/panels/lighthouse/LighthousePanel.ts +1 -3
  31. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +2 -1
  32. package/front_end/panels/network/NetworkItemView.ts +10 -1
  33. package/front_end/panels/network/NetworkLogView.ts +7 -4
  34. package/front_end/panels/network/RequestHeadersView.ts +1 -1
  35. package/front_end/panels/network/ResourceWebSocketFrameView.ts +2 -2
  36. package/front_end/panels/network/components/RequestHeadersView.css +78 -0
  37. package/front_end/panels/network/components/RequestHeadersView.ts +262 -0
  38. package/front_end/panels/network/components/components.ts +2 -0
  39. package/front_end/panels/network/forward/UIRequestLocation.ts +1 -0
  40. package/front_end/panels/network/networkLogView.css +3 -3
  41. package/front_end/panels/network/requestHeadersTree.css +6 -0
  42. package/front_end/panels/profiler/HeapSnapshotView.ts +11 -13
  43. package/front_end/panels/profiler/LiveHeapProfileView.ts +0 -1
  44. package/front_end/panels/screencast/ScreencastView.ts +0 -1
  45. package/front_end/panels/settings/SettingsScreen.ts +0 -1
  46. package/front_end/panels/sources/CallStackSidebarPane.ts +13 -0
  47. package/front_end/panels/sources/NavigatorView.ts +0 -2
  48. package/front_end/panels/sources/ScopeChainSidebarPane.ts +4 -3
  49. package/front_end/panels/sources/SourcesSearchScope.ts +0 -2
  50. package/front_end/panels/sources/sourcesView.css +4 -0
  51. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +16 -2
  52. package/front_end/ui/legacy/components/data_grid/ViewportDataGrid.ts +2 -2
  53. package/package.json +1 -1
@@ -3212,6 +3212,7 @@ export namespace DOM {
3212
3212
  */
3213
3213
  isSVG?: boolean;
3214
3214
  compatibilityMode?: CompatibilityMode;
3215
+ assignedSlot?: BackendNode;
3215
3216
  }
3216
3217
 
3217
3218
  /**
@@ -10177,6 +10178,7 @@ export namespace Page {
10177
10178
  AmbientLightSensor = 'ambient-light-sensor',
10178
10179
  AttributionReporting = 'attribution-reporting',
10179
10180
  Autoplay = 'autoplay',
10181
+ Bluetooth = 'bluetooth',
10180
10182
  BrowsingTopics = 'browsing-topics',
10181
10183
  Camera = 'camera',
10182
10184
  ChDpr = 'ch-dpr',
@@ -11296,7 +11298,8 @@ export namespace Page {
11296
11298
  */
11297
11299
  frameId: FrameId;
11298
11300
  /**
11299
- * Loader identifier.
11301
+ * Loader identifier. This is omitted in case of same-document navigation,
11302
+ * as the previously committed loaderId would not change.
11300
11303
  */
11301
11304
  loaderId?: Network.LoaderId;
11302
11305
  /**
@@ -14480,6 +14483,17 @@ export namespace WebAuthn {
14480
14483
  largeBlob?: binary;
14481
14484
  }
14482
14485
 
14486
+ export interface EnableRequest {
14487
+ /**
14488
+ * Whether to enable the WebAuthn user interface. Enabling the UI is
14489
+ * recommended for debugging and demo purposes, as it is closer to the real
14490
+ * experience. Disabling the UI is recommended for automated testing.
14491
+ * Supported at the embedder's discretion if UI is available.
14492
+ * Defaults to false.
14493
+ */
14494
+ enableUI?: boolean;
14495
+ }
14496
+
14483
14497
  export interface AddVirtualAuthenticatorRequest {
14484
14498
  options: VirtualAuthenticatorOptions;
14485
14499
  }
@@ -15023,11 +15037,20 @@ export namespace Debugger {
15023
15037
  breakpointId: BreakpointId;
15024
15038
  }
15025
15039
 
15040
+ export const enum RestartFrameRequestMode {
15041
+ StepInto = 'StepInto',
15042
+ }
15043
+
15026
15044
  export interface RestartFrameRequest {
15027
15045
  /**
15028
15046
  * Call frame identifier to evaluate on.
15029
15047
  */
15030
15048
  callFrameId: CallFrameId;
15049
+ /**
15050
+ * The `mode` parameter must be present and set to 'StepInto', otherwise
15051
+ * `restartFrame` will error out.
15052
+ */
15053
+ mode?: RestartFrameRequestMode;
15031
15054
  }
15032
15055
 
15033
15056
  export interface RestartFrameResponse extends ProtocolResponseWithError {
@@ -157,7 +157,7 @@ export class ExtensionSidebarPane extends UI.View.SimpleView {
157
157
  expression, true, false, evaluateOptions, securityOrigin, this.onEvaluate.bind(this, title, callback));
158
158
  }
159
159
 
160
- setPage(url: string): void {
160
+ setPage(url: Platform.DevToolsPath.UrlString): void {
161
161
  if (this.objectPropertiesView) {
162
162
  this.objectPropertiesView.detach();
163
163
  delete this.objectPropertiesView;
@@ -31,8 +31,6 @@
31
31
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
32
32
  /* eslint-disable @typescript-eslint/naming-convention */
33
33
 
34
- // TODO(crbug.com/1253323): Casts to UrlString will be removed from this file when migration to branded types is complete.
35
-
36
34
  import * as Common from '../../core/common/common.js';
37
35
  import * as Host from '../../core/host/host.js';
38
36
  import * as i18n from '../../core/i18n/i18n.js';
@@ -56,7 +54,7 @@ import {ExtensionTraceProvider} from './ExtensionTraceProvider.js';
56
54
  import {LanguageExtensionEndpoint} from './LanguageExtensionEndpoint.js';
57
55
  import {PrivateAPI} from './ExtensionAPI.js';
58
56
 
59
- const extensionOrigins: WeakMap<MessagePort, string> = new WeakMap();
57
+ const extensionOrigins: WeakMap<MessagePort, Platform.DevToolsPath.UrlString> = new WeakMap();
60
58
 
61
59
  declare global {
62
60
  interface Window {
@@ -344,7 +342,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
344
342
  return undefined;
345
343
  }
346
344
 
347
- private getExtensionOrigin(port: MessagePort): string {
345
+ private getExtensionOrigin(port: MessagePort): Platform.DevToolsPath.UrlString {
348
346
  const origin = extensionOrigins.get(port);
349
347
  if (!origin) {
350
348
  throw new Error('Received a message from an unregistered extension');
@@ -503,8 +501,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
503
501
  if (message.command !== PrivateAPI.Commands.OpenResource) {
504
502
  return this.status.E_BADARG('command', `expected ${PrivateAPI.Commands.OpenResource}`);
505
503
  }
506
- const uiSourceCode =
507
- Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(message.url as Platform.DevToolsPath.UrlString);
504
+ const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(message.url);
508
505
  if (uiSourceCode) {
509
506
  void Common.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, message.columnNumber));
510
507
  return this.status.OK();
@@ -840,7 +837,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
840
837
  this.postNotification(PrivateAPI.Events.PanelObjectSelected + 'elements');
841
838
  }
842
839
 
843
- sourceSelectionChanged(url: string, range: TextUtils.TextRange.TextRange): void {
840
+ sourceSelectionChanged(url: Platform.DevToolsPath.UrlString, range: TextUtils.TextRange.TextRange): void {
844
841
  this.postNotification(PrivateAPI.Events.PanelObjectSelected + 'sources', {
845
842
  startLine: range.startLine,
846
843
  startColumn: range.startColumn,
@@ -896,7 +893,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
896
893
  return true;
897
894
  }
898
895
 
899
- private registerExtension(origin: string, port: MessagePort): void {
896
+ private registerExtension(origin: Platform.DevToolsPath.UrlString, port: MessagePort): void {
900
897
  if (!this.registeredExtensions.has(origin)) {
901
898
  if (origin !== window.location.origin) { // Just ignore inspector frames.
902
899
  console.error('Ignoring unauthorized client request from ' + origin);
@@ -910,7 +907,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
910
907
 
911
908
  private onWindowMessage(event: MessageEvent): void {
912
909
  if (event.data === 'registerExtension') {
913
- this.registerExtension(event.origin, event.ports[0]);
910
+ this.registerExtension(event.origin as Platform.DevToolsPath.UrlString, event.ports[0]);
914
911
  }
915
912
  }
916
913
 
@@ -984,8 +981,9 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
984
981
  removeLastEventListener.bind(this));
985
982
  }
986
983
 
987
- private expandResourcePath(extensionPath: string, resourcePath: string): string {
988
- return extensionPath + '/' + Common.ParsedURL.normalizePath(resourcePath);
984
+ private expandResourcePath(extensionPath: Platform.DevToolsPath.UrlString, resourcePath: string):
985
+ Platform.DevToolsPath.UrlString {
986
+ return extensionPath + '/' + Common.ParsedURL.normalizePath(resourcePath) as Platform.DevToolsPath.UrlString;
989
987
  }
990
988
 
991
989
  evaluate(
@@ -995,7 +993,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
995
993
  |undefined {
996
994
  let context;
997
995
 
998
- function resolveURLToFrame(url: string): SDK.ResourceTreeModel.ResourceTreeFrame|null {
996
+ function resolveURLToFrame(url: Platform.DevToolsPath.UrlString): SDK.ResourceTreeModel.ResourceTreeFrame|null {
999
997
  let found = null;
1000
998
  function hasMatchingURL(frame: SDK.ResourceTreeModel.ResourceTreeFrame): SDK.ResourceTreeModel.ResourceTreeFrame|
1001
999
  null {
@@ -1009,7 +1007,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1009
1007
  options = options || {};
1010
1008
  let frame;
1011
1009
  if (options.frameURL) {
1012
- frame = resolveURLToFrame(options.frameURL);
1010
+ frame = resolveURLToFrame(options.frameURL as Platform.DevToolsPath.UrlString);
1013
1011
  } else {
1014
1012
  const target = SDK.TargetManager.TargetManager.instance().mainTarget();
1015
1013
  const resourceTreeModel = target && target.model(SDK.ResourceTreeModel.ResourceTreeModel);
@@ -1088,7 +1086,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1088
1086
  return undefined;
1089
1087
  }
1090
1088
 
1091
- private canInspectURL(url: string): boolean {
1089
+ private canInspectURL(url: Platform.DevToolsPath.UrlString): boolean {
1092
1090
  let parsedURL;
1093
1091
  // This is only to work around invalid URLs we're occasionally getting from some tests.
1094
1092
  // TODO(caseq): make sure tests supply valid URLs or we specifically handle invalid ones.
@@ -35,6 +35,7 @@
35
35
  // See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.
36
36
 
37
37
  import * as Common from '../../core/common/common.js';
38
+ import type * as Platform from '../../core/platform/platform.js';
38
39
  import * as SDK from '../../core/sdk/sdk.js';
39
40
  import type * as Protocol from '../../generated/protocol.js';
40
41
 
@@ -346,8 +347,8 @@ export class Entry {
346
347
  return parameters.slice();
347
348
  }
348
349
 
349
- private buildRequestURL(url: string): string {
350
- return url.split('#', 2)[0];
350
+ private buildRequestURL(url: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.UrlString {
351
+ return Common.ParsedURL.ParsedURL.split(url, '#', 2)[0];
351
352
  }
352
353
 
353
354
  private buildCookies(cookies: SDK.Cookie.Cookie[]): CookieDTO[] {
@@ -438,7 +439,7 @@ export interface Content {
438
439
 
439
440
  export interface Request {
440
441
  method: string;
441
- url: string;
442
+ url: Platform.DevToolsPath.UrlString;
442
443
  httpVersion: string;
443
444
  headers: Object;
444
445
  queryString: Parameter[];
@@ -34,7 +34,9 @@ const UIStrings = {
34
34
  authorizationCoveredByWildcard:
35
35
  'Authorization will not be covered by the wildcard symbol (*) in CORS `Access-Control-Allow-Headers` handling.',
36
36
  /**
37
- * @description TODO(crbug.com/1320334): Description needed for translation
37
+ * @description This warning occurs when a page attempts to request a resource
38
+ * whose URL contained both a newline character (`\n` or `\r`), and a
39
+ * less-than character (`<`). These resources are blocked.
38
40
  */
39
41
  canRequestURLHTTPContainingNewline:
40
42
  'Resource requests whose URLs contained both removed whitespace `\\(n|r|t)` characters and less-than characters (`<`) are blocked. Please remove newlines and encode less-than characters from places like element attribute values in order to load these resources.',
@@ -137,11 +139,6 @@ const UIStrings = {
137
139
  */
138
140
  localCSSFileExtensionRejected:
139
141
  'CSS cannot be loaded from `file:` URLs unless they end in a `.css` file extension.',
140
- /**
141
- * @description TODO(crbug.com/1320344): Description needed for translation
142
- */
143
- mediaElementAudioSourceNode:
144
- 'Creating a `MediaElementAudioSourceNode` on an `OfflineAudioContext` is deprecated and will be removed.',
145
142
  /**
146
143
  * @description TODO(crbug.com/1320345): Description needed for translation
147
144
  */
@@ -415,11 +412,6 @@ export class DeprecationIssue extends Issue {
415
412
  messageFunction = i18nLazyString(UIStrings.localCSSFileExtensionRejected);
416
413
  milestone = 64;
417
414
  break;
418
- case Protocol.Audits.DeprecationIssueType.MediaElementAudioSourceNode:
419
- messageFunction = i18nLazyString(UIStrings.mediaElementAudioSourceNode);
420
- feature = 5258622686724096;
421
- milestone = 71;
422
- break;
423
415
  case Protocol.Audits.DeprecationIssueType.MediaSourceAbortRemove:
424
416
  messageFunction = i18nLazyString(UIStrings.mediaSourceAbortRemove);
425
417
  feature = 6107495151960064;
@@ -240,6 +240,14 @@ const UIStrings = {
240
240
  *@description Label for a button which when clicked causes some information to be refreshed/updated.
241
241
  */
242
242
  refresh: 'Refresh',
243
+ /**
244
+ *@description Label for section of frame details view
245
+ */
246
+ prerendering: 'Prerendering',
247
+ /**
248
+ *@description Label for subtitle of frame details view
249
+ */
250
+ prerenderingStatus: 'Prerendering Status',
243
251
  };
244
252
  const str_ = i18n.i18n.registerUIStrings('panels/application/components/FrameDetailsView.ts', UIStrings);
245
253
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -253,6 +261,8 @@ export class FrameDetailsView extends UI.ThrottledWidget.ThrottledWidget {
253
261
  this.contentElement.classList.add('overflow-auto');
254
262
  this.contentElement.appendChild(this.#reportView);
255
263
  this.update();
264
+ frame.resourceTreeModel().addEventListener(
265
+ SDK.ResourceTreeModel.Events.PrerenderingStatusUpdated, this.update, this);
256
266
  }
257
267
 
258
268
  async doUpdate(): Promise<void> {
@@ -311,6 +321,7 @@ export class FrameDetailsReportView extends HTMLElement {
311
321
  </${PermissionsPolicySection.litTagName}>
312
322
  `;
313
323
  }), LitHtml.nothing)}
324
+ ${this.#renderPrerenderingSection()}
314
325
  ${this.#protocolMonitorExperimentEnabled ? this.#renderAdditionalInfoSection() : LitHtml.nothing}
315
326
  </${ReportView.ReportView.Report.litTagName}>
316
327
  `, this.#shadow, {host: this});
@@ -750,6 +761,23 @@ export class FrameDetailsReportView extends HTMLElement {
750
761
  return LitHtml.nothing;
751
762
  }
752
763
 
764
+ #renderPrerenderingSection(): LitHtml.LitTemplate {
765
+ if (!this.#frame || !this.#frame.prerenderFinalStatus) {
766
+ return LitHtml.nothing;
767
+ }
768
+
769
+ return LitHtml.html`
770
+ <${ReportView.ReportView.ReportSectionHeader.litTagName}>
771
+ ${i18nString(UIStrings.prerendering)}</${ReportView.ReportView.ReportSectionHeader.litTagName}>
772
+ <${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.prerenderingStatus)}</${
773
+ ReportView.ReportView.ReportKey.litTagName}>
774
+ <${ReportView.ReportView.ReportValue.litTagName}>
775
+ <div class="text-ellipsis" title=${this.#frame.prerenderFinalStatus}>${this.#frame.prerenderFinalStatus}</div>
776
+ </${ReportView.ReportView.ReportValue.litTagName}>
777
+ <${ReportView.ReportView.ReportSectionDivider.litTagName}></${
778
+ ReportView.ReportView.ReportSectionDivider.litTagName}>`;
779
+ }
780
+
753
781
  #renderAdditionalInfoSection(): LitHtml.LitTemplate {
754
782
  if (!this.#frame) {
755
783
  return LitHtml.nothing;
@@ -7,8 +7,6 @@ import type * as Platform from '../../core/platform/platform.js';
7
7
  import type * as SDK from '../../core/sdk/sdk.js';
8
8
  import type * as Protocol from '../../generated/protocol.js';
9
9
 
10
- // TODO(crbug.com/1253323): Casts to UrlString will be removed from this file when migration to branded types is complete.
11
-
12
10
  export interface ParsedErrorFrame {
13
11
  line: string;
14
12
  link?: {
@@ -109,9 +107,8 @@ function parseOrScriptMatch(debuggerModel: SDK.DebuggerModel.DebuggerModel, url:
109
107
  if (!url) {
110
108
  return null;
111
109
  }
112
- const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
113
- if (parsedURL) {
114
- return parsedURL.url as Platform.DevToolsPath.UrlString;
110
+ if (Common.ParsedURL.ParsedURL.isValidUrlString(url)) {
111
+ return url;
115
112
  }
116
113
  if (debuggerModel.scriptsForSourceURL(url).length) {
117
114
  return url;
@@ -41,6 +41,7 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
41
41
  import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
42
42
  import * as Adorners from '../../ui/components/adorners/adorners.js';
43
43
  import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
44
+ import * as IconButton from '../../ui/components/icon_button/icon_button.js';
44
45
  import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
45
46
  import * as Components from '../../ui/legacy/components/utils/utils.js';
46
47
  import * as UI from '../../ui/legacy/legacy.js';
@@ -237,6 +238,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
237
238
  private searchHighlightsVisible?: boolean;
238
239
  selectionElement?: HTMLDivElement;
239
240
  private hintElement?: HTMLElement;
241
+ #slot?: Adorners.Adorner.Adorner;
240
242
  private contentElement: HTMLElement;
241
243
 
242
244
  constructor(node: SDK.DOMModel.DOMNode, isClosingTag?: boolean) {
@@ -422,6 +424,21 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
422
424
  this.expandedChildrenLimitInternal = expandedChildrenLimit;
423
425
  }
424
426
 
427
+ createSlotLink(nodeShortcut: SDK.DOMModel.DOMNodeShortcut|null): void {
428
+ if (nodeShortcut) {
429
+ const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
430
+ ElementsComponents.AdornerManager.RegisteredAdorners.SLOT);
431
+ this.#slot = this.adornSlot(config);
432
+ const deferredNode = nodeShortcut.deferredNode;
433
+ this.#slot.addEventListener('click', () => {
434
+ deferredNode.resolve(node => {
435
+ void Common.Revealer.reveal(node);
436
+ });
437
+ });
438
+ this.#slot.addEventListener('mousedown', e => e.consume(), false);
439
+ }
440
+ }
441
+
425
442
  private createSelection(): void {
426
443
  const contentElement = this.contentElement;
427
444
  if (!contentElement) {
@@ -1314,6 +1331,9 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1314
1331
  if (!this.isClosingTagInternal && this.adornerContainer) {
1315
1332
  this.contentElement.append(this.adornerContainer);
1316
1333
  }
1334
+ if (this.#slot) {
1335
+ this.contentElement.append(this.#slot);
1336
+ }
1317
1337
  this.highlightResult = [];
1318
1338
  delete this.selectionElement;
1319
1339
  delete this.hintElement;
@@ -1936,6 +1956,27 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1936
1956
  return adorner;
1937
1957
  }
1938
1958
 
1959
+ adornSlot({name}: {name: string}): Adorners.Adorner.Adorner {
1960
+ const linkIcon = new IconButton.Icon.Icon();
1961
+ linkIcon
1962
+ .data = {iconName: 'ic_show_node_16x16', color: 'var(--color-text-disabled)', width: '12px', height: '12px'};
1963
+ const slotText = document.createElement('span');
1964
+ slotText.textContent = name;
1965
+ const adornerContent = document.createElement('span');
1966
+ adornerContent.append(linkIcon);
1967
+ adornerContent.append(slotText);
1968
+ adornerContent.classList.add('adorner-with-icon');
1969
+ const adorner = new Adorners.Adorner.Adorner();
1970
+ adorner.data = {
1971
+ name,
1972
+ content: adornerContent,
1973
+ };
1974
+ this.adorners.push(adorner);
1975
+ ElementsPanel.instance().registerAdorner(adorner);
1976
+ this.updateAdorners();
1977
+ return adorner;
1978
+ }
1979
+
1939
1980
  removeAdorner(adornerToRemove: Adorners.Adorner.Adorner): void {
1940
1981
  const adorners = this.adorners;
1941
1982
  ElementsPanel.instance().deregisterAdorner(adornerToRemove);
@@ -1180,6 +1180,11 @@ export class ElementsTreeOutline extends
1180
1180
  !node.parentNode.parentNode) {
1181
1181
  treeElement.setCollapsible(false);
1182
1182
  }
1183
+
1184
+ if (node.hasAssignedSlot()) {
1185
+ treeElement.createSlotLink(node.assignedSlot);
1186
+ }
1187
+
1183
1188
  treeElement.selectable = Boolean(this.selectEnabled);
1184
1189
  return treeElement;
1185
1190
  }
@@ -29,6 +29,7 @@ export enum RegisteredAdorners {
29
29
  AD = 'ad',
30
30
  SCROLL_SNAP = 'scroll-snap',
31
31
  CONTAINER = 'container',
32
+ SLOT = 'slot',
32
33
  }
33
34
 
34
35
  // This enum-like const object serves as the authoritative registry for all the
@@ -65,6 +66,12 @@ export function getRegisteredAdorner(which: RegisteredAdorners): RegisteredAdorn
65
66
  category: AdornerCategories.LAYOUT,
66
67
  enabledByDefault: true,
67
68
  };
69
+ case RegisteredAdorners.SLOT:
70
+ return {
71
+ name: 'slot',
72
+ category: AdornerCategories.LAYOUT,
73
+ enabledByDefault: true,
74
+ };
68
75
  }
69
76
  }
70
77
 
@@ -27,6 +27,15 @@
27
27
  display: none;
28
28
  }
29
29
 
30
+ .adorner-with-icon {
31
+ display: flex;
32
+ justify-content: center;
33
+ }
34
+
35
+ .adorner-with-icon *:not(:last-child) {
36
+ margin-right: 2px;
37
+ }
38
+
30
39
  .elements-disclosure {
31
40
  width: 100%;
32
41
  display: inline-block;
@@ -5,7 +5,7 @@
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 type * as Platform from '../../core/platform/platform.js';
8
+ import * as Platform from '../../core/platform/platform.js';
9
9
  import type * as Protocol from '../../generated/protocol.js';
10
10
  import * as SDK from '../../core/sdk/sdk.js';
11
11
  import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
@@ -79,7 +79,7 @@ export class AffectedDirectivesView extends AffectedResourcesView {
79
79
  element.appendChild(violatedDirective);
80
80
  }
81
81
 
82
- #appendBlockedURL(element: Element, url: string): void {
82
+ #appendBlockedURL(element: Element, url: Platform.DevToolsPath.UrlString): void {
83
83
  const info = document.createElement('td');
84
84
  info.classList.add('affected-resource-directive-info');
85
85
  info.textContent = url;
@@ -178,7 +178,8 @@ export class AffectedDirectivesView extends AffectedResourcesView {
178
178
  this.appendSourceLocation(element, location, maybeTarget);
179
179
  this.#appendStatus(element, cspIssueDetails.isReportOnly);
180
180
  } else if (this.issue.code() === IssuesManager.ContentSecurityPolicyIssue.urlViolationCode) {
181
- const url = cspIssueDetails.blockedURL ? cspIssueDetails.blockedURL : '';
181
+ const url = cspIssueDetails.blockedURL ? cspIssueDetails.blockedURL as Platform.DevToolsPath.UrlString :
182
+ Platform.DevToolsPath.EmptyUrlString;
182
183
  this.#appendBlockedURL(element, url);
183
184
  this.#appendStatus(element, cspIssueDetails.isReportOnly);
184
185
  this.#appendViolatedDirective(element, cspIssueDetails.violatedDirective);
@@ -4,7 +4,7 @@
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as i18n from '../../core/i18n/i18n.js';
7
- import type * as Platform from '../../core/platform/platform.js';
7
+ import * as Platform from '../../core/platform/platform.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
9
9
  import * as Protocol from '../../generated/protocol.js';
10
10
 
@@ -186,7 +186,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
186
186
  SDK.TargetManager.SDKModelObserver<SDK.ServiceWorkerManager.ServiceWorkerManager> {
187
187
  private manager?: SDK.ServiceWorkerManager.ServiceWorkerManager|null;
188
188
  private serviceWorkerListeners?: Common.EventTarget.EventDescriptor[];
189
- private inspectedURL?: string;
189
+ private inspectedURL?: Platform.DevToolsPath.UrlString;
190
190
 
191
191
  constructor(protocolService: ProtocolService) {
192
192
  super();
@@ -314,9 +314,9 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
314
314
  return '';
315
315
  }
316
316
 
317
- private async evaluateInspectedURL(): Promise<string> {
317
+ private async evaluateInspectedURL(): Promise<Platform.DevToolsPath.UrlString> {
318
318
  if (!this.manager) {
319
- return '';
319
+ return Platform.DevToolsPath.EmptyUrlString;
320
320
  }
321
321
  const mainTarget = this.manager.target();
322
322
  // target.inspectedURL is reliably populated, however it lacks any url #hash
@@ -331,7 +331,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
331
331
 
332
332
  const {currentIndex, entries} = navHistory;
333
333
  const navigationEntry = entries[currentIndex];
334
- return navigationEntry.url;
334
+ return navigationEntry.url as Platform.DevToolsPath.UrlString;
335
335
  }
336
336
 
337
337
  getFlags(): {
@@ -365,7 +365,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
365
365
  return categoryIDs;
366
366
  }
367
367
 
368
- async getInspectedURL(options?: {force: boolean}): Promise<string> {
368
+ async getInspectedURL(options?: {force: boolean}): Promise<Platform.DevToolsPath.UrlString> {
369
369
  if (options && options.force || !this.inspectedURL) {
370
370
  this.inspectedURL = await this.evaluateInspectedURL();
371
371
  }
@@ -5,7 +5,6 @@
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 type * as Platform from '../../core/platform/platform.js';
9
8
  import * as Root from '../../core/root/root.js';
10
9
  import * as SDK from '../../core/sdk/sdk.js';
11
10
  import * as EmulationModel from '../../models/emulation/emulation.js';
@@ -503,8 +502,7 @@ export class LighthousePanel extends UI.Panel.Panel {
503
502
  }
504
503
  // reload to reset the page state
505
504
  const inspectedURL = await this.controller.getInspectedURL();
506
- // TODO(crbug.com/1253323): Cast to UrlString will be removed when migration to branded types is complete.
507
- await resourceTreeModel.navigate(inspectedURL as Platform.DevToolsPath.UrlString);
505
+ await resourceTreeModel.navigate(inspectedURL);
508
506
  }
509
507
 
510
508
  wasShown(): void {
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as i18n from '../../core/i18n/i18n.js';
6
6
  import type * as ProtocolClient from '../../core/protocol_client/protocol_client.js';
7
+ import type * as Platform from '../../core/platform/platform.js';
7
8
  import * as SDK from '../../core/sdk/sdk.js';
8
9
 
9
10
  import type * as ReportRenderer from './LighthouseReporterTypes.js';
@@ -45,7 +46,7 @@ LighthouseWorkerService ││ Either ConnectionProxy or LegacyPort
45
46
  let lastId = 1;
46
47
 
47
48
  export interface LighthouseRun {
48
- inspectedURL: string;
49
+ inspectedURL: Platform.DevToolsPath.UrlString;
49
50
  categoryIDs: string[];
50
51
  flags: Record<string, Object|undefined>;
51
52
  }
@@ -30,12 +30,14 @@
30
30
 
31
31
  import * as Common from '../../core/common/common.js';
32
32
  import * as i18n from '../../core/i18n/i18n.js';
33
+ import * as Root from '../../core/root/root.js';
33
34
  import * as SDK from '../../core/sdk/sdk.js';
34
35
  import * as NetworkForward from '../../panels/network/forward/forward.js';
35
36
  import * as UI from '../../ui/legacy/legacy.js';
36
- import * as NetworkComponents from './components/components.js';
37
37
 
38
+ import * as NetworkComponents from './components/components.js';
38
39
  import {EventSourceMessagesView} from './EventSourceMessagesView.js';
40
+
39
41
  import type {NetworkTimeCalculator} from './NetworkTimeCalculator.js';
40
42
  import {RequestCookiesView} from './RequestCookiesView.js';
41
43
  import {RequestHeadersView} from './RequestHeadersView.js';
@@ -130,6 +132,7 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
130
132
  private requestInternal: SDK.NetworkRequest.NetworkRequest;
131
133
  private readonly resourceViewTabSetting: Common.Settings.Setting<NetworkForward.UIRequestLocation.UIRequestTabs>;
132
134
  private readonly headersView: RequestHeadersView;
135
+ private readonly headersViewComponent: NetworkComponents.RequestHeadersView.RequestHeadersView;
133
136
  private payloadView: RequestPayloadView|null;
134
137
  private readonly responseView: RequestResponseView|undefined;
135
138
  private cookiesView: RequestCookiesView|null;
@@ -149,6 +152,12 @@ export class NetworkItemView extends UI.TabbedPane.TabbedPane {
149
152
  this.appendTab(
150
153
  NetworkForward.UIRequestLocation.UIRequestTabs.Headers, i18nString(UIStrings.headers), this.headersView,
151
154
  i18nString(UIStrings.headers));
155
+ this.headersViewComponent = new NetworkComponents.RequestHeadersView.RequestHeadersView(request);
156
+ if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES)) {
157
+ this.appendTab(
158
+ NetworkForward.UIRequestLocation.UIRequestTabs.HeadersComponent, i18nString(UIStrings.headers),
159
+ this.headersViewComponent, i18nString(UIStrings.headers));
160
+ }
152
161
 
153
162
  this.payloadView = null;
154
163
  void this.maybeAppendPayloadPanel();
@@ -36,6 +36,7 @@ import * as Common from '../../core/common/common.js';
36
36
  import * as Host from '../../core/host/host.js';
37
37
  import * as i18n from '../../core/i18n/i18n.js';
38
38
  import * as Platform from '../../core/platform/platform.js';
39
+ import * as Root from '../../core/root/root.js';
39
40
  import * as SDK from '../../core/sdk/sdk.js';
40
41
  import * as Protocol from '../../generated/protocol.js';
41
42
  import * as Bindings from '../../models/bindings/bindings.js';
@@ -1583,10 +1584,12 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
1583
1584
 
1584
1585
  contextMenu.saveSection().appendItem(i18nString(UIStrings.saveAllAsHarWithContent), this.exportAll.bind(this));
1585
1586
 
1586
- contextMenu.editSection().appendItem(
1587
- i18nString(UIStrings.createResponseHeaderOverride),
1588
- this.#handleCreateResponseHeaderOverrideClick.bind(this, request));
1589
- contextMenu.editSection().appendSeparator();
1587
+ if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES)) {
1588
+ contextMenu.editSection().appendItem(
1589
+ i18nString(UIStrings.createResponseHeaderOverride),
1590
+ this.#handleCreateResponseHeaderOverrideClick.bind(this, request));
1591
+ contextMenu.editSection().appendSeparator();
1592
+ }
1590
1593
  contextMenu.editSection().appendItem(i18nString(UIStrings.clearBrowserCache), this.clearBrowserCache.bind(this));
1591
1594
  contextMenu.editSection().appendItem(
1592
1595
  i18nString(UIStrings.clearBrowserCookies), this.clearBrowserCookies.bind(this));
@@ -451,7 +451,7 @@ export class RequestHeadersView extends UI.Widget.VBox {
451
451
  if (headersText) {
452
452
  const toggleButton = this.createHeadersToggleButton(this.showRequestHeadersText);
453
453
  toggleButton.addEventListener('click', this.toggleRequestHeadersText.bind(this), false);
454
- treeElement.listItemElement.appendChild(toggleButton);
454
+ treeElement.listItemElement.querySelector('.headers-title-left')?.appendChild(toggleButton);
455
455
  }
456
456
  }
457
457
 
@@ -388,13 +388,13 @@ export const _filterTypes: UI.FilterBar.Item[] = [
388
388
  ];
389
389
 
390
390
  export class ResourceWebSocketFrameNode extends DataGrid.SortableDataGrid.SortableDataGridNode<unknown> {
391
- private readonly url: string;
391
+ private readonly url: Platform.DevToolsPath.UrlString;
392
392
  readonly frame: SDK.NetworkRequest.WebSocketFrame;
393
393
  private readonly isTextFrame: boolean;
394
394
  private dataTextInternal: string;
395
395
  private binaryViewInternal: BinaryResourceView|null;
396
396
 
397
- constructor(url: string, frame: SDK.NetworkRequest.WebSocketFrame) {
397
+ constructor(url: Platform.DevToolsPath.UrlString, frame: SDK.NetworkRequest.WebSocketFrame) {
398
398
  let length = String(frame.text.length);
399
399
  const time = new Date(frame.time * 1000);
400
400
  const timeText = ('0' + time.getHours()).substr(-2) + ':' + ('0' + time.getMinutes()).substr(-2) + ':' +