chrome-devtools-frontend 1.0.1669021 → 1.0.1672557

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 (302) hide show
  1. package/.agents/skills/fixing-skipped-tests/SKILL.md +6 -6
  2. package/.agents/skills/gerrit-cli/SKILL.md +4 -10
  3. package/.agents/skills/gerrit-cli/references/commands.md +45 -2
  4. package/.agents/skills/gerrit-cli/references/workflows.md +7 -0
  5. package/.agents/skills/gerrit-cli/scripts/import_upstream.py +34 -152
  6. package/config/typescript/tsconfig.eslint.json +1 -1
  7. package/docs/contributing/settings-experiments-features.md +2 -8
  8. package/docs/ecosystem/automatic_workspace_folders.md +0 -19
  9. package/eslint.config.mjs +5 -5
  10. package/front_end/core/common/Lazy.ts +3 -3
  11. package/front_end/core/common/SettingRegistration.ts +0 -7
  12. package/front_end/core/common/Settings.ts +0 -38
  13. package/front_end/core/host/UserMetrics.ts +187 -953
  14. package/front_end/core/host/UserMetricsEnums.ts +949 -0
  15. package/front_end/core/root/Runtime.ts +21 -138
  16. package/front_end/core/sdk/CSSMetadata.ts +70 -65
  17. package/front_end/core/sdk/CategorizedBreakpoint.ts +0 -1
  18. package/front_end/core/sdk/ChildTargetManager.ts +0 -2
  19. package/front_end/core/sdk/EmulationModel.ts +0 -2
  20. package/front_end/core/sdk/EventBreakpointsModel.ts +0 -4
  21. package/front_end/core/sdk/NetworkManager.ts +0 -3
  22. package/front_end/core/sdk/PageResourceLoader.ts +9 -9
  23. package/front_end/core/sdk/RehydratingConnection.ts +52 -4
  24. package/front_end/core/sdk/Target.ts +0 -4
  25. package/front_end/devtools_compatibility.js +886 -0
  26. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +7 -6
  27. package/front_end/entrypoints/main/ExecutionContextSelector.ts +0 -1
  28. package/front_end/entrypoints/main/MainImpl.ts +18 -22
  29. package/front_end/foundation/Universe.ts +7 -2
  30. package/front_end/generated/InspectorBackendCommands.ts +3 -10
  31. package/front_end/generated/{SupportedCSSProperties.js → SupportedCSSProperties.ts} +16 -0
  32. package/front_end/generated/protocol-mapping.d.ts +0 -42
  33. package/front_end/generated/protocol-proxy-api.d.ts +0 -38
  34. package/front_end/generated/protocol.ts +9 -169
  35. package/front_end/models/ai_assistance/AiAgent2.ts +11 -3
  36. package/front_end/models/ai_assistance/AiConversation.ts +1 -0
  37. package/front_end/models/ai_assistance/AiHistoryStorage.ts +8 -5
  38. package/front_end/models/ai_assistance/AiSetting.ts +108 -0
  39. package/front_end/models/ai_assistance/AiUtils.ts +47 -0
  40. package/front_end/models/ai_assistance/ChangeManager.ts +1 -0
  41. package/front_end/models/ai_assistance/ExtensionScope.ts +3 -12
  42. package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -18
  43. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +3 -0
  44. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +42 -17
  45. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +1 -1
  46. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -2
  47. package/front_end/models/ai_assistance/agents/StorageAgent.ts +253 -155
  48. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -2
  49. package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
  50. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +12 -6
  51. package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +3 -1
  52. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +1 -0
  53. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +4 -3
  54. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +1 -1
  55. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -0
  56. package/front_end/models/ai_assistance/injected.ts +1 -0
  57. package/front_end/models/ai_assistance/performance/AICallTree.ts +1 -0
  58. package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
  59. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +2 -0
  60. package/front_end/models/ai_assistance/skills/performance.md +10 -0
  61. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +52 -5
  62. package/front_end/models/ai_assistance/tools/GetElementAccessibilityDetails.ts +4 -4
  63. package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +4 -4
  64. package/front_end/models/ai_assistance/tools/GetNetworkRequestDetails.ts +5 -4
  65. package/front_end/models/ai_assistance/tools/GetStyles.ts +5 -4
  66. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +5 -4
  67. package/front_end/models/ai_assistance/tools/README.md +1 -1
  68. package/front_end/models/ai_assistance/tools/RecordPerformanceTrace.ts +63 -0
  69. package/front_end/models/ai_assistance/tools/ResolveDevtoolsNodePath.ts +5 -5
  70. package/front_end/models/ai_assistance/tools/Tool.ts +118 -24
  71. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +2 -0
  72. package/front_end/models/badges/UserBadges.ts +2 -0
  73. package/front_end/models/bindings/NetworkProject.ts +5 -0
  74. package/front_end/models/bindings/ResourceScriptMapping.ts +2 -0
  75. package/front_end/models/bindings/ResourceUtils.ts +3 -0
  76. package/front_end/models/crux-manager/CrUXManager.ts +1 -0
  77. package/front_end/models/emulation/DeviceModeModel.ts +140 -7
  78. package/front_end/models/emulation/EmulatedDevices.ts +246 -793
  79. package/front_end/models/issues_manager/IssuesManager.ts +10 -2
  80. package/front_end/models/live-metrics/LiveMetrics.ts +41 -9
  81. package/front_end/models/logs/LogManager.ts +8 -5
  82. package/front_end/models/logs/NetworkLog.ts +1 -0
  83. package/front_end/models/persistence/IsolatedFileSystemManager.ts +21 -3
  84. package/front_end/models/persistence/NetworkPersistenceManager.ts +6 -0
  85. package/front_end/models/project_settings/ProjectSettingsModel.ts +8 -12
  86. package/front_end/models/trace/Processor.ts +42 -10
  87. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +12 -19
  88. package/front_end/models/trace/handlers/MetaHandler.ts +38 -5
  89. package/front_end/models/trace/insights/CLSCulprits.ts +1 -2
  90. package/front_end/models/trace/insights/CharacterSet.ts +1 -1
  91. package/front_end/models/trace/insights/Common.ts +21 -2
  92. package/front_end/models/trace/insights/DocumentLatency.ts +1 -1
  93. package/front_end/models/trace/insights/LCPBreakdown.ts +7 -6
  94. package/front_end/models/trace/insights/LCPDiscovery.ts +1 -1
  95. package/front_end/models/trace/insights/ModernHTTP.ts +7 -3
  96. package/front_end/models/trace/insights/NetworkDependencyTree.ts +1 -1
  97. package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
  98. package/front_end/models/trace/insights/ThirdParties.ts +5 -2
  99. package/front_end/models/trace/insights/types.ts +11 -6
  100. package/front_end/models/trace/types/Configuration.ts +5 -0
  101. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +3 -1
  102. package/front_end/models/workspace/IgnoreListManager.ts +2 -0
  103. package/front_end/models/workspace/UISourceCode.ts +2 -0
  104. package/front_end/models/workspace_diff/WorkspaceDiff.ts +4 -0
  105. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +22 -22
  106. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +0 -7
  107. package/front_end/panels/ai_assistance/components/ChatInput.ts +4 -0
  108. package/front_end/panels/ai_assistance/components/ChatMessage.ts +79 -34
  109. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +1 -2
  110. package/front_end/panels/ai_assistance/components/walkthroughView.css +1 -1
  111. package/front_end/panels/application/ApplicationPanelSidebar.ts +9 -106
  112. package/front_end/panels/application/ApplicationPanelTreeElement.ts +1 -1
  113. package/front_end/panels/application/application.ts +0 -10
  114. package/front_end/panels/application/components/components.ts +0 -4
  115. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +0 -5
  116. package/front_end/panels/browser_debugger/EventListenerBreakpointsSidebarPane.ts +6 -12
  117. package/front_end/panels/browser_debugger/browser_debugger-meta.ts +5 -3
  118. package/front_end/panels/console/ConsoleFormat.ts +2 -62
  119. package/front_end/panels/console/ConsoleViewMessage.ts +14 -7
  120. package/front_end/panels/elements/ElementsTreeElement.ts +1 -2
  121. package/front_end/panels/emulation/AdvancedApp.ts +1 -2
  122. package/front_end/panels/emulation/DeviceModeToolbar.ts +83 -69
  123. package/front_end/panels/emulation/DeviceModeView.ts +4 -134
  124. package/front_end/panels/emulation/DeviceModeWrapper.ts +52 -69
  125. package/front_end/panels/emulation/MediaQueryInspector.ts +2 -2
  126. package/front_end/panels/emulation/emulation-meta.ts +12 -12
  127. package/front_end/panels/issues/IssuesPane.ts +3 -1
  128. package/front_end/panels/lighthouse/LighthouseController.ts +6 -0
  129. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +17 -21
  130. package/front_end/panels/linear_memory_inspector/components/LinearMemoryNavigator.ts +206 -126
  131. package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +1 -1
  132. package/front_end/panels/mobile_throttling/CalibrationController.ts +1 -1
  133. package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +3 -3
  134. package/front_end/panels/mobile_throttling/NetworkPanelIndicator.ts +6 -6
  135. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -12
  136. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +13 -13
  137. package/front_end/panels/mobile_throttling/ThrottlingPresets.ts +10 -10
  138. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +28 -28
  139. package/front_end/panels/mobile_throttling/mobile_throttling-meta.ts +6 -6
  140. package/front_end/panels/network/RequestHeadersView.ts +1 -1
  141. package/front_end/panels/network/ResourceChunkView.ts +243 -144
  142. package/front_end/panels/network/ResourceDirectSocketChunkView.ts +52 -29
  143. package/front_end/panels/network/ResourceWebSocketFrameView.ts +21 -35
  144. package/front_end/panels/network/resourceChunkView.css +41 -36
  145. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +21 -12
  146. package/front_end/panels/profiler/profiler.ts +4 -0
  147. package/front_end/panels/recorder/RecorderPanel.ts +6 -14
  148. package/front_end/panels/sensors/LocationsSettingsTab.ts +7 -7
  149. package/front_end/panels/settings/AISettingsTab.ts +75 -31
  150. package/front_end/panels/settings/SettingsScreen.ts +8 -13
  151. package/front_end/panels/settings/components/SyncSection.ts +3 -4
  152. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +650 -18
  153. package/front_end/panels/settings/emulation/devicesSettingsTab.css +18 -0
  154. package/front_end/panels/settings/settings-meta.ts +0 -1
  155. package/front_end/panels/sources/CategorizedBreakpointL10n.ts +0 -2
  156. package/front_end/panels/sources/DebuggerPausedMessage.ts +11 -5
  157. package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
  158. package/front_end/panels/sources/EditingLocationHistoryManager.ts +12 -9
  159. package/front_end/panels/sources/SourcesPanel.ts +19 -17
  160. package/front_end/panels/sources/SourcesView.ts +191 -96
  161. package/front_end/panels/sources/TabbedEditorContainer.ts +3 -4
  162. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +2 -5
  163. package/front_end/panels/timeline/TimelinePanel.ts +2 -0
  164. package/front_end/panels/timeline/TimelineUIUtils.ts +15 -0
  165. package/front_end/panels/timeline/components/CWVMetrics.ts +16 -3
  166. package/front_end/panels/timeline/components/cwvMetrics.css +4 -0
  167. package/front_end/panels/timeline/components/liveMetricsView.css +0 -17
  168. package/front_end/panels/timeline/components/metricValueStyles.css +17 -0
  169. package/front_end/panels/timeline/timeline-meta.ts +3 -5
  170. package/front_end/third_party/chromium/README.chromium +1 -1
  171. package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
  172. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  173. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  174. package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
  175. package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
  176. package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
  177. package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
  178. package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
  179. package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
  180. package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
  181. package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
  182. package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
  183. package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
  184. package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
  185. package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
  186. package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
  187. package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
  188. package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
  189. package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
  190. package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
  191. package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
  192. package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
  193. package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
  194. package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
  195. package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
  196. package/front_end/third_party/codemirror.next/codemirror.next.d.ts +1332 -193
  197. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  198. package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
  199. package/front_end/third_party/puppeteer/README.chromium +2 -2
  200. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +64 -15
  201. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +65 -16
  202. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +50 -7
  203. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  204. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  205. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts +2 -1
  206. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts.map +1 -1
  207. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js +5 -5
  208. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js.map +1 -1
  209. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts +2 -1
  210. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts.map +1 -1
  211. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js +8 -6
  212. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js.map +1 -1
  213. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.d.ts.map +1 -1
  214. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.js +3 -0
  215. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.js.map +1 -1
  216. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  217. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +16 -1
  218. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  219. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.d.ts +5 -1
  220. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.d.ts.map +1 -1
  221. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js +11 -6
  222. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js.map +1 -1
  223. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.d.ts.map +1 -1
  224. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.js +5 -0
  225. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.js.map +1 -1
  226. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  227. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +10 -0
  228. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
  229. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +4 -3
  230. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
  231. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts +27 -2
  232. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts.map +1 -1
  233. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js +12 -1
  234. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js.map +1 -1
  235. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +2 -2
  236. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
  237. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +2 -2
  238. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
  239. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  240. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js +2 -0
  241. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js.map +1 -1
  242. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts +2 -1
  243. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts.map +1 -1
  244. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js +5 -4
  245. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js.map +1 -1
  246. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  247. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  248. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  249. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  250. package/front_end/third_party/puppeteer/package/lib/types.d.ts +64 -15
  251. package/front_end/third_party/puppeteer/package/package.json +2 -2
  252. package/front_end/third_party/puppeteer/package/src/api/Page.ts +50 -7
  253. package/front_end/third_party/puppeteer/package/src/bidi/BidiOverCdp.ts +9 -7
  254. package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +9 -6
  255. package/front_end/third_party/puppeteer/package/src/bidi/Dialog.ts +4 -0
  256. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +24 -1
  257. package/front_end/third_party/puppeteer/package/src/cdp/Connection.ts +11 -6
  258. package/front_end/third_party/puppeteer/package/src/cdp/Dialog.ts +7 -0
  259. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +11 -0
  260. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +7 -3
  261. package/front_end/third_party/puppeteer/package/src/common/Debug.ts +30 -5
  262. package/front_end/third_party/puppeteer/package/src/common/util.ts +2 -2
  263. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +2 -0
  264. package/front_end/third_party/puppeteer/package/src/node/ScreenRecorder.ts +6 -4
  265. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  266. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  267. package/front_end/tsconfig.compatibility.json +2 -1
  268. package/front_end/tsconfig.json +1 -1
  269. package/front_end/ui/components/icon_button/IconButton.ts +1 -1
  270. package/front_end/ui/components/issue_counter/IssueCounter.ts +1 -1
  271. package/front_end/ui/components/settings/SettingCheckbox.ts +4 -7
  272. package/front_end/ui/components/settings/settings.ts +1 -2
  273. package/front_end/ui/legacy/Treeoutline.ts +52 -30
  274. package/front_end/ui/legacy/components/object_ui/CSSStyleSanitizer.ts +74 -0
  275. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +6 -1
  276. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +47 -54
  277. package/front_end/ui/legacy/components/object_ui/object_ui.ts +2 -0
  278. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +5 -27
  279. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +10 -12
  280. package/front_end/ui/settings/SettingUIRegistration.ts +0 -8
  281. package/front_end/ui/visual_logging/KnownContextValues.ts +37 -0
  282. package/inspector_overlay/tsconfig.json +8 -2
  283. package/package.json +3 -2
  284. package/.agents/skills/gerrit-cli/scripts/gerrit_client_wrapper.py +0 -47
  285. package/front_end/core/sdk/CSSModel.test.api.ts +0 -102
  286. package/front_end/core/sdk/DOMModel.test.api.ts +0 -104
  287. package/front_end/foundation/Universe.test.api.ts +0 -73
  288. package/front_end/panels/application/SharedStorageEventsView.ts +0 -128
  289. package/front_end/panels/application/SharedStorageItemsView.ts +0 -179
  290. package/front_end/panels/application/SharedStorageListTreeElement.ts +0 -65
  291. package/front_end/panels/application/SharedStorageModel.ts +0 -249
  292. package/front_end/panels/application/SharedStorageTreeElement.ts +0 -40
  293. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +0 -191
  294. package/front_end/panels/application/components/SharedStorageMetadataView.ts +0 -133
  295. package/front_end/panels/application/components/sharedStorageAccessGrid.css +0 -29
  296. package/front_end/panels/application/components/sharedStorageMetadataView.css +0 -29
  297. package/front_end/panels/application/sharedStorageEventsView.css +0 -9
  298. package/front_end/panels/network/OriginalResourceChunkView.ts +0 -340
  299. package/front_end/panels/network/originalResourceChunkView.css +0 -49
  300. package/front_end/ui/components/settings/SettingDeprecationWarning.ts +0 -47
  301. package/front_end/ui/components/settings/settingDeprecationWarning.css +0 -14
  302. /package/front_end/generated/{ARIAProperties.js → ARIAProperties.ts} +0 -0
@@ -5,10 +5,58 @@
5
5
  import type * as Host from '../../../core/host/host.js';
6
6
  import type * as SDK from '../../../core/sdk/sdk.js';
7
7
  import type * as LHModel from '../../lighthouse/lighthouse.js';
8
- import type {ConversationContext, FunctionCallHandlerResult, FunctionHandlerOptions} from '../agents/AiAgent.js';
8
+ import type * as Trace from '../../trace/trace.js';
9
+ import type {AiWidget, ConversationContext, FunctionHandlerOptions} from '../agents/AiAgent.js';
9
10
  import type {executeJsCode} from '../agents/ExecuteJavascript.js';
10
11
  import type {ChangeManager} from '../ChangeManager.js';
11
12
 
13
+ /**
14
+ * Result indicating an error occurred during tool execution.
15
+ */
16
+ export interface ToolErrorResult {
17
+ error: string;
18
+ }
19
+
20
+ /**
21
+ * Result indicating user approval is required before running the tool.
22
+ */
23
+ export interface ToolApprovalResult {
24
+ requiresApproval: true;
25
+ description: string|null;
26
+ }
27
+
28
+ /**
29
+ * Result produced by a DataTool (`DataTool`). Contains a structured data payload (`result`)
30
+ * returned to answer the AI query without altering the conversation's active focus target.
31
+ * May optionally include UI widgets to render in the panel.
32
+ */
33
+ export interface ToolDataResult<DataType> {
34
+ result: DataType;
35
+ widgets?: AiWidget[];
36
+ }
37
+
38
+ /**
39
+ * Result produced by a ContextTool (`ContextTool`). Switches or introduces a new active focal entity
40
+ * (`context`) into the conversation session (e.g., attaching a performance trace or selecting a DOM node)
41
+ * along with a human-readable `description` explaining the context switch and optional UI widgets.
42
+ */
43
+ export interface ToolContextResult<ContextType = unknown> {
44
+ context: ConversationContext<ContextType>;
45
+ description: string;
46
+ widgets?: AiWidget[];
47
+ }
48
+
49
+ /**
50
+ * Union for tools that produce data output (`DataTool`).
51
+ */
52
+ export type DataHandlerResult<DataType> = ToolDataResult<DataType>|ToolApprovalResult|ToolErrorResult;
53
+
54
+ /**
55
+ * Union for tools that switch or return conversation context (`ContextTool`).
56
+ */
57
+ export type ContextHandlerResult<ContextType = unknown> =
58
+ ToolContextResult<ContextType>|ToolApprovalResult|ToolErrorResult;
59
+
12
60
  /**
13
61
  * Base capability for all tool contexts, providing access to the conversation context.
14
62
  */
@@ -80,12 +128,19 @@ export interface LighthouseCapability {
80
128
  lighthouseRecording?: (overrides?: LHModel.RunTypes.RunOverrides) => Promise<LHModel.ReporterTypes.ReportJSON|null>;
81
129
  }
82
130
 
131
+ /**
132
+ * Capability for tools that need to record performance traces.
133
+ */
134
+ export interface PerformanceRecordingCapability {
135
+ performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>;
136
+ }
137
+
83
138
  /**
84
139
  * Unified context interface providing all capabilities available in the project.
85
140
  * Used by the agent to pass a complete context to any tool type-safely.
86
141
  */
87
142
  export type AllToolsCapabilities = BaseToolCapability&PageExecutionCapability&StyleMutationCapability&TargetCapability&
88
- OriginLockCapability&LighthouseCapability;
143
+ OriginLockCapability&LighthouseCapability&PerformanceRecordingCapability;
89
144
 
90
145
  /**
91
146
  * Base argument type for AI Tools.
@@ -100,51 +155,90 @@ export const enum ToolName {
100
155
  GET_LIGHTHOUSE_AUDITS = 'getLighthouseAudits',
101
156
  RESOLVE_DEVTOOLS_NODE_PATH = 'resolveDevtoolsNodePath',
102
157
  GET_ELEMENT_ACCESSIBILITY_DETAILS = 'getElementAccessibilityDetails',
158
+ RECORD_PERFORMANCE_TRACE = 'recordPerformanceTrace',
103
159
  }
104
160
 
105
161
  /**
106
- * Non-generic metadata interface for a Tool.
107
- * Used for storing and retrieving tools generically without type-erasure concerns.
162
+ * Base metadata interface for a Tool.
163
+ * Provides parameter schema and display info formatting for tool argument types.
164
+ *
165
+ * @template ArgsType The expected object schema for tool arguments. Defaults to `ToolArgs`.
108
166
  */
109
- export interface BaseTool {
167
+ export interface BaseTool<ArgsType extends ToolArgs = ToolArgs> {
110
168
  readonly name: ToolName;
111
169
  readonly description: string;
112
170
  /**
113
171
  * JSON schema representing the parameters this tool accepts.
114
172
  */
115
- readonly parameters: Host.AidaClient.FunctionObjectParam<string|number|symbol>;
116
- }
117
-
118
- /**
119
- * Main generic interface for defining a Tool.
120
- * Binds the parameter schema properties and the handler implementation to a strict `Args` and `ContextType` contract.
121
- *
122
- * @template Args - The expected object type for tool arguments. Must be an object type.
123
- * @template ReturnType - The type of data returned by the handler function.
124
- * @template ContextType - The interface defining the capabilities this tool requires. Defaults to `BaseToolCapability`.
125
- */
126
- export interface Tool<Args extends ToolArgs = ToolArgs, ReturnType = unknown,
127
- ContextType extends BaseToolCapability = BaseToolCapability> extends BaseTool {
128
- readonly parameters: Host.AidaClient.FunctionObjectParam<keyof Args>;
173
+ readonly parameters: Host.AidaClient.FunctionObjectParam<keyof ArgsType>;
129
174
  /**
130
175
  * Converts the tool arguments into user-friendly display information.
131
176
  * This is used by the UI to show what the agent is doing (e.g., in the history/steps log).
132
177
  */
133
178
  readonly displayInfoFromArgs?: (
134
- args: Args,
179
+ args: ArgsType,
135
180
  ) => {
136
181
  title?: string, thought?: string, action?: string, suggestions?: [string, ...string[]],
137
182
  };
183
+ }
184
+
185
+ /**
186
+ * Generic tool interface for tools that process inputs and return structured data results.
187
+ *
188
+ * @template ArgsType The expected object schema for tool arguments.
189
+ * @template ReturnType The concrete type of data payload returned in the result.
190
+ * @template CapabilitiesType The capabilities interface required by this tool. Defaults to `BaseToolCapability`.
191
+ */
192
+ export interface DataTool<
193
+ ArgsType extends ToolArgs = ToolArgs,
194
+ ReturnType = unknown,
195
+ CapabilitiesType extends BaseToolCapability = BaseToolCapability,
196
+ > extends BaseTool<ArgsType> {
197
+ /**
198
+ * The implementation function called when the AI invokes this tool.
199
+ *
200
+ * @param args The arguments provided by the AI model matching the tool's parameter schema.
201
+ * @param capabilities The context object providing the capabilities requested by `CapabilitiesType`.
202
+ * @param options Additional runtime options for the handler execution.
203
+ */
204
+ handler(
205
+ args: ArgsType,
206
+ capabilities: CapabilitiesType,
207
+ options?: FunctionHandlerOptions,
208
+ ): Promise<DataHandlerResult<ReturnType>>;
209
+ }
210
+
211
+ /**
212
+ * Generic tool interface for tools that yield a new `ConversationContext` rather than plain data.
213
+ *
214
+ * @template ArgsType The expected object schema for tool arguments.
215
+ * @template ContextClass The concrete item type wrapped by the returned `ConversationContext`.
216
+ * @template CapabilitiesType The capabilities interface required by this tool. Defaults to `BaseToolCapability`.
217
+ */
218
+ export interface ContextTool<
219
+ ArgsType extends ToolArgs = ToolArgs,
220
+ ContextClass = unknown,
221
+ CapabilitiesType extends BaseToolCapability = BaseToolCapability,
222
+ > extends BaseTool<ArgsType> {
138
223
  /**
139
224
  * The implementation function called when the AI invokes this tool.
140
225
  *
141
226
  * @param args The arguments provided by the AI model matching the tool's parameter schema.
142
- * @param context The context object providing the capabilities requested by `ContextType`.
227
+ * @param capabilities The context object providing the capabilities requested by `CapabilitiesType`.
143
228
  * @param options Additional runtime options for the handler execution.
144
229
  */
145
230
  handler(
146
- args: Args,
147
- context: ContextType,
231
+ args: ArgsType,
232
+ capabilities: CapabilitiesType,
148
233
  options?: FunctionHandlerOptions,
149
- ): Promise<FunctionCallHandlerResult<ReturnType>>;
234
+ ): Promise<ContextHandlerResult<ContextClass>>;
150
235
  }
236
+
237
+ /**
238
+ * Represents any AI Assistance tool: either a `DataTool` (returns data/widgets) or a `ContextTool` (switches active context).
239
+ */
240
+ export type Tool<
241
+ ArgsType extends ToolArgs = ToolArgs,
242
+ ReturnType = unknown,
243
+ CapabilitiesType extends BaseToolCapability = BaseToolCapability,
244
+ > = DataTool<ArgsType, ReturnType, CapabilitiesType>|ContextTool<ArgsType, ReturnType, CapabilitiesType>;
@@ -8,6 +8,7 @@ import {GetLighthouseAuditsTool} from './GetLighthouseAudits.js';
8
8
  import {GetNetworkRequestDetailsTool} from './GetNetworkRequestDetails.js';
9
9
  import {GetStylesTool} from './GetStyles.js';
10
10
  import {ListNetworkRequestsTool} from './ListNetworkRequests.js';
11
+ import {RecordPerformanceTraceTool} from './RecordPerformanceTrace.js';
11
12
  import {ResolveDevtoolsNodePathTool} from './ResolveDevtoolsNodePath.js';
12
13
  import {type AllToolsCapabilities, type Tool, type ToolArgs, ToolName} from './Tool.js';
13
14
 
@@ -27,6 +28,7 @@ export const TOOLS = {
27
28
  [ToolName.GET_LIGHTHOUSE_AUDITS]: new GetLighthouseAuditsTool(),
28
29
  [ToolName.RESOLVE_DEVTOOLS_NODE_PATH]: new ResolveDevtoolsNodePathTool(),
29
30
  [ToolName.GET_ELEMENT_ACCESSIBILITY_DETAILS]: new GetElementAccessibilityDetailsTool(),
31
+ [ToolName.RECORD_PERFORMANCE_TRACE]: new RecordPerformanceTraceTool(),
30
32
  };
31
33
 
32
34
  /**
@@ -92,7 +92,9 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
92
92
  Root.DevToolsContext.globalInstance().set(
93
93
  UserBadges,
94
94
  new UserBadges(
95
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
95
96
  Common.Settings.Settings.instance(),
97
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
96
98
  Host.GdpClient.GdpClient.instance(),
97
99
  Host.InspectorFrontendHost.InspectorFrontendHostInstance,
98
100
  ),
@@ -120,6 +120,7 @@ export class NetworkProject {
120
120
  }
121
121
 
122
122
  const data = {uiSourceCode, frame};
123
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
123
124
  NetworkProjectManager.instance().dispatchEventToListeners(Events.FRAME_ATTRIBUTION_ADDED, data);
124
125
  }
125
126
 
@@ -140,18 +141,22 @@ export class NetworkProject {
140
141
  }
141
142
  frameAttribution.delete(frameId);
142
143
  const data = {uiSourceCode, frame: attributionInfo.frame};
144
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
143
145
  NetworkProjectManager.instance().dispatchEventToListeners(Events.FRAME_ATTRIBUTION_REMOVED, data);
144
146
  }
145
147
 
146
148
  static targetForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Target.Target|null {
149
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
147
150
  return NetworkProjectManager.instance().getTargetForUISourceCode(uiSourceCode);
148
151
  }
149
152
 
150
153
  static setTargetForProject(project: Workspace.Workspace.Project, target: SDK.Target.Target): void {
154
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
151
155
  NetworkProjectManager.instance().setTargetForProject(project, target);
152
156
  }
153
157
 
154
158
  static getTargetForProject(project: Workspace.Workspace.Project): SDK.Target.Target|null {
159
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
155
160
  return NetworkProjectManager.instance().getTargetForProject(project);
156
161
  }
157
162
 
@@ -408,6 +408,7 @@ export class ResourceScriptFile extends Common.ObjectWrapper.ObjectWrapper<Resou
408
408
  if (!exceptionDetails) {
409
409
  // TODO(crbug.com/1334484): Instead of to the console, report these errors in an "info bar" at the bottom
410
410
  // of the text editor, similar to e.g. source mapping errors.
411
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
411
412
  Common.Console.Console.instance().addMessage(
412
413
  i18nString(UIStrings.liveEditFailed, {PH1: getErrorText(status)}), Common.Console.MessageLevel.WARNING);
413
414
  return;
@@ -508,6 +509,7 @@ export class ResourceScriptFile extends Common.ObjectWrapper.ObjectWrapper<Resou
508
509
  if (!this.script) {
509
510
  return;
510
511
  }
512
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
511
513
  const {pluginManager} = DebuggerWorkspaceBinding.instance();
512
514
  pluginManager.setDebugInfoURL(this.script, debugInfoURL);
513
515
  }
@@ -39,6 +39,7 @@ import type * as Protocol from '../../generated/protocol.js';
39
39
  import * as Workspace from '../workspace/workspace.js';
40
40
 
41
41
  export function resourceForURL(url: Platform.DevToolsPath.UrlString): SDK.Resource.Resource|null {
42
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
42
43
  return SDK.ResourceTreeModel.ResourceTreeModel.resourceForURL(SDK.TargetManager.TargetManager.instance(), url);
43
44
  }
44
45
 
@@ -47,6 +48,7 @@ export function displayNameForURL(url: Platform.DevToolsPath.UrlString): string
47
48
  return '';
48
49
  }
49
50
 
51
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
50
52
  const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(url);
51
53
  if (uiSourceCode) {
52
54
  return uiSourceCode.displayName();
@@ -57,6 +59,7 @@ export function displayNameForURL(url: Platform.DevToolsPath.UrlString): string
57
59
  return resource.displayName;
58
60
  }
59
61
 
62
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
60
63
  const inspectedURL = SDK.TargetManager.TargetManager.instance().inspectedURL();
61
64
  if (!inspectedURL) {
62
65
  return Platform.StringUtilities.trimURL(url, '');
@@ -166,6 +166,7 @@ export class CrUXManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
166
166
  if (!Root.DevToolsContext.globalInstance().has(CrUXManager) || forceNew) {
167
167
  Root.DevToolsContext.globalInstance().set(
168
168
  CrUXManager,
169
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
169
170
  new CrUXManager(SDK.TargetManager.TargetManager.instance(), Common.Settings.Settings.instance()));
170
171
  }
171
172
 
@@ -5,10 +5,13 @@
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
+ import * as Platform from '../../core/platform/platform.js';
8
9
  import * as Root from '../../core/root/root.js';
9
10
  import * as SDK from '../../core/sdk/sdk.js';
11
+ import * as TextUtils from '../../core/text_utils/text_utils.js';
10
12
  import * as Protocol from '../../generated/protocol.js';
11
13
  import * as Geometry from '../geometry/geometry.js';
14
+ import * as Workspace from '../workspace/workspace.js';
12
15
 
13
16
  import {
14
17
  type Cutout,
@@ -196,12 +199,16 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
196
199
 
197
200
  static instance(opts?: {forceNew: boolean}): DeviceModeModel {
198
201
  if (!Root.DevToolsContext.globalInstance().has(DeviceModeModel) || opts?.forceNew) {
199
- Root.DevToolsContext.globalInstance().set(DeviceModeModel,
200
- new DeviceModeModel(
201
- SDK.TargetManager.TargetManager.instance(),
202
- Common.Settings.Settings.instance(),
203
- SDK.NetworkManager.MultitargetNetworkManager.instance(),
204
- ));
202
+ Root.DevToolsContext.globalInstance().set(
203
+ DeviceModeModel,
204
+ new DeviceModeModel(
205
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
206
+ SDK.TargetManager.TargetManager.instance(),
207
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
208
+ Common.Settings.Settings.instance(),
209
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
210
+ SDK.NetworkManager.MultitargetNetworkManager.instance(),
211
+ ));
205
212
  }
206
213
 
207
214
  return Root.DevToolsContext.globalInstance().get(DeviceModeModel);
@@ -444,6 +451,14 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
444
451
  return this.#settings.createSetting('emulation.show-device-mode', false);
445
452
  }
446
453
 
454
+ isDeviceModeOn(): boolean {
455
+ return this.enabledSetting().get();
456
+ }
457
+
458
+ toggleDeviceMode(): void {
459
+ this.enabledSetting().set(!this.enabledSetting().get());
460
+ }
461
+
447
462
  scaleSetting(): Common.Settings.Setting<number> {
448
463
  return this.#scaleSetting;
449
464
  }
@@ -832,7 +847,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
832
847
  }
833
848
  }
834
849
 
835
- async captureScreenshot(fullSize: boolean, clip?: Protocol.Page.Viewport): Promise<string|null> {
850
+ async #captureScreenshot(fullSize: boolean, clip?: Protocol.Page.Viewport): Promise<string|null> {
836
851
  const screenCaptureModel =
837
852
  this.#emulationModel ? this.#emulationModel.target().model(SDK.ScreenCaptureModel.ScreenCaptureModel) : null;
838
853
  if (!screenCaptureModel) {
@@ -879,6 +894,124 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
879
894
  }
880
895
  }
881
896
 
897
+ async captureScreenshot(): Promise<void> {
898
+ const screenshot = await this.#captureScreenshot(false);
899
+ if (screenshot === null) {
900
+ return;
901
+ }
902
+
903
+ const pageImage = new Image();
904
+ pageImage.src = 'data:image/png;base64,' + screenshot;
905
+ pageImage.onload = async () => {
906
+ const scale = pageImage.naturalWidth / this.screenRect().width;
907
+ const outlineRectFromModel = this.outlineRect();
908
+ if (!outlineRectFromModel) {
909
+ throw new Error('Unable to take screenshot: no outlineRect available.');
910
+ }
911
+ const outlineRect = outlineRectFromModel.scale(scale);
912
+ const screenRect = this.screenRect().scale(scale);
913
+ const visiblePageRect = this.visiblePageRect().scale(scale);
914
+ const contentLeft = screenRect.left + visiblePageRect.left - outlineRect.left;
915
+ const contentTop = screenRect.top + visiblePageRect.top - outlineRect.top;
916
+
917
+ const canvas = new OffscreenCanvas(Math.floor(outlineRect.width),
918
+ // Cap the height to not hit the GPU limit.
919
+ // https://crbug.com/1260828
920
+ Math.min((1 << 14), Math.floor(outlineRect.height)));
921
+ const ctx = canvas.getContext('2d', {willReadFrequently: true});
922
+ if (!ctx) {
923
+ throw new Error('Could not get 2d context from canvas.');
924
+ }
925
+ ctx.imageSmoothingEnabled = false;
926
+
927
+ if (this.outlineImage()) {
928
+ await this.paintImage(ctx, this.outlineImage(), outlineRect.relativeTo(outlineRect));
929
+ }
930
+ if (this.screenImage()) {
931
+ await this.paintImage(ctx, this.screenImage(), screenRect.relativeTo(outlineRect));
932
+ }
933
+ ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
934
+ void this.saveScreenshot(canvas);
935
+ };
936
+ }
937
+
938
+ async captureFullSizeScreenshot(): Promise<void> {
939
+ const screenshot = await this.#captureScreenshot(true);
940
+ if (screenshot === null) {
941
+ return;
942
+ }
943
+ return this.saveScreenshotBase64(screenshot);
944
+ }
945
+
946
+ async captureAreaScreenshot(clip?: Protocol.Page.Viewport): Promise<void> {
947
+ const screenshot = await this.#captureScreenshot(false, clip);
948
+ if (screenshot === null) {
949
+ return;
950
+ }
951
+ return this.saveScreenshotBase64(screenshot);
952
+ }
953
+
954
+ private saveScreenshotBase64(screenshot: string): void {
955
+ const pageImage = new Image();
956
+ pageImage.src = 'data:image/png;base64,' + screenshot;
957
+ pageImage.onload = () => {
958
+ const canvas = new OffscreenCanvas(pageImage.naturalWidth,
959
+ // Cap the height to not hit the GPU limit.
960
+ // https://crbug.com/1260828
961
+ Math.min((1 << 14), Math.floor(pageImage.naturalHeight)));
962
+ const ctx = canvas.getContext('2d', {willReadFrequently: true});
963
+ if (!ctx) {
964
+ throw new Error('Could not get 2d context for base64 screenshot.');
965
+ }
966
+ ctx.imageSmoothingEnabled = false;
967
+ ctx.drawImage(pageImage, 0, 0);
968
+ void this.saveScreenshot(canvas);
969
+ };
970
+ }
971
+
972
+ private paintImage(ctx: OffscreenCanvasRenderingContext2D|CanvasRenderingContext2D, src: string,
973
+ rect: Rect): Promise<void> {
974
+ return new Promise(resolve => {
975
+ const image = new Image();
976
+ image.crossOrigin = 'Anonymous';
977
+ image.srcset = src;
978
+ image.onerror = () => resolve();
979
+ image.onload = () => {
980
+ ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height);
981
+ resolve();
982
+ };
983
+ });
984
+ }
985
+
986
+ private async saveScreenshot(canvas: OffscreenCanvas): Promise<void> {
987
+ const url = this.inspectedURL();
988
+ let fileName = '';
989
+ if (url) {
990
+ const withoutFragment = Platform.StringUtilities.removeURLFragment(url);
991
+ fileName = Platform.StringUtilities.trimURL(withoutFragment);
992
+ }
993
+
994
+ const device = this.device();
995
+ if (device && this.type() === Type.Device) {
996
+ fileName += `(${device.title})`;
997
+ }
998
+ fileName += '.png';
999
+ const blob = await canvas.convertToBlob({type: 'image/png'});
1000
+ const dataUrl = await new Promise<string>((resolve, reject) => {
1001
+ const reader = new FileReader();
1002
+ reader.onloadend = () => resolve(reader.result as string);
1003
+ reader.onerror = reject;
1004
+ reader.readAsDataURL(blob);
1005
+ });
1006
+ const base64 = dataUrl.slice(dataUrl.indexOf(',') + 1);
1007
+ const contentData = new TextUtils.ContentData.ContentData(base64, /* isBase64=*/ true, 'image/png');
1008
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
1009
+ await Workspace.FileManager.FileManager.instance().save(fileName as Platform.DevToolsPath.RawPathString,
1010
+ contentData, /* forceSaveAs=*/ true);
1011
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
1012
+ Workspace.FileManager.FileManager.instance().close(fileName as Platform.DevToolsPath.RawPathString);
1013
+ }
1014
+
882
1015
  private applyTouch(touchEnabled: boolean, mobile: boolean): void {
883
1016
  this.#touchEnabled = touchEnabled;
884
1017
  this.#touchMobile = mobile;