chrome-devtools-frontend 1.0.1715126 → 1.0.1716465

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 (205) hide show
  1. package/eslint.config.mjs +1 -0
  2. package/front_end/core/host/Platform.ts +37 -0
  3. package/front_end/core/host/UserMetricsEnums.ts +5 -2
  4. package/front_end/core/platform/browser/HostRuntime.ts +3 -3
  5. package/front_end/core/sdk/CSSProperty.ts +2 -1
  6. package/front_end/core/sdk/DebuggerModel.ts +7 -1
  7. package/front_end/core/sdk/ResourceTreeModel.ts +9 -0
  8. package/front_end/core/sdk/RuntimeModel.ts +6 -3
  9. package/front_end/core/sdk/SDKSettings.ts +7 -0
  10. package/front_end/core/sdk/SourceMapFunctionRanges.ts +4 -1
  11. package/front_end/core/sdk/SourceMapScopesInfo.ts +8 -7
  12. package/front_end/devtools_compatibility.js +5 -2
  13. package/front_end/entrypoints/formatter_worker/CSSFormatter.ts +56 -6
  14. package/front_end/entrypoints/formatter_worker/HTMLFormatter.ts +29 -6
  15. package/front_end/entrypoints/main/MainImpl.ts +6 -14
  16. package/front_end/generated/Deprecation.ts +0 -7
  17. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  18. package/front_end/generated/protocol.ts +5 -2
  19. package/front_end/models/ai_assistance/AiAgent2.ts +0 -1
  20. package/front_end/models/ai_assistance/README.md +2 -2
  21. package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
  22. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +0 -2
  23. package/front_end/models/ai_assistance/skills/lighthouse.md +28 -10
  24. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +0 -3
  25. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +21 -11
  26. package/front_end/models/bindings/DefaultScriptMapping.ts +8 -2
  27. package/front_end/models/bindings/SourceMapStepping.ts +23 -3
  28. package/front_end/models/emulation/DeviceModeModel.ts +4 -19
  29. package/front_end/models/formatter/ScriptFormatter.ts +6 -7
  30. package/front_end/models/javascript_metadata/NativeFunctions.ts +0 -44
  31. package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +9 -12
  32. package/front_end/models/trace/LanternComputationData.ts +6 -14
  33. package/front_end/models/trace/extras/TraceTree.ts +44 -13
  34. package/front_end/models/trace/helpers/SamplesIntegrator.ts +70 -58
  35. package/front_end/models/trace/insights/Common.ts +3 -2
  36. package/front_end/models/trace/insights/RenderBlocking.ts +28 -6
  37. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +12 -20
  38. package/front_end/models/trace/lantern/simulation/Simulator.ts +5 -2
  39. package/front_end/models/trace/lantern/simulation/TCPConnection.ts +1 -1
  40. package/front_end/models/trace/types/Overlays.ts +4 -3
  41. package/front_end/models/workspace_diff/WorkspaceDiff.ts +5 -3
  42. package/front_end/panels/ai_assistance/components/ChatMessage.ts +1 -2
  43. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +0 -8
  44. package/front_end/panels/application/FrameDetailsView.ts +84 -0
  45. package/front_end/panels/application/WebMCPView.ts +3 -3
  46. package/front_end/panels/application/preloading/PreloadingView.ts +4 -1
  47. package/front_end/panels/application/preloading/components/RuleSetDetailsView.ts +5 -2
  48. package/front_end/panels/common/ExtensionServer.ts +84 -26
  49. package/front_end/panels/console/PromptBuilder.ts +5 -2
  50. package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +1 -118
  51. package/front_end/panels/elements/DOMPath.ts +38 -5
  52. package/front_end/panels/elements/DOMTreeContextMenu.ts +13 -8
  53. package/front_end/panels/elements/{ElementsTreeElement.ts → DOMTreeElementWidget.ts} +104 -469
  54. package/front_end/panels/elements/DOMTreeWidget.ts +74 -1253
  55. package/front_end/panels/elements/StylePropertiesSection.ts +3 -3
  56. package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -2
  57. package/front_end/panels/elements/StylesSidebarPane.ts +3 -1
  58. package/front_end/panels/elements/{elementsTreeOutline.css → domTreeWidget.css} +3 -178
  59. package/front_end/panels/elements/elements.ts +3 -6
  60. package/front_end/panels/emulation/DeviceModeToolbar.ts +0 -8
  61. package/front_end/panels/media/PlayerPropertiesView.ts +4 -4
  62. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +4 -4
  63. package/front_end/panels/recorder/RecorderPanel.ts +2 -1
  64. package/front_end/panels/security/SecurityPanel.ts +163 -100
  65. package/front_end/panels/sources/DebuggerPlugin.ts +125 -81
  66. package/front_end/panels/sources/SourcesPanel.ts +10 -4
  67. package/front_end/panels/sources/TabbedEditorContainer.ts +2 -1
  68. package/front_end/panels/sources/UISourceCodeFrame.ts +4 -2
  69. package/front_end/panels/sources/sources-meta.ts +20 -34
  70. package/front_end/panels/timeline/README.md +3 -1
  71. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
  72. package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
  73. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +14 -32
  74. package/front_end/panels/timeline/timelineFlameChartView.css +1 -42
  75. package/front_end/panels/whats_new/ReleaseNoteText.ts +8 -8
  76. package/front_end/panels/whats_new/resources/WNDT.md +5 -5
  77. package/front_end/third_party/chromium/README.chromium +1 -1
  78. package/front_end/third_party/puppeteer/README.chromium +2 -2
  79. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +77 -0
  80. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +474 -358
  81. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts +15 -0
  82. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts.map +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +27 -0
  84. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts +13 -0
  86. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.js +38 -0
  88. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +20 -0
  90. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.d.ts.map +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js +9 -2
  94. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserContext.js +6 -5
  96. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserContext.js.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js +2 -1
  99. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/ExposedFunction.js +2 -1
  101. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/ExposedFunction.js.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Frame.js +2 -1
  103. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Frame.js.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js +4 -3
  105. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +9 -8
  107. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
  108. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.js +9 -3
  110. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js +3 -2
  112. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/UserPrompt.js +3 -2
  114. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/UserPrompt.js.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.d.ts +2 -1
  116. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.d.ts.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.js +2 -2
  118. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.js.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +11 -2
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +9 -1
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +7 -2
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.d.ts.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.js +9 -2
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.js.map +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.d.ts +3 -1
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.d.ts.map +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.js +2 -2
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.js.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts +1 -0
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +9 -2
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +8 -0
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.d.ts +24 -1
  143. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.d.ts.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.js +30 -1
  145. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.js.map +1 -1
  146. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/CustomQueryHandler.js +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/CustomQueryHandler.js.map +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.d.ts.map +1 -1
  153. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js +5 -1
  154. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js.map +1 -1
  155. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  156. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +7 -2
  157. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
  158. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts +10 -0
  159. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts.map +1 -1
  160. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +7 -1
  161. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  163. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  164. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  165. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/types.d.ts +77 -0
  167. package/front_end/third_party/puppeteer/package/package.json +7 -7
  168. package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +30 -0
  169. package/front_end/third_party/puppeteer/package/src/api/HTTPResponse.ts +41 -0
  170. package/front_end/third_party/puppeteer/package/src/api/Page.ts +20 -0
  171. package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +6 -0
  172. package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +2 -1
  173. package/front_end/third_party/puppeteer/package/src/bidi/Realm.ts +1 -0
  174. package/front_end/third_party/puppeteer/package/src/bidi/util.ts +3 -0
  175. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +9 -2
  176. package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +10 -3
  177. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +11 -2
  178. package/front_end/third_party/puppeteer/package/src/cdp/WebWorker.ts +19 -2
  179. package/front_end/third_party/puppeteer/package/src/cdp/utils.ts +6 -1
  180. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +10 -2
  181. package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +9 -0
  182. package/front_end/third_party/puppeteer/package/src/common/ConsoleMessage.ts +35 -0
  183. package/front_end/third_party/puppeteer/package/src/common/CustomQueryHandler.ts +1 -1
  184. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  185. package/front_end/third_party/puppeteer/package/src/injected/util.ts +6 -2
  186. package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +7 -2
  187. package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +12 -1
  188. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  189. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  190. package/front_end/ui/components/text_editor/config.ts +6 -3
  191. package/front_end/ui/legacy/InspectorView.ts +13 -12
  192. package/front_end/ui/legacy/ProgressIndicator.ts +18 -0
  193. package/front_end/ui/legacy/SearchableView.ts +348 -269
  194. package/front_end/ui/legacy/TabbedPane.ts +19 -3
  195. package/front_end/ui/legacy/UIUtils.ts +1 -46
  196. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +4 -0
  197. package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +3 -3
  198. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +66 -30
  199. package/front_end/ui/legacy/components/source_frame/source_frame-meta.ts +3 -5
  200. package/front_end/ui/settings/SourcesSettings.ts +21 -0
  201. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  202. package/package.json +1 -1
  203. package/front_end/models/ai_assistance/skills/accessibility.md +0 -33
  204. package/front_end/panels/elements/ShortcutTreeElement.ts +0 -172
  205. package/front_end/panels/elements/TopLayerContainer.ts +0 -54
@@ -1,35 +1,53 @@
1
1
  ---
2
2
  name: lighthouse
3
- description: Running Lighthouse reports and audits when the user explicitly asks for Lighthouse, a Lighthouse score, or a multi-category audit (accessibility, best practices, Search Engine Optimization (SEO)). Not for general page performance measurement; use the performance skill for that.
3
+ description: Analyzing an active Lighthouse report context, running Lighthouse reports and audits (performance, accessibility, best practices, Search Engine Optimization (SEO)), accessibility audits, ARIA properties, accessible tree inspection, color contrast, and screen reader semantics. Not for general page performance measurement without a Lighthouse report; use the performance skill for that.
4
4
  allowed-tools:
5
5
  - runLighthouse
6
6
  - getLighthouseAudits
7
7
  - resolveDevtoolsNodePath
8
+ - getStyles
9
+ - getElementAccessibilityDetails
10
+ - executeJavaScript
8
11
  ---
9
- You are an expert web quality and audit assistant integrated into Chrome DevTools.
10
- Your role is to evaluate websites using Lighthouse audits across performance, accessibility, best practices, and SEO.
12
+ You are an expert web quality, Lighthouse audit, and accessibility debugging assistant integrated into Chrome DevTools.
13
+ Your role is to evaluate websites using Lighthouse audits across performance, accessibility, best practices, and SEO, and to inspect live DOM elements for accessibility and styling fixes.
11
14
 
12
15
  # Tools & Workflow
13
16
 
14
17
  1. **Lighthouse Audits (`runLighthouse` & `getLighthouseAudits`)**:
15
- - The Lighthouse report context contains only category scores and failing audit titles. To answer questions about failing audits or how to improve a score, you must first call `getLighthouseAudits` for the relevant category to fetch the full details. Never reply using only the initial summary.
18
+ - The Lighthouse report context contains only category scores and failing audit titles. To answer any question about a Lighthouse run, failing audits, or how to improve a score, you MUST call `getLighthouseAudits` for the relevant category to fetch the full audit details. Never reply using only the initial summary.
16
19
  - If an active Lighthouse report context already exists and no fresh audit is requested:
17
- - To inspect the entire report or multiple categories, call `getLighthouseAudits` with `categoryId: 'all'`.
20
+ - To inspect the entire report, multiple categories, or general opportunities to improve the score, call `getLighthouseAudits` with `categoryId: 'all'`.
18
21
  - For a specific category, call `getLighthouseAudits` with the corresponding category ID (e.g. `'performance'`, `'accessibility'`, `'best-practices'`, `'seo'`).
19
22
  - If no active report exists or a fresh audit is requested, call `runLighthouse`:
20
23
  - If the user asks for a general report or multiple categories, use `categoryId: 'all'`.
21
- - For a single category, pass that category ID.
24
+ - For a single category, pass that category ID (e.g. `'accessibility'`).
22
25
  - Execution mode:
23
26
  - Use `"navigation"` mode for full page-load audits (default for full site reviews).
24
27
  - Use `"snapshot"` mode to re-evaluate live in-page DOM/CSS modifications without reloading.
25
28
  - Use `"timespan"` mode for user interaction flows.
26
29
  - Always honor explicit mode requests from the user.
30
+ - **CRITICAL**: `runLighthouse` only records the report and returns `"Lighthouse audit completed"` without audit details. Immediately after `runLighthouse` completes, you MUST call `getLighthouseAudits` (with the matching `categoryId`) to retrieve the audit results before responding.
27
31
 
28
- 2. **Resolving Node References (`resolveDevtoolsNodePath`)**:
29
- - When an audit references failing elements by DevTools node path (e.g. `"1,HTML,1,BODY,2,BUTTON"`), use `resolveDevtoolsNodePath` to resolve the path to a `backendNodeId` to identify the failing element (or inspect it using tools from other skills if active).
32
+ 2. **Resolving & Inspecting Failing Audit Elements (`resolveDevtoolsNodePath`, `getStyles`, `getElementAccessibilityDetails`)**:
33
+ - `getLighthouseAudits` only returns static HTML snippets and DevTools `node path` strings (e.g. `"1,HTML,1,BODY,2,BUTTON"`), not live CSS rules, rendered dimensions, or accessibility tree state.
34
+ - Whenever failing audits reference specific page elements by `node path` (excluding document-level `"1,HTML"` landmark checks) and those elements have not yet been resolved and inspected in the conversation:
35
+ 1. Deduplicate `node path` strings first so an element referenced across multiple failing audits is only resolved once.
36
+ 2. You MUST call `resolveDevtoolsNodePath` for each unique failing element's `node path` to obtain its `backendNodeId`. Never guess `backendNodeId` numbers; only pass `backendNodeId` values provided by the active context or returned by `resolveDevtoolsNodePath`.
37
+ 3. You MUST then inspect those `backendNodeId`s using dedicated tools before answering:
38
+ - Call `getStyles` on the `backendNodeId` for sizing/layout audits (such as `unsized-images` to find the actual rendered CSS `width` and `height`), color contrast, or link styling (`link-in-text-block`).
39
+ - Call `getElementAccessibilityDetails` on the `backendNodeId` for accessibility, ARIA, role, or accessible name audits (such as `button-name`).
40
+ - Never guess CSS dimensions, styles, or ARIA properties from the static HTML snippet alone, and never use `executeJavaScript` (`document.querySelector`) as a substitute for `resolveDevtoolsNodePath`, `getStyles`, or `getElementAccessibilityDetails`.
41
+
42
+ 3. **Direct Element Accessibility Inspection (`getElementAccessibilityDetails` & `getStyles`)**:
43
+ - When inspecting a selected DOM element for accessibility, ALWAYS call `getElementAccessibilityDetails` on its `backendNodeId` to retrieve the computed role, accessible name, name source, ARIA attributes, ignored state, and accessibility properties directly from the accessibility tree.
44
+ - Call `getStyles` on the `backendNodeId` to inspect layout, color contrast, or font properties when relevant.
45
+
46
+ 4. **Supplementary DOM & Dynamic Interaction Checks (`executeJavaScript`)**:
47
+ - Only after calling `resolveDevtoolsNodePath`, `getStyles`, and `getElementAccessibilityDetails` on failing elements with a `node path`, you may use `executeJavaScript` if you need supplementary DOM state not available from single-node tools (such as `<head>` `<meta>` tags, `document.body.children` for `<main>` landmarks, parent element computed styles, or pseudo-element styles) or to test dynamic keyboard/focus interactions.
30
48
 
31
49
  # Considerations
32
50
 
33
- - Base all analysis on empirical Lighthouse audit data. Never fabricate audit scores or results.
34
- - For performance-only questions (e.g. loading speed, Core Web Vitals), do not run Lighthouse unless the user mentions Lighthouse or a Lighthouse score. Record a performance trace with the performance skill instead.
51
+ - Base all analysis on empirical Lighthouse audit data and live element inspection. Never fabricate audit scores or results.
52
+ - For performance-only questions (e.g. loading speed, Core Web Vitals) when no Lighthouse report is active, do not run Lighthouse unless the user mentions Lighthouse or a Lighthouse score. Record a performance trace with the performance skill instead.
35
53
  - When summarizing a full Lighthouse run, highlight overall category scores first, then detail failing audits (score < 90).
@@ -2,7 +2,6 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import * as Common from '../../../core/common/common.js';
6
5
  import * as Host from '../../../core/host/host.js';
7
6
  import * as i18n from '../../../core/i18n/i18n.js';
8
7
  import * as Root from '../../../core/root/root.js';
@@ -48,8 +47,6 @@ export class ExecuteJavaScriptTool implements
48
47
  static async validateAndFormatCode(code: string): Promise<{formattedCode?: string, error?: string}> {
49
48
  try {
50
49
  const formatted = await Formatter.ScriptFormatter.formatScriptContent(
51
- // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
52
- Common.Settings.Settings.instance(),
53
50
  'text/javascript',
54
51
  code,
55
52
  ' ',
@@ -2,7 +2,7 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import type * as Common from '../../core/common/common.js';
5
+ import * as Common from '../../core/common/common.js';
6
6
  import * as Platform from '../../core/platform/platform.js';
7
7
  import * as Root from '../../core/root/root.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
@@ -28,6 +28,13 @@ import {
28
28
  UnparsableError,
29
29
  } from './SymbolizedError.js';
30
30
 
31
+ export const wasmAutoSteppingSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
32
+ name: 'wasm-auto-stepping',
33
+ type: Common.Settings.SettingType.BOOLEAN,
34
+ defaultValue: true,
35
+ storageType: Common.Settings.SettingStorageType.LOCAL,
36
+ };
37
+
31
38
  export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObserver<SDK.DebuggerModel.DebuggerModel>,
32
39
  DebuggerLocationUpdater {
33
40
  readonly resourceMapping: ResourceMapping;
@@ -474,6 +481,10 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
474
481
  const scripts = new Set<SDK.Script.Script>();
475
482
  this.pluginManager.scriptsForUISourceCode(uiSourceCode).forEach(script => scripts.add(script));
476
483
  for (const modelData of this.#debuggerModelToData.values()) {
484
+ const defaultScript = modelData.defaultMapping.scriptForUISourceCode(uiSourceCode);
485
+ if (defaultScript) {
486
+ scripts.add(defaultScript);
487
+ }
477
488
  const resourceScriptFile = modelData.getResourceScriptMapping().scriptFile(uiSourceCode);
478
489
  if (resourceScriptFile?.script) {
479
490
  scripts.add(resourceScriptFile.script);
@@ -536,7 +547,7 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
536
547
  const {callFrames: [frame]} = debuggerPausedDetails;
537
548
  const functionLocation = frame.functionLocation();
538
549
  if (!autoSteppingContext || debuggerPausedDetails.reason !== Protocol.Debugger.PausedEventReason.Step ||
539
- !functionLocation || !this.#settings.moduleSetting('wasm-auto-stepping').get() ||
550
+ !functionLocation || !this.#settings.resolve(wasmAutoSteppingSettingDescriptor).get() ||
540
551
  !this.pluginManager.hasPluginForScript(frame.script)) {
541
552
  return true;
542
553
  }
@@ -581,7 +592,7 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
581
592
  class ModelData {
582
593
  readonly #debuggerModel: SDK.DebuggerModel.DebuggerModel;
583
594
  readonly #debuggerWorkspaceBinding: DebuggerWorkspaceBinding;
584
- #defaultMapping: DefaultScriptMapping;
595
+ readonly defaultMapping: DefaultScriptMapping;
585
596
  readonly #resourceMapping: ResourceMapping;
586
597
  #resourceScriptMapping: ResourceScriptMapping;
587
598
  readonly compilerMapping: CompilerScriptMapping;
@@ -592,7 +603,7 @@ class ModelData {
592
603
  this.#debuggerWorkspaceBinding = debuggerWorkspaceBinding;
593
604
 
594
605
  const {workspace} = debuggerWorkspaceBinding.resourceMapping;
595
- this.#defaultMapping = new DefaultScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
606
+ this.defaultMapping = new DefaultScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
596
607
  this.#resourceMapping = debuggerWorkspaceBinding.resourceMapping;
597
608
  this.#resourceScriptMapping = new ResourceScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
598
609
  this.compilerMapping = new CompilerScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
@@ -631,7 +642,7 @@ class ModelData {
631
642
  #nonCompilerRawLocationToUILocation(rawLocation: SDK.DebuggerModel.Location): Workspace.UISourceCode.UILocation|null {
632
643
  let uiLocation = this.#resourceScriptMapping.rawLocationToUILocation(rawLocation);
633
644
  uiLocation = uiLocation || this.#resourceMapping.jsLocationToUILocation(rawLocation);
634
- uiLocation = uiLocation || this.#defaultMapping.rawLocationToUILocation(rawLocation);
645
+ uiLocation = uiLocation || this.defaultMapping.rawLocationToUILocation(rawLocation);
635
646
  return uiLocation;
636
647
  }
637
648
 
@@ -639,7 +650,7 @@ class ModelData {
639
650
  let uiSourceCode: Workspace.UISourceCode.UISourceCode|null = null;
640
651
  uiSourceCode = uiSourceCode || this.#resourceScriptMapping.uiSourceCodeForScript(script);
641
652
  uiSourceCode = uiSourceCode || this.#resourceMapping.uiSourceCodeForScript(script);
642
- uiSourceCode = uiSourceCode || this.#defaultMapping.uiSourceCodeForScript(script);
653
+ uiSourceCode = uiSourceCode || this.defaultMapping.uiSourceCodeForScript(script);
643
654
  return uiSourceCode;
644
655
  }
645
656
 
@@ -654,9 +665,8 @@ class ModelData {
654
665
  locations = locations.length ?
655
666
  locations :
656
667
  this.#resourceMapping.uiLocationToJSLocations(uiSourceCode, lineNumber, columnNumber);
657
- locations = locations.length ?
658
- locations :
659
- this.#defaultMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
668
+ locations = locations.length ? locations :
669
+ this.defaultMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
660
670
  return locations;
661
671
  }
662
672
 
@@ -666,7 +676,7 @@ class ModelData {
666
676
  let ranges = this.compilerMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
667
677
  ranges ??= this.#resourceScriptMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
668
678
  ranges ??= this.#resourceMapping.uiLocationRangeToJSLocationRanges(uiSourceCode, textRange);
669
- ranges ??= this.#defaultMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
679
+ ranges ??= this.defaultMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
670
680
  return ranges;
671
681
  }
672
682
 
@@ -720,7 +730,7 @@ class ModelData {
720
730
  this.#debuggerModel.setBeforePausedCallback(null);
721
731
  this.compilerMapping.dispose();
722
732
  this.#resourceScriptMapping.dispose();
723
- this.#defaultMapping.dispose();
733
+ this.defaultMapping.dispose();
724
734
  }
725
735
 
726
736
  getResourceScriptMapping(): ResourceScriptMapping {
@@ -10,6 +10,7 @@ import * as Workspace from '../workspace/workspace.js';
10
10
 
11
11
  import {ContentProviderBasedProject} from './ContentProviderBasedProject.js';
12
12
  import type {DebuggerSourceMapping, DebuggerWorkspaceBinding} from './DebuggerWorkspaceBinding.js';
13
+ import {NetworkProject} from './NetworkProject.js';
13
14
 
14
15
  export class DefaultScriptMapping implements DebuggerSourceMapping {
15
16
  readonly #debuggerWorkspaceBinding: DebuggerWorkspaceBinding;
@@ -26,6 +27,7 @@ export class DefaultScriptMapping implements DebuggerSourceMapping {
26
27
  this.#project =
27
28
  new ContentProviderBasedProject(workspace, 'debugger:' + debuggerModel.target().id(),
28
29
  Workspace.Workspace.projectTypes.Debugger, '', true /* isServiceProject */);
30
+ NetworkProject.setTargetForProject(this.#project, debuggerModel.target());
29
31
  this.#eventListeners = [
30
32
  debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this.globalObjectCleared, this),
31
33
  debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this.parsedScriptSource, this),
@@ -44,14 +46,18 @@ export class DefaultScriptMapping implements DebuggerSourceMapping {
44
46
 
45
47
  static scriptForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Script.Script|null {
46
48
  for (const defaultScriptMapping of defaultScriptMappings) {
47
- const script = defaultScriptMapping.#uiSourceCodeToScript.get(uiSourceCode);
48
- if (script !== undefined) {
49
+ const script = defaultScriptMapping.scriptForUISourceCode(uiSourceCode);
50
+ if (script !== null) {
49
51
  return script;
50
52
  }
51
53
  }
52
54
  return null;
53
55
  }
54
56
 
57
+ scriptForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Script.Script|null {
58
+ return this.#uiSourceCodeToScript.get(uiSourceCode) ?? null;
59
+ }
60
+
55
61
  uiSourceCodeForScript(script: SDK.Script.Script): Workspace.UISourceCode.UISourceCode|null {
56
62
  return this.#scriptToUISourceCode.get(script) ?? null;
57
63
  }
@@ -104,6 +104,24 @@ export function inlinedFunctionRanges(frame: SDK.DebuggerModel.CallFrame): SDK.D
104
104
  return position && range ? toLocationRanges(position, [range]) : [];
105
105
  }
106
106
 
107
+ /**
108
+ * @returns true iff both frames are paused in the same call of an inlined function (or both aren't in any). Separate
109
+ * calls of the same function are inlined into separate generated ranges.
110
+ */
111
+ function isSameInlinedCall(a: SDK.DebuggerModel.CallFrame, b: SDK.DebuggerModel.CallFrame): boolean {
112
+ const range = (frame: SDK.DebuggerModel.CallFrame): SDK.SourceMapScopesInfo.PositionRange|null => {
113
+ const position = scopedPosition(frame);
114
+ return position?.sourceMap.inlinedFunctionRange(position.line, position.column) ?? null;
115
+ };
116
+ const rangeA = range(a);
117
+ const rangeB = range(b);
118
+ if (!rangeA || !rangeB) {
119
+ return rangeA === rangeB;
120
+ }
121
+ return a.script === b.script && SDK.SourceMapScopesInfo.comparePositions(rangeA.start, rangeB.start) === 0 &&
122
+ SDK.SourceMapScopesInfo.comparePositions(rangeA.end, rangeB.end) === 0;
123
+ }
124
+
107
125
  /** @returns the bodies of the functions inlined into the logical function that {@link frame} is paused in. */
108
126
  export function inlinedCalleeRanges(frame: SDK.DebuggerModel.CallFrame): SDK.DebuggerModel.LocationRange[] {
109
127
  const position = scopedPosition(frame);
@@ -157,9 +175,11 @@ export async function nextAutoStep(
157
175
  case SDK.DebuggerModel.StepMode.STEP_OVER: {
158
176
  const startDepth = logicalDepth(start);
159
177
  const depth = logicalDepth(frames);
160
- if (isUnmapped(frames[0]) || (depth === startDepth && isSameOriginalLocation(frames[0], start[0]))) {
161
- // Unmapped code, or still on the same original location (the skip list only covers the generated ranges that
162
- // contain the start position): keep stepping over.
178
+ if (isUnmapped(frames[0]) ||
179
+ (depth === startDepth && isSameOriginalLocation(frames[0], start[0]) &&
180
+ isSameInlinedCall(frames[0], start[0]))) {
181
+ // Unmapped code, or still on the same original location in the same (inlined) call (the skip list only covers
182
+ // the generated ranges that contain the start position): keep stepping over.
163
183
  return await computeAutoStep(SDK.DebuggerModel.StepMode.STEP_OVER, frames);
164
184
  }
165
185
  return null;
@@ -778,25 +778,10 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
778
778
  }
779
779
 
780
780
  private calculateFitScale(screenWidth: number, screenHeight: number): number {
781
- let scale = Math.min(screenWidth ? this.#preferredSize.width / screenWidth : 1,
782
- screenHeight ? this.#preferredSize.height / screenHeight : 1);
783
- scale = Math.max(Math.min(Math.floor(scale * 100), 100), 1);
784
-
785
- let sharpScale = scale;
786
- while (sharpScale > scale * 0.7) {
787
- let sharp = true;
788
- if (screenWidth) {
789
- sharp = sharp && Number.isInteger(screenWidth * sharpScale / 100);
790
- }
791
- if (screenHeight) {
792
- sharp = sharp && Number.isInteger(screenHeight * sharpScale / 100);
793
- }
794
- if (sharp) {
795
- return sharpScale / 100;
796
- }
797
- sharpScale -= 1;
798
- }
799
- return scale / 100;
781
+ const scaleW = screenWidth ? Math.floor(this.#preferredSize.width * 100 / screenWidth) : 100;
782
+ const scaleH = screenHeight ? Math.floor(this.#preferredSize.height * 100 / screenHeight) : 100;
783
+ const scale = Math.min(scaleW, scaleH, 100);
784
+ return Math.max(scale, 1) / 100;
800
785
  }
801
786
 
802
787
  setSizeAndScaleToFit(width: number, height: number): void {
@@ -30,25 +30,24 @@ export interface FormattedContent {
30
30
  formattedMapping: FormatterSourceMapping;
31
31
  }
32
32
 
33
- export async function format(settings: Common.Settings.Settings, contentType: Common.ResourceType.ResourceType,
34
- mimeType: string, content: string, indent?: string): Promise<FormattedContent> {
33
+ export async function format(contentType: Common.ResourceType.ResourceType, mimeType: string, content: string,
34
+ indent: string): Promise<FormattedContent> {
35
35
  if (contentType.isDocumentOrScriptOrStyleSheet()) {
36
- return await formatScriptContent(settings, mimeType, content, indent);
36
+ return await formatScriptContent(mimeType, content, indent);
37
37
  }
38
38
 
39
39
  return {formattedContent: content, formattedMapping: new IdentityFormatterSourceMapping()};
40
40
  }
41
41
 
42
- export async function formatScriptContent(settings: Common.Settings.Settings, mimeType: string, content: string,
43
- indent?: string): Promise<FormattedContent> {
44
- const indentString = indent ?? settings.moduleSetting('text-editor-indent').get();
42
+ export async function formatScriptContent(mimeType: string, content: string,
43
+ indent: string): Promise<FormattedContent> {
45
44
  const originalContent = content.replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '');
46
45
 
47
46
  const pool = formatterWorkerPool();
48
47
 
49
48
  let formatResult: FormatterActions.FormatResult = {content: originalContent, mapping: {original: [], formatted: []}};
50
49
  try {
51
- formatResult = await pool.format(mimeType, originalContent, indentString);
50
+ formatResult = await pool.format(mimeType, originalContent, indent);
52
51
  } catch {
53
52
  }
54
53
  const originalContentLineEndings = Platform.StringUtilities.findLineEndingIndexes(originalContent);
@@ -6735,10 +6735,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
6735
6735
  name: "setImmediates",
6736
6736
  signatures: [["rangeOffset","data","?dataOffset","?size"]]
6737
6737
  },
6738
- {
6739
- name: "copyElementImageToTexture",
6740
- signatures: [["source","destination"]]
6741
- },
6742
6738
  {
6743
6739
  name: "drawElementImageToTexture",
6744
6740
  signatures: [["source","destination"]]
@@ -6831,10 +6827,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
6831
6827
  name: "drawingBufferToneMapping",
6832
6828
  signatures: [["?toneMapping"]]
6833
6829
  },
6834
- {
6835
- name: "texElementImage2D",
6836
- signatures: [["target","internalformat","element","?config"]]
6837
- },
6838
6830
  {
6839
6831
  name: "texElementSubImage2D",
6840
6832
  signatures: [["target","level","xoffset","yoffset","element","?config"]]
@@ -7131,38 +7123,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
7131
7123
  name: "SmartCardError",
7132
7124
  signatures: [["message","options"]]
7133
7125
  },
7134
- {
7135
- name: "contributeToHistogram",
7136
- signatures: [["contribution"]]
7137
- },
7138
- {
7139
- name: "enableDebugMode",
7140
- signatures: [["?options"]]
7141
- },
7142
- {
7143
- name: "SharedStorageAppendMethod",
7144
- signatures: [["key","value","?options"]]
7145
- },
7146
- {
7147
- name: "SharedStorageClearMethod",
7148
- signatures: [["?options"]]
7149
- },
7150
- {
7151
- name: "SharedStorageDeleteMethod",
7152
- signatures: [["key","?options"]]
7153
- },
7154
- {
7155
- name: "SharedStorageSetMethod",
7156
- signatures: [["key","value","?options"]]
7157
- },
7158
- {
7159
- name: "selectURL",
7160
- signatures: [["name","urls","?options"]]
7161
- },
7162
- {
7163
- name: "run",
7164
- signatures: [["name","?options"]]
7165
- },
7166
7126
  {
7167
7127
  name: "BarcodeDetector",
7168
7128
  signatures: [["?barcodeDetectorOptions"]]
@@ -8739,10 +8699,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
8739
8699
  name: "setReportEventDataForAutomaticBeacons",
8740
8700
  signatures: [["event"]]
8741
8701
  },
8742
- {
8743
- name: "setSharedStorageContext",
8744
- signatures: [["contextString"]]
8745
- },
8746
8702
  {
8747
8703
  name: "CloseWatcher",
8748
8704
  signatures: [["?options"]]
@@ -2,7 +2,6 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import type * as Common from '../../core/common/common.js';
6
5
  import type * as Platform from '../../core/platform/platform.js';
7
6
  import * as SDK from '../../core/sdk/sdk.js';
8
7
  import * as TextUtils from '../../core/text_utils/text_utils.js';
@@ -42,9 +41,8 @@ interface InputData {
42
41
 
43
42
  const inputCache = new WeakMap<Workspace.UISourceCode.UISourceCode, Promise<InputData>>();
44
43
 
45
- async function prepareInput(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string,
46
- settings: Common.Settings.Settings): Promise<InputData> {
47
- const formattedContent = await format(uiSourceCode, content, settings);
44
+ async function prepareInput(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string): Promise<InputData> {
45
+ const formattedContent = await format(uiSourceCode, content);
48
46
  const text = new TextUtils.Text.Text(formattedContent ? formattedContent.formattedContent : content);
49
47
  let performanceData = uiSourceCode.getDecorationData(Workspace.UISourceCode.DecoratorType.PERFORMANCE) as
50
48
  Workspace.UISourceCode.LineColumnProfileMap |
@@ -61,14 +59,14 @@ async function prepareInput(uiSourceCode: Workspace.UISourceCode.UISourceCode, c
61
59
  }
62
60
 
63
61
  /** Formatting and parsing line endings for Text is expensive, so cache it. */
64
- async function prepareInputAndCache(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string,
65
- settings: Common.Settings.Settings): Promise<InputData> {
62
+ async function prepareInputAndCache(uiSourceCode: Workspace.UISourceCode.UISourceCode,
63
+ content: string): Promise<InputData> {
66
64
  let cachedPromise = inputCache.get(uiSourceCode);
67
65
  if (cachedPromise) {
68
66
  return await cachedPromise;
69
67
  }
70
68
 
71
- cachedPromise = prepareInput(uiSourceCode, content, settings);
69
+ cachedPromise = prepareInput(uiSourceCode, content);
72
70
  inputCache.set(uiSourceCode, cachedPromise);
73
71
  return await cachedPromise;
74
72
  }
@@ -248,8 +246,8 @@ export async function getFunctionCodeFromLocation(
248
246
  return await getFunctionCodeFromRawLocation(rawLocation, debuggerWorkspaceBinding, options);
249
247
  }
250
248
 
251
- async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string,
252
- settings: Common.Settings.Settings): Promise<Formatter.ScriptFormatter.FormattedContent|null> {
249
+ async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode,
250
+ content: string): Promise<Formatter.ScriptFormatter.FormattedContent|null> {
253
251
  const contentType = uiSourceCode.contentType();
254
252
  const shouldFormat = !contentType.isFromSourceMap() && (contentType.isDocument() || contentType.isScript()) &&
255
253
  TextUtils.TextUtils.isMinified(content);
@@ -257,7 +255,7 @@ async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode, content
257
255
  return null;
258
256
  }
259
257
 
260
- return await Formatter.ScriptFormatter.formatScriptContent(settings, contentType.canonicalMimeType(), content, '\t');
258
+ return await Formatter.ScriptFormatter.formatScriptContent(contentType.canonicalMimeType(), content, '\t');
261
259
  }
262
260
 
263
261
  /**
@@ -278,7 +276,6 @@ export async function getFunctionCodeFromRawLocation(
278
276
  return null;
279
277
  }
280
278
 
281
- const settings = rawLocation.debuggerModel.target().targetManager().settings;
282
- const inputData = await prepareInputAndCache(functionBounds.uiSourceCode, content, settings);
279
+ const inputData = await prepareInputAndCache(functionBounds.uiSourceCode, content);
283
280
  return createFunctionCode(inputData, functionBounds, options);
284
281
  }
@@ -157,17 +157,6 @@ function createLanternRequest(
157
157
  resourceType = 'Fetch';
158
158
  }
159
159
 
160
- // TODO: set decodedBodyLength for data urls in Trace Engine.
161
- let resourceSize = request.args.data.decodedBodyLength ?? 0;
162
- if (url.protocol === 'data:' && resourceSize === 0) {
163
- const commaIndex = url.pathname.indexOf(',');
164
- if (url.pathname.substring(0, commaIndex).includes(';base64')) {
165
- resourceSize = atob(url.pathname.substring(commaIndex + 1)).length;
166
- } else {
167
- resourceSize = url.pathname.length - commaIndex - 1;
168
- }
169
- }
170
-
171
160
  // NetworkRequestsHandler defaults missing `renderBlocking` to 'non_blocking',
172
161
  // so only populate `renderBlocking` when it was explicitly set on the raw
173
162
  // ResourceSendRequest event or updated via PreloadRenderBlockingStatusChange.
@@ -189,7 +178,7 @@ function createLanternRequest(
189
178
  responseHeadersEndTime: request.args.data.syntheticData.downloadStart / 1000,
190
179
  networkEndTime: request.args.data.syntheticData.finishTime / 1000,
191
180
  transferSize: request.args.data.encodedDataLength,
192
- resourceSize,
181
+ resourceSize: request.args.data.decodedBodyLength ?? 0,
193
182
  fromDiskCache: request.args.data.syntheticData.isDiskCached,
194
183
  fromMemoryCache: request.args.data.syntheticData.isMemoryCached,
195
184
  isLinkPreload: request.args.data.isLinkPreload,
@@ -321,8 +310,8 @@ function createNetworkRequests(trace: Lantern.Types.Trace, data: Handlers.Types.
321
310
 
322
311
  redirectedRequest.timing = {
323
312
  requestTime: redirectedRequest.networkRequestTime / 1000,
324
- receiveHeadersStart: redirectedRequest.responseHeadersEndTime,
325
- receiveHeadersEnd: redirectedRequest.responseHeadersEndTime,
313
+ receiveHeadersStart: redirectedRequest.responseHeadersEndTime - redirectedRequest.networkRequestTime,
314
+ receiveHeadersEnd: redirectedRequest.responseHeadersEndTime - redirectedRequest.networkRequestTime,
326
315
  proxyStart: -1,
327
316
  proxyEnd: -1,
328
317
  dnsStart: -1,
@@ -351,6 +340,9 @@ function createNetworkRequests(trace: Lantern.Types.Trace, data: Handlers.Types.
351
340
  requestChain.push(redirectedRequest);
352
341
  lanternRequests.push(redirectedRequest);
353
342
  }
343
+ if (requestChain.length) {
344
+ request.rendererStartTime = requestChain[requestChain.length - 1].networkEndTime;
345
+ }
354
346
  requestChain.push(request);
355
347
  lanternRequests.push(request);
356
348
 
@@ -408,23 +408,57 @@ export class BottomUpRootNode extends Node {
408
408
  const forceGroupIdCallback = this.forceGroupIdCallback;
409
409
 
410
410
  const idToIsCacheHit = new Map<string, boolean>();
411
+
412
+ // Node IDs are cached so that every event with the same ID reuses one
413
+ // string. Building a new ID string per event, and hashing it again on
414
+ // each Map lookup, is a large part of the cost of this loop on big
415
+ // traces.
416
+ const profileCallIdByCallFrame = new Map<Protocol.Runtime.CallFrame, string>();
417
+ // Grouped IDs are looked up by ID and then by group ID, because keying a
418
+ // flat Map by `${id}-${groupId}` would build a new string per event.
419
+ const groupedIdsByEventId = new Map<string, Map<string, string>>();
420
+ const nodeIdForEvent = (e: Types.Events.Event): string => {
421
+ let id: string;
422
+ if (Types.Events.isProfileCall(e)) {
423
+ // Profile calls for the same frame share one callFrame object, and
424
+ // their ID only depends on its fields.
425
+ const cachedId = profileCallIdByCallFrame.get(e.callFrame);
426
+ if (cachedId === undefined) {
427
+ id = generateEventID(e);
428
+ profileCallIdByCallFrame.set(e.callFrame, id);
429
+ } else {
430
+ id = cachedId;
431
+ }
432
+ } else {
433
+ id = generateEventID(e);
434
+ }
435
+ if (!forceGroupIdCallback || !eventGroupIdCallback) {
436
+ return id;
437
+ }
438
+ const groupId = eventGroupIdCallback(e);
439
+ let groupedIds = groupedIdsByEventId.get(id);
440
+ if (!groupedIds) {
441
+ groupedIds = new Map();
442
+ groupedIdsByEventId.set(id, groupedIds);
443
+ }
444
+ let groupedId = groupedIds.get(groupId);
445
+ if (groupedId === undefined) {
446
+ groupedId = `${id}-${groupId}`;
447
+ groupedIds.set(groupId, groupedId);
448
+ }
449
+ return groupedId;
450
+ };
451
+
411
452
  for (const e of this.events) {
412
453
  if (Types.Events.isReceivedDataEvent(e) && e.name === 'ResourceReceiveResponse') {
413
- let id = generateEventID(e);
414
- if (this.forceGroupIdCallback && this.eventGroupIdCallback) {
415
- id = `${id}-${this.eventGroupIdCallback(e)}`;
416
- }
417
- idToIsCacheHit.set(id, e.args.data.fromCache || false);
454
+ idToIsCacheHit.set(nodeIdForEvent(e), e.args.data.fromCache || false);
418
455
  }
419
456
  }
420
457
 
421
458
  // encodedDataLength is provided solely on instant events.
422
459
  const sumTransferSizeOfInstantEvent = (e: Types.Events.Event): void => {
423
460
  if (Types.Events.isReceivedDataEvent(e)) {
424
- let id = generateEventID(e);
425
- if (this.forceGroupIdCallback && this.eventGroupIdCallback) {
426
- id = `${id}-${this.eventGroupIdCallback(e)}`;
427
- }
461
+ const id = nodeIdForEvent(e);
428
462
  let node = nodeById.get(id);
429
463
  if (!node) {
430
464
  node = new BottomUpNode(root, id, e, false, root);
@@ -477,10 +511,7 @@ export class BottomUpRootNode extends Node {
477
511
  const duration = actualEndTime - Math.max(currentStartTime, startTime);
478
512
  selfTimeStack[selfTimeStack.length - 1] -= duration;
479
513
  selfTimeStack.push(duration);
480
- let id = generateEventID(e);
481
- if (forceGroupIdCallback && eventGroupIdCallback) {
482
- id = `${id}-${eventGroupIdCallback(e)}`;
483
- }
514
+ const id = nodeIdForEvent(e);
484
515
 
485
516
  idStack.push(id);
486
517