chrome-devtools-frontend 1.0.1636056 → 1.0.1640418

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 (171) hide show
  1. package/front_end/core/common/Color.ts +0 -4
  2. package/front_end/core/host/AidaClientTypes.ts +8 -6
  3. package/front_end/core/root/Runtime.ts +2 -2
  4. package/front_end/core/sdk/DOMStorageModel.ts +1 -1
  5. package/front_end/core/sdk/SourceMap.ts +8 -3
  6. package/front_end/core/sdk/TargetManager.ts +14 -1
  7. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +147 -0
  8. package/front_end/generated/ARIAProperties.js +17 -4
  9. package/front_end/generated/InspectorBackendCommands.ts +13 -7
  10. package/front_end/generated/SupportedCSSProperties.js +1 -0
  11. package/front_end/generated/protocol-mapping.d.ts +7 -0
  12. package/front_end/generated/protocol-proxy-api.d.ts +14 -0
  13. package/front_end/generated/protocol.ts +120 -2
  14. package/front_end/global_typings/global_defs.d.ts +13 -0
  15. package/front_end/models/ai_assistance/AiAgent2.ts +116 -0
  16. package/front_end/models/ai_assistance/AiConversation.ts +22 -36
  17. package/front_end/models/ai_assistance/AiHistoryStorage.ts +0 -1
  18. package/front_end/models/ai_assistance/AiOrigins.ts +46 -0
  19. package/front_end/models/ai_assistance/AiUtils.ts +9 -0
  20. package/front_end/models/ai_assistance/README.md +16 -0
  21. package/front_end/models/ai_assistance/StorageItem.ts +30 -26
  22. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +12 -5
  23. package/front_end/models/ai_assistance/agents/AiAgent.ts +86 -32
  24. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +2 -2
  25. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +31 -10
  26. package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +1 -1
  27. package/front_end/models/ai_assistance/agents/FileAgent.ts +2 -2
  28. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +1 -3
  29. package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +19 -0
  30. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +9 -4
  31. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +2 -2
  32. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +41 -12
  33. package/front_end/models/ai_assistance/agents/StorageAgent.ts +442 -122
  34. package/front_end/models/ai_assistance/agents/StylingAgent.ts +2 -2
  35. package/front_end/models/ai_assistance/ai_assistance.ts +4 -2
  36. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +2 -2
  37. package/front_end/models/ai_assistance/performance/AIContext.ts +7 -8
  38. package/front_end/models/ai_assistance/skills/README.md +40 -0
  39. package/front_end/models/ai_assistance/skills/Skill.ts +13 -0
  40. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +10 -0
  41. package/front_end/models/ai_assistance/skills/styling.md +6 -0
  42. package/front_end/models/bindings/CompilerScriptMapping.ts +12 -4
  43. package/front_end/models/breakpoints/BreakpointManager.ts +54 -2
  44. package/front_end/models/greendev/Prototypes.ts +0 -7
  45. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +20 -0
  46. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +5 -0
  47. package/front_end/models/issues_manager/EmailVerificationRequestIssue.ts +293 -0
  48. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  49. package/front_end/models/issues_manager/descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  50. package/front_end/models/issues_manager/descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  51. package/front_end/models/issues_manager/descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  52. package/front_end/models/issues_manager/descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  53. package/front_end/models/issues_manager/descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  54. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  55. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  56. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  57. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  58. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  59. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  60. package/front_end/models/issues_manager/descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  61. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  62. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  63. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  64. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  65. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  66. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  67. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  68. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  69. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  70. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  71. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  72. package/front_end/models/javascript_metadata/NativeFunctions.js +1748 -1739
  73. package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +1 -1
  74. package/front_end/models/stack_trace/DetailedErrorStackParser.ts +9 -1
  75. package/front_end/models/stack_trace/StackTraceImpl.ts +29 -9
  76. package/front_end/models/stack_trace/StackTraceModel.ts +23 -11
  77. package/front_end/models/stack_trace/Trie.ts +11 -1
  78. package/front_end/models/trace/extras/TraceTree.ts +20 -1
  79. package/front_end/models/trace/insights/Common.ts +9 -0
  80. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +21 -25
  81. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +19 -75
  82. package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +10 -3
  83. package/front_end/panels/ai_assistance/components/ChatMessage.ts +148 -2
  84. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +2 -3
  85. package/front_end/panels/ai_assistance/components/chatMessage.css +27 -0
  86. package/front_end/panels/application/CookieItemsView.ts +24 -0
  87. package/front_end/panels/application/DOMStorageItemsView.ts +9 -4
  88. package/front_end/panels/application/preloading/components/PreloadingString.ts +6 -0
  89. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +4 -4
  90. package/front_end/panels/console/ConsoleViewMessage.ts +13 -102
  91. package/front_end/panels/elements/StandaloneStylesContainer.ts +10 -0
  92. package/front_end/panels/elements/StylePropertiesSection.ts +6 -2
  93. package/front_end/panels/elements/StylePropertyTreeElement.ts +30 -1
  94. package/front_end/panels/elements/StylesContainer.ts +3 -0
  95. package/front_end/panels/elements/StylesSidebarPane.ts +54 -4
  96. package/front_end/panels/elements/elements-meta.ts +14 -0
  97. package/front_end/panels/layer_viewer/layerDetailsView.css +1 -1
  98. package/front_end/panels/lighthouse/LighthouseController.ts +1 -1
  99. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +4 -4
  100. package/front_end/panels/network/NetworkDataGridNode.ts +14 -0
  101. package/front_end/panels/network/NetworkLogViewColumns.ts +2 -2
  102. package/front_end/panels/network/RequestHeadersView.ts +55 -19
  103. package/front_end/panels/network/networkTimingTable.css +2 -4
  104. package/front_end/panels/recorder/components/ReplaySection.ts +28 -16
  105. package/front_end/panels/recorder/converters/LighthouseConverter.snapshot.txt +47 -0
  106. package/front_end/panels/recorder/converters/PuppeteerConverter.snapshot.txt +49 -0
  107. package/front_end/panels/recorder/converters/PuppeteerReplayConverter.snapshot.txt +33 -0
  108. package/front_end/panels/settings/SettingsScreen.ts +1 -2
  109. package/front_end/panels/sources/BreakpointsView.ts +23 -42
  110. package/front_end/panels/sources/DebuggerPlugin.ts +12 -5
  111. package/front_end/panels/sources/ScopeChainSidebarPane.ts +169 -106
  112. package/front_end/panels/timeline/components/IgnoreListSetting.ts +1 -0
  113. package/front_end/third_party/chromium/README.chromium +1 -1
  114. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +2 -2
  115. package/front_end/third_party/marked/README.chromium +3 -6
  116. package/front_end/third_party/marked/package/README.md +5 -5
  117. package/front_end/third_party/marked/package/bin/main.js +27 -22
  118. package/front_end/third_party/marked/package/bin/marked.js +2 -1
  119. package/front_end/third_party/marked/package/lib/marked.esm.d.ts +346 -256
  120. package/front_end/third_party/marked/package/lib/marked.esm.js +67 -2698
  121. package/front_end/third_party/marked/package/lib/marked.esm.js.map +7 -1
  122. package/front_end/third_party/marked/package/lib/marked.umd.js +69 -2722
  123. package/front_end/third_party/marked/package/lib/marked.umd.js.map +7 -1
  124. package/front_end/third_party/marked/package/man/marked.1 +4 -2
  125. package/front_end/third_party/marked/package/man/marked.1.md +2 -1
  126. package/front_end/third_party/marked/package/package.json +49 -57
  127. package/front_end/third_party/puppeteer-replay/README.chromium +2 -2
  128. package/front_end/third_party/puppeteer-replay/package/lib/cli.js +84 -80
  129. package/front_end/third_party/puppeteer-replay/package/lib/cli.js.map +1 -1
  130. package/front_end/third_party/puppeteer-replay/package/lib/extension-test.js +79 -83
  131. package/front_end/third_party/puppeteer-replay/package/lib/extension-test.js.map +1 -1
  132. package/front_end/third_party/puppeteer-replay/package/lib/main.d.ts +43 -171
  133. package/front_end/third_party/puppeteer-replay/package/lib/main.js +51 -206
  134. package/front_end/third_party/puppeteer-replay/package/lib/main.js.map +1 -1
  135. package/front_end/third_party/puppeteer-replay/package/package.json +37 -67
  136. package/front_end/tsconfig.json +1 -1
  137. package/front_end/ui/components/markdown_view/CodeBlock.ts +17 -6
  138. package/front_end/ui/components/markdown_view/MarkdownView.ts +39 -3
  139. package/front_end/ui/components/markdown_view/codeBlock.css +11 -0
  140. package/front_end/ui/components/markdown_view/markdownView.css +17 -0
  141. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +0 -79
  142. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +16 -4
  143. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
  144. package/inspector_overlay/testing/InspectorOverlayHelpers.ts +2 -0
  145. package/mcp/mcp.ts +1 -6
  146. package/package.json +14 -16
  147. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +0 -1015
  148. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgentOverlay.ts +0 -87
  149. package/front_end/third_party/marked/package/bin/marked +0 -215
  150. package/front_end/third_party/marked/package/lib/marked.cjs +0 -2726
  151. package/front_end/third_party/marked/package/lib/marked.cjs.map +0 -1
  152. package/front_end/third_party/marked/package/lib/marked.d.cts +0 -670
  153. package/front_end/third_party/marked/package/lib/marked.js +0 -2780
  154. package/front_end/third_party/marked/package/man/marked.1.txt +0 -86
  155. package/front_end/third_party/marked/package/marked.min.js +0 -6
  156. package/front_end/third_party/marked/package/src/Lexer.js +0 -492
  157. package/front_end/third_party/marked/package/src/Parser.js +0 -286
  158. package/front_end/third_party/marked/package/src/Renderer.js +0 -166
  159. package/front_end/third_party/marked/package/src/Slugger.js +0 -49
  160. package/front_end/third_party/marked/package/src/TextRenderer.js +0 -42
  161. package/front_end/third_party/marked/package/src/Tokenizer.js +0 -755
  162. package/front_end/third_party/marked/package/src/defaults.js +0 -29
  163. package/front_end/third_party/marked/package/src/helpers.js +0 -249
  164. package/front_end/third_party/marked/package/src/marked.js +0 -350
  165. package/front_end/third_party/marked/package/src/rules.js +0 -285
  166. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.cjs +0 -2099
  167. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.cjs.map +0 -1
  168. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.d.cts +0 -686
  169. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.d.ts +0 -35
  170. package/mcp/HostBindings.ts +0 -319
  171. /package/front_end/third_party/marked/package/{LICENSE.md → LICENSE} +0 -0
@@ -154,6 +154,8 @@ const lockedString = i18n.i18n.lockedString;
154
154
  const FILTER_IDLE_PERIOD = 500;
155
155
  // Minimum number of @property rules for the @property section block to be folded initially
156
156
  const MIN_FOLDED_SECTIONS_COUNT = 5;
157
+ // The number of properties required in a matched styles cascade to trigger IntersectionObserver lazy rendering.
158
+ const LAZY_RENDER_THRESHOLD = 200;
157
159
  /** Title of the registered properties section **/
158
160
  export const REGISTERED_PROPERTY_SECTION_NAME = '@property';
159
161
  /** Title of the function section **/
@@ -230,12 +232,18 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
230
232
  aiCodeCompletionProvider?: StylesAiCodeCompletionProvider.StylesAiCodeCompletionProvider;
231
233
  #aiCodeCompletionSummaryToolbarContainer?: HTMLElement;
232
234
  #aiCodeCompletionSummaryToolbar?: PanelsCommon.AiCodeCompletionSummaryToolbar.AiCodeCompletionSummaryToolbar;
235
+ #shouldRenderLazily = false;
236
+ #lazyRenderObserver?: IntersectionObserver;
237
+ #lazyRenderCallbacks = new WeakMap<Element, () => void>();
233
238
 
234
239
  constructor(computedStyleModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel) {
235
240
  super(computedStyleModel, {delegatesFocus: true, useShadowDom: true, classes: ['flex-none']});
236
241
  this.setMinimumSize(96, 26);
237
242
  this.registerRequiredCSS(stylesSidebarPaneStyles);
238
243
  Common.Settings.Settings.instance().moduleSetting('text-editor-indent').addChangeListener(this.requestUpdate, this);
244
+ Common.Settings.Settings.instance()
245
+ .moduleSetting('collapse-non-contributing-css-rules')
246
+ .addChangeListener(this.updateCollapsedSectionsSetting, this);
239
247
  this.toolbarPaneElement = this.createStylesSidebarToolbar();
240
248
  this.noMatchesElement = this.contentElement.createChild('div', 'gray-info-message hidden');
241
249
  this.noMatchesElement.textContent = i18nString(UIStrings.noMatchingSelectorOrStyle);
@@ -363,6 +371,12 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
363
371
  this.requestUpdate();
364
372
  }
365
373
 
374
+ private updateCollapsedSectionsSetting(): void {
375
+ for (const section of this.allSections()) {
376
+ section.updateCollapsedState();
377
+ }
378
+ }
379
+
366
380
  private sectionsContainerKeyDown(event: Event): void {
367
381
  const activeElement = UI.DOMUtilities.deepActiveElement(this.sectionsContainer.contentElement.ownerDocument);
368
382
  if (!activeElement) {
@@ -553,10 +567,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
553
567
  // Hide all popovers when scrolling.
554
568
  // Styles and Computed panels both have popover (e.g. imagePreviewPopover),
555
569
  // so we need to bind both scroll events.
556
- const scrollerElementLists =
557
- this?.contentElement?.enclosingNodeOrSelfWithClass('style-panes-wrapper')
558
- ?.parentElement?.querySelectorAll('.style-panes-wrapper') as unknown as NodeListOf<Element>;
559
- if (scrollerElementLists.length > 0) {
570
+ const scrollerElementLists = this?.contentElement?.enclosingNodeOrSelfWithClass('style-panes-wrapper')
571
+ ?.parentElement?.querySelectorAll('.style-panes-wrapper');
572
+ if (scrollerElementLists && scrollerElementLists.length > 0) {
560
573
  for (const element of scrollerElementLists) {
561
574
  this.scrollerElement = element;
562
575
  this.scrollerElement.addEventListener('scroll', this.boundOnScroll, false);
@@ -1109,6 +1122,14 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1109
1122
  const animationsPanelVisible = UI.ViewManager.ViewManager.instance().isViewVisible('animations');
1110
1123
  const cssAnimationsOnlyWhenAnimationsTabOpen =
1111
1124
  Common.Settings.Settings.instance().moduleSetting('css-animations-only-when-animations-tab-open').get();
1125
+
1126
+ let totalProperties = 0;
1127
+ for (const style of matchedStyles.nodeStyles()) {
1128
+ totalProperties += style.leadingProperties().length;
1129
+ }
1130
+ // Always render eagerly for layout tests.
1131
+ this.#shouldRenderLazily = !Host.InspectorFrontendHost.isUnderTest() && totalProperties > LAZY_RENDER_THRESHOLD;
1132
+
1112
1133
  for (const style of matchedStyles.nodeStyles()) {
1113
1134
  const isTransitionOrAnimationStyle = style.type === SDK.CSSStyleDeclaration.Type.Transition ||
1114
1135
  style.type === SDK.CSSStyleDeclaration.Type.Animation;
@@ -1610,6 +1631,35 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1610
1631
  #onAiCodeCompletionResponseReceived(): void {
1611
1632
  this.#aiCodeCompletionSummaryToolbar?.setLoading(false);
1612
1633
  }
1634
+
1635
+ trackForLazyRendering(element: Element, callback: () => void): void {
1636
+ if (!this.#lazyRenderObserver) {
1637
+ this.#lazyRenderObserver = new IntersectionObserver(entries => {
1638
+ for (const entry of entries) {
1639
+ if (entry.isIntersecting) {
1640
+ const cb = this.#lazyRenderCallbacks.get(entry.target);
1641
+ if (cb) {
1642
+ cb();
1643
+ this.untrackForLazyRendering(entry.target);
1644
+ }
1645
+ }
1646
+ }
1647
+ }, {rootMargin: '100px'});
1648
+ }
1649
+ this.#lazyRenderCallbacks.set(element, callback);
1650
+ this.#lazyRenderObserver.observe(element);
1651
+ }
1652
+
1653
+ shouldRenderLazily(): boolean {
1654
+ return this.#shouldRenderLazily;
1655
+ }
1656
+
1657
+ untrackForLazyRendering(element: Element): void {
1658
+ if (this.#lazyRenderObserver) {
1659
+ this.#lazyRenderObserver.unobserve(element);
1660
+ }
1661
+ this.#lazyRenderCallbacks.delete(element);
1662
+ }
1613
1663
  }
1614
1664
 
1615
1665
  export const enum Events {
@@ -156,6 +156,10 @@ const UIStrings = {
156
156
  * @description Title of a setting under the Elements category.
157
157
  */
158
158
  cssAnimationsOnlyWhenAnimationsTabOpen: 'Show animation styles only when the Animations tab is open',
159
+ /**
160
+ * @description Whether CSS rules that do not apply active styles in the Styles pane are collapsed by default.
161
+ */
162
+ collapseNonContributingCSSRules: 'Collapse non-contributing CSS rules',
159
163
  } as const;
160
164
  const str_ = i18n.i18n.registerUIStrings('panels/elements/elements-meta.ts', UIStrings);
161
165
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
@@ -558,6 +562,16 @@ Common.Settings.registerSettingExtension({
558
562
  defaultValue: true,
559
563
  });
560
564
 
565
+ Common.Settings.registerSettingExtension({
566
+ category: Common.Settings.SettingCategory.ELEMENTS,
567
+ storageType: Common.Settings.SettingStorageType.SYNCED,
568
+ order: 7,
569
+ title: i18nLazyString(UIStrings.collapseNonContributingCSSRules),
570
+ settingName: 'collapse-non-contributing-css-rules',
571
+ settingType: Common.Settings.SettingType.BOOLEAN,
572
+ defaultValue: false,
573
+ });
574
+
561
575
  Common.Settings.registerSettingExtension({
562
576
  settingName: 'show-event-listeners-for-ancestors',
563
577
  settingType: Common.Settings.SettingType.BOOLEAN,
@@ -36,7 +36,7 @@ ul {
36
36
  margin-block: 0;
37
37
  }
38
38
 
39
- .devtools-link.link-margin {
39
+ .devtools-link.link-margin, .devtools-link.link-margin:hover {
40
40
  margin: 8px;
41
41
  display: inline-block;
42
42
  }
@@ -310,7 +310,7 @@ class LighthouseRun {
310
310
  }
311
311
  }
312
312
 
313
- await this.protocolService.attach();
313
+ await this.protocolService.attach(this.inspectedURL);
314
314
  }
315
315
 
316
316
  private async restoreEmulationAndProtocolConnection(): Promise<void> {
@@ -86,7 +86,9 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
86
86
  */
87
87
  readonly #pendingRequests = new Map<number, (reason: Error) => void>();
88
88
 
89
- async attach(): Promise<void> {
89
+ async attach(inspectedURL: Platform.DevToolsPath.UrlString): Promise<void> {
90
+ const parsedInitialOrigin = Common.ParsedURL.ParsedURL.extractOrigin(inspectedURL);
91
+
90
92
  await SDK.TargetManager.TargetManager.instance().suspendAllTargets();
91
93
  const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
92
94
  if (!mainTarget) {
@@ -130,8 +132,6 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
130
132
  // To ensure the teardown operations can proceed, we need a dialog handler which lasts until
131
133
  // the LighthouseProtocolService detaches.
132
134
 
133
- const initialInspectedUrl = mainTarget.inspectedURL();
134
- const parsedInitialOrigin = Common.ParsedURL.ParsedURL.extractOrigin(initialInspectedUrl);
135
135
  const dialogHandler =
136
136
  (event: Common.EventTarget.EventTargetEvent<Protocol.Page.JavascriptDialogOpeningEvent>): void => {
137
137
  const parsedEventOrigin =
@@ -139,7 +139,7 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
139
139
  if (!parsedInitialOrigin || parsedEventOrigin !== parsedInitialOrigin) {
140
140
  // See http://crbug.com/513728809.
141
141
  console.warn(`Lighthouse auto-accept for dialog on ${
142
- event.data.url} blocked as it was not from the original audit origin ${initialInspectedUrl}.`);
142
+ event.data.url} blocked as it was not from the original audit origin ${inspectedURL}.`);
143
143
  return;
144
144
  }
145
145
 
@@ -932,6 +932,20 @@ export class NetworkRequestNode extends NetworkNode {
932
932
  return aValue > bValue ? 1 : -1;
933
933
  }
934
934
 
935
+ static OverrideTypesComparator(a: NetworkNode, b: NetworkNode): number {
936
+ const aRequest = a.requestOrFirstKnownChildRequest();
937
+ const bRequest = b.requestOrFirstKnownChildRequest();
938
+ if (!aRequest || !bRequest) {
939
+ if (!aRequest && !bRequest) {
940
+ return 0;
941
+ }
942
+ return !aRequest ? -1 : 1;
943
+ }
944
+ const aValue = aRequest.overrideTypes.join(', ');
945
+ const bValue = bRequest.overrideTypes.join(', ');
946
+ return aValue.localeCompare(bValue) || aRequest.identityCompare(bRequest);
947
+ }
948
+
935
949
  override showingInitiatorChainChanged(): void {
936
950
  const showInitiatorChain = this.showingInitiatorChain();
937
951
 
@@ -1129,9 +1129,9 @@ const DEFAULT_COLUMNS = [
1129
1129
  sortingFunction: NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'etag'),
1130
1130
  },
1131
1131
  {
1132
- id: 'response-header-has-overrides',
1132
+ id: 'has-overrides',
1133
1133
  title: i18nLazyString(UIStrings.hasOverrides),
1134
- sortingFunction: NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'has-overrides'),
1134
+ sortingFunction: NetworkRequestNode.OverrideTypesComparator,
1135
1135
  },
1136
1136
  {
1137
1137
  id: 'response-header-keep-alive',
@@ -106,8 +106,8 @@ interface ViewInput {
106
106
  toReveal?: {section: NetworkForward.UIRequestLocation.UIHeaderSection, header?: string};
107
107
  }
108
108
  type View = (input: ViewInput, output: object, target: HTMLElement) => void;
109
- export const DEFAULT_VIEW: View = (input, output, target) => {
110
- const requestHeadersText = input.request.requestHeadersText();
109
+
110
+ export function renderGeneralRows(input: ViewInput): Lit.LitTemplate {
111
111
  const statusClasses = ['status'];
112
112
  if (input.request.statusCode < 300 || input.request.statusCode === 304) {
113
113
  statusClasses.push('green-circle');
@@ -137,28 +137,42 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
137
137
  }
138
138
 
139
139
  const statusText = [input.request.statusCode, input.request.getInferredStatusText(), comment].join(' ');
140
+
141
+ // clang-format off
142
+ return html`<div jslog=${VisualLogging.section('general')}>
143
+ ${renderGeneralRow(input, i18nString(UIStrings.requestUrl), input.request.url(), 'request-url')}
144
+ ${input.request.statusCode ? renderGeneralRow(input, i18nString(UIStrings.requestMethod), input.request.requestMethod, 'request-method') :
145
+ Lit.nothing}
146
+ ${input.request.statusCode ? renderGeneralRow(input, i18nString(UIStrings.statusCode), statusText, 'status-code', statusClasses) :
147
+ Lit.nothing}
148
+ ${input.request.remoteAddress()? renderGeneralRow(input, i18nString(UIStrings.remoteAddress), input.request.remoteAddress(), 'remote-address') :
149
+ Lit.nothing}
150
+ ${input.request.referrerPolicy()? renderGeneralRow(input, i18nString(UIStrings.referrerPolicy), String(input.request.referrerPolicy()), 'referrer-policy') :
151
+ Lit.nothing}
152
+ </div>`;
153
+ // clang-format on
154
+ }
155
+
156
+ export function renderGeneralSection(input: ViewInput, forceOpen: boolean): Lit.LitTemplate {
157
+ // Rendered in a walkthrough widget where we only want rows without the ability to collapse the section.
158
+ return renderCategory({
159
+ name: 'general',
160
+ title: i18nString(UIStrings.general),
161
+ forceOpen,
162
+ loggingContext: 'general',
163
+ contents: renderGeneralRows(input),
164
+ });
165
+ }
166
+
167
+ export const DEFAULT_VIEW: View = (input, _output, target) => {
168
+ const requestHeadersText = input.request.requestHeadersText();
169
+
140
170
  // clang-format off
141
171
  render(
142
172
  html`
143
173
  <style>${NetworkComponents.RequestHeaderSection.requestHeadersViewStyles}</style>
144
174
  <style>${Input.checkboxStyles}</style>
145
- ${renderCategory({
146
- name: 'general',
147
- title: i18nString(UIStrings.general),
148
- forceOpen: input.toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.GENERAL,
149
- loggingContext: 'general',
150
- contents: html`<div jslog=${VisualLogging.section('general')}>
151
- ${renderGeneralRow(input, i18nString(UIStrings.requestUrl), input.request.url(), 'request-url')}
152
- ${input.request.statusCode? renderGeneralRow(input, i18nString(UIStrings.requestMethod),
153
- input.request.requestMethod, 'request-method') : Lit.nothing}
154
- ${input.request.statusCode? renderGeneralRow(input, i18nString(UIStrings.statusCode),
155
- statusText, 'status-code', statusClasses) : Lit.nothing}
156
- ${input.request.remoteAddress()? renderGeneralRow(input, i18nString(UIStrings.remoteAddress),
157
- input.request.remoteAddress(), 'remote-address') : Lit.nothing}
158
- ${input.request.referrerPolicy()? renderGeneralRow(input, i18nString(UIStrings.referrerPolicy),
159
- String(input.request.referrerPolicy()), 'referrer-policy') : Lit.nothing}
160
- </div>`
161
- })}
175
+ ${renderGeneralSection(input, input.toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.GENERAL)}
162
176
  ${!input.request?.earlyHintsHeaders || input.request.earlyHintsHeaders.length === 0
163
177
  ? Lit.nothing
164
178
  : renderCategory({
@@ -221,6 +235,22 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
221
235
  target, {container: {attributes: {jslog: `${VisualLogging.pane('headers').track({resize: true})}`}}});
222
236
  };
223
237
 
238
+ /**
239
+ * View used by the AI Assistance walkthrough's NetworkRequestGeneralHeaders widget
240
+ * to display only the General section of the network headers.
241
+ */
242
+ export const GENERAL_HEADERS_ONLY_VIEW: View = (input, _output, target) => {
243
+ // clang-format off
244
+ render(
245
+ html`
246
+ <style>${NetworkComponents.RequestHeaderSection.requestHeadersViewStyles}</style>
247
+ <style>${Input.checkboxStyles}</style>
248
+ ${renderGeneralRows(input)}
249
+ `,
250
+ target, {container: {attributes: {jslog: `${VisualLogging.pane('headers').track({resize: true})}`}}});
251
+ // clang-format on
252
+ };
253
+
224
254
  export class RequestHeadersView extends UI.Widget.Widget {
225
255
  #request?: SDK.NetworkRequest.NetworkRequest;
226
256
  #showResponseHeadersText = false;
@@ -243,6 +273,12 @@ export class RequestHeadersView extends UI.Widget.Widget {
243
273
  this.#view = view;
244
274
  }
245
275
 
276
+ static createGeneralHeadersView(request: SDK.NetworkRequest.NetworkRequest): RequestHeadersView {
277
+ const view = new RequestHeadersView(undefined, GENERAL_HEADERS_ONLY_VIEW);
278
+ view.request = request;
279
+ return view;
280
+ }
281
+
246
282
  #addEventListeners(): void {
247
283
  this.#request?.addEventListener(SDK.NetworkRequest.Events.REMOTE_ADDRESS_CHANGED, this.#refreshHeadersView, this);
248
284
  this.#request?.addEventListener(SDK.NetworkRequest.Events.FINISHED_LOADING, this.#refreshHeadersView, this);
@@ -79,7 +79,6 @@ table.network-timing-table > tr:not(.network-timing-table-header, .network-timin
79
79
  position: absolute;
80
80
  min-width: 1px;
81
81
  inset: 0 attr(data-right %) 0 attr(data-left %); /* stylelint-disable-line declaration-property-value-no-unknown */
82
- background-color: attr(data-background <color>); /* stylelint-disable-line declaration-property-value-no-unknown */
83
82
  }
84
83
 
85
84
  .network-timing-bar-title {
@@ -218,9 +217,8 @@ td.throttled {
218
217
  background: var(--sys-color-surface1);
219
218
  }
220
219
 
221
- .network-timing-bar.server-timing,
222
- .-theme-preserve {
223
- background-color: var(--sys-color-neutral-container);
220
+ .network-timing-bar.server-timing {
221
+ background-color: attr(data-background type(<color>), var(--sys-color-neutral-container)); /* stylelint-disable-line declaration-property-value-no-unknown */
224
222
  }
225
223
 
226
224
  tr.synthetic {
@@ -72,6 +72,11 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
72
72
 
73
73
  const REPLAY_EXTENSION_PREFIX = 'extension';
74
74
 
75
+ function isPlayRecordingSpeed(string: string): string is PlayRecordingSpeed {
76
+ return string === PlayRecordingSpeed.NORMAL || string === PlayRecordingSpeed.SLOW ||
77
+ string === PlayRecordingSpeed.VERY_SLOW || string === PlayRecordingSpeed.EXTREMELY_SLOW;
78
+ }
79
+
75
80
  interface Item {
76
81
  value: string;
77
82
  buttonIconName: string;
@@ -274,9 +279,9 @@ export class ReplaySection extends UI.Widget.Widget {
274
279
  if (this.#replayExtensions.length) {
275
280
  groups.push({
276
281
  name: i18nString(UIStrings.extensionGroup),
277
- items: this.#replayExtensions.map((extension, idx) => {
282
+ items: this.#replayExtensions.map(extension => {
278
283
  return {
279
- value: (REPLAY_EXTENSION_PREFIX + idx),
284
+ value: REPLAY_EXTENSION_PREFIX + extension.getOrigin(),
280
285
  buttonIconName: 'play',
281
286
  buttonLabel: () => extension.getName() as Platform.UIString.LocalizedString,
282
287
  label: () => extension.getName() as Platform.UIString.LocalizedString,
@@ -301,28 +306,35 @@ export class ReplaySection extends UI.Widget.Widget {
301
306
 
302
307
  #onStartReplay(): void {
303
308
  const value = this.#settings?.replayExtension || this.#settings?.speed || '';
304
- if (value?.startsWith(REPLAY_EXTENSION_PREFIX)) {
305
- const extensionIdx = Number(
306
- value.substring(REPLAY_EXTENSION_PREFIX.length),
307
- );
308
- const extension = this.#replayExtensions[extensionIdx];
309
- if (this.#settings) {
310
- this.#settings.replayExtension = REPLAY_EXTENSION_PREFIX + extensionIdx;
311
- }
312
- if (this.onStartReplay) {
313
- this.onStartReplay(PlayRecordingSpeed.NORMAL, extension);
309
+ if (value.startsWith(REPLAY_EXTENSION_PREFIX)) {
310
+ const origin = value.substring(REPLAY_EXTENSION_PREFIX.length);
311
+ const extension = this.#replayExtensions.find(ext => ext.getOrigin() === origin);
312
+ if (extension) {
313
+ if (this.#settings) {
314
+ this.#settings.replayExtension = REPLAY_EXTENSION_PREFIX + extension.getOrigin();
315
+ }
316
+ if (this.onStartReplay) {
317
+ this.onStartReplay(PlayRecordingSpeed.NORMAL, extension);
318
+ }
319
+ this.performUpdate();
320
+ return;
314
321
  }
315
- } else if (this.onStartReplay) {
322
+ }
323
+ if (this.onStartReplay) {
316
324
  this.onStartReplay(this.#settings ? this.#settings.speed : PlayRecordingSpeed.NORMAL);
317
325
  }
318
326
  this.performUpdate();
319
327
  }
320
328
 
321
329
  #onItemSelected(item: string): void {
322
- const speed = item as PlayRecordingSpeed;
323
- if (this.#settings && speed) {
324
- this.#settings.speed = speed;
330
+ if (!this.#settings) {
331
+ return;
332
+ }
333
+ if (isPlayRecordingSpeed(item)) {
334
+ this.#settings.speed = item;
325
335
  this.#settings.replayExtension = '';
336
+ } else {
337
+ this.#settings.replayExtension = item;
326
338
  }
327
339
  this.performUpdate();
328
340
  }
@@ -0,0 +1,47 @@
1
+ Title: LighthouseConverter should stringify a flow
2
+ Content:
3
+ import fs from 'fs';
4
+ import { Locator, launch } from 'puppeteer'; // v25.0.0 or later
5
+
6
+ const browser = await launch();
7
+ const page = await browser.newPage();
8
+ const timeout = 5000;
9
+ page.setDefaultTimeout(timeout);
10
+
11
+ const lhApi = await import('lighthouse'); // v10.0.0 or later
12
+ const flags = {
13
+ screenEmulation: {
14
+ disabled: true
15
+ }
16
+ }
17
+ const config = lhApi.desktopConfig;
18
+ const lhFlow = await lhApi.startFlow(page, {name: 'test', config, flags});
19
+ await lhFlow.startNavigation();
20
+ {
21
+ const targetPage = page;
22
+ await targetPage.goto('https://example.com');
23
+ }
24
+ await lhFlow.endNavigation();
25
+ await lhFlow.startTimespan();
26
+ {
27
+ const targetPage = page;
28
+ await Locator.race([
29
+ targetPage.locator('.cls')
30
+ ])
31
+ .setTimeout(timeout)
32
+ .scroll({ scrollTop: undefined, scrollLeft: undefined});
33
+ }
34
+ await lhFlow.endTimespan();
35
+ const lhFlowReport = await lhFlow.generateReport();
36
+ fs.writeFileSync(import.meta.dirname + '/flow.report.html', lhFlowReport)
37
+
38
+ await browser.close();
39
+ === end content
40
+
41
+ Title: LighthouseConverter should stringify a step
42
+ Content:
43
+ {
44
+ const targetPage = page;
45
+ await targetPage.evaluate((x, y) => { window.scroll(x, y); }, undefined, undefined)
46
+ }
47
+ === end content
@@ -0,0 +1,49 @@
1
+ Title: PuppeteerConverter should stringify a flow
2
+ Content:
3
+ import { Locator, launch } from 'puppeteer'; // v25.0.0 or later
4
+
5
+ const browser = await launch();
6
+ const page = await browser.newPage();
7
+ const timeout = 5000;
8
+ page.setDefaultTimeout(timeout);
9
+
10
+ {
11
+ const targetPage = page;
12
+ await Locator.race([
13
+ targetPage.locator('.cls')
14
+ ])
15
+ .setTimeout(timeout)
16
+ .scroll({ scrollTop: undefined, scrollLeft: undefined});
17
+ }
18
+
19
+ await browser.close();
20
+ === end content
21
+
22
+ Title: PuppeteerConverter should stringify a step
23
+ Content:
24
+ {
25
+ const targetPage = page;
26
+ await targetPage.evaluate((x, y) => { window.scroll(x, y); }, undefined, undefined)
27
+ }
28
+ === end content
29
+
30
+ Title: PuppeteerConverter should stringify a flow for Firefox
31
+ Content:
32
+ import { Locator, launch } from 'puppeteer'; // v25.0.0 or later
33
+
34
+ const browser = await launch({browser: 'firefox'});
35
+ const page = await browser.newPage();
36
+ const timeout = 5000;
37
+ page.setDefaultTimeout(timeout);
38
+
39
+ {
40
+ const targetPage = page;
41
+ await Locator.race([
42
+ targetPage.locator('.cls')
43
+ ])
44
+ .setTimeout(timeout)
45
+ .scroll({ scrollTop: undefined, scrollLeft: undefined});
46
+ }
47
+
48
+ await browser.close();
49
+ === end content
@@ -0,0 +1,33 @@
1
+ Title: PuppeteerReplayConverter should stringify a flow
2
+ Content:
3
+ import url from 'url';
4
+ import { createRunner } from '@puppeteer/replay';
5
+
6
+ export async function run(extension) {
7
+ const runner = await createRunner(extension);
8
+
9
+ await runner.runBeforeAllSteps();
10
+
11
+ await runner.runStep({
12
+ type: 'scroll',
13
+ selectors: [
14
+ [
15
+ '.cls'
16
+ ]
17
+ ]
18
+ });
19
+
20
+ await runner.runAfterAllSteps();
21
+ }
22
+
23
+ if (process && import.meta.url === url.pathToFileURL(process.argv[1]).href) {
24
+ run()
25
+ }
26
+ === end content
27
+
28
+ Title: PuppeteerReplayConverter should stringify a step
29
+ Content:
30
+ await runner.runStep({
31
+ type: 'scroll'
32
+ });
33
+ === end content
@@ -636,7 +636,7 @@ const GREENDEV_VIEW: View = (input, _output, target) => {
636
636
  <span>${i18nString(UIStrings.greenDevUnstable)}</span>
637
637
  </div>
638
638
  <div class="settings-experiments-block">
639
- ${renderPrototypeCheckboxes(input.settings, ['aiAnnotations', 'beyondStylingGemini', 'beyondStylingAntigravity', 'breakpointDebuggerAgent', 'emulationCapabilities'])}
639
+ ${renderPrototypeCheckboxes(input.settings, ['aiAnnotations', 'beyondStylingGemini', 'beyondStylingAntigravity', 'emulationCapabilities'])}
640
640
  </div>
641
641
  </devtools-card>
642
642
  </div>
@@ -648,7 +648,6 @@ const GREENDEV_PROTOTYPE_NAMES: Record<keyof GreenDev.GreenDevSettings, string>
648
648
  aiAnnotations: 'AI auto-annotations',
649
649
  beyondStylingGemini: 'Beyond Styling (Gemini CLI)',
650
650
  beyondStylingAntigravity: 'Beyond Styling (Antigravity CLI)',
651
- breakpointDebuggerAgent: 'Breakpoint Debugger Agent',
652
651
  emulationCapabilities: 'Emulation Capabilities',
653
652
  };
654
653