chrome-devtools-frontend 1.0.1526203 → 1.0.1528866

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 (328) hide show
  1. package/docs/ui_engineering.md +159 -0
  2. package/eslint.config.mjs +6 -1
  3. package/front_end/core/i18n/i18nImpl.ts +5 -0
  4. package/front_end/core/protocol_client/protocol_client.ts +1 -1
  5. package/front_end/core/root/Runtime.ts +28 -4
  6. package/front_end/core/sdk/CSSMatchedStyles.ts +50 -7
  7. package/front_end/core/sdk/CSSRule.ts +35 -6
  8. package/front_end/core/sdk/ChildTargetManager.ts +2 -0
  9. package/front_end/core/sdk/Connections.ts +2 -1
  10. package/front_end/core/sdk/DOMModel.ts +4 -0
  11. package/front_end/core/sdk/DebuggerModel.ts +5 -1
  12. package/front_end/core/sdk/NetworkManager.ts +214 -31
  13. package/front_end/core/sdk/PreloadingModel.ts +82 -17
  14. package/front_end/core/sdk/RehydratingConnection.snapshot.txt +1 -1
  15. package/front_end/core/sdk/RehydratingConnection.ts +29 -4
  16. package/front_end/core/sdk/ScopeTreeCache.ts +8 -3
  17. package/front_end/core/sdk/SourceMap.ts +37 -11
  18. package/front_end/core/sdk/SourceMapManager.ts +13 -2
  19. package/front_end/core/sdk/SourceMapScopesInfo.ts +17 -0
  20. package/front_end/core/sdk/TargetManager.ts +0 -22
  21. package/front_end/core/sdk/TraceObject.ts +8 -7
  22. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +81 -0
  23. package/front_end/entrypoints/inspector_main/InspectorMain.ts +3 -1
  24. package/front_end/entrypoints/main/GlobalAiButton.ts +1 -0
  25. package/front_end/entrypoints/main/MainImpl.ts +20 -25
  26. package/front_end/generated/InspectorBackendCommands.js +4 -3
  27. package/front_end/generated/protocol-mapping.d.ts +3 -1
  28. package/front_end/generated/protocol-proxy-api.d.ts +3 -1
  29. package/front_end/generated/protocol.ts +17 -3
  30. package/front_end/models/ai_assistance/BuiltInAi.ts +111 -0
  31. package/front_end/models/ai_assistance/ai_assistance.ts +53 -24
  32. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +105 -0
  33. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +6 -1
  34. package/front_end/models/extensions/ExtensionView.ts +3 -0
  35. package/front_end/models/javascript_metadata/NativeFunctions.js +23 -27
  36. package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +31 -29
  37. package/front_end/models/persistence/EditFileSystemView.ts +1 -0
  38. package/front_end/models/source_map_scopes/NamesResolver.ts +5 -11
  39. package/front_end/models/stack_trace/Trie.ts +9 -0
  40. package/front_end/models/trace/lantern/types/Lantern.ts +1 -1
  41. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +1 -0
  42. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +1 -0
  43. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +120 -113
  44. package/front_end/panels/ai_assistance/PatchWidget.ts +9 -8
  45. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +2 -0
  46. package/front_end/panels/ai_assistance/components/ChatView.ts +29 -29
  47. package/front_end/panels/ai_assistance/components/UserActionRow.ts +1 -0
  48. package/front_end/panels/animation/AnimationTimeline.ts +1 -0
  49. package/front_end/panels/application/CookieItemsView.ts +1 -0
  50. package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
  51. package/front_end/panels/application/ServiceWorkerCacheViews.ts +2 -0
  52. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +11 -5
  53. package/front_end/panels/application/preloading/components/PreloadingMismatchedHeadersGrid.ts +2 -2
  54. package/front_end/panels/application/preloading/components/PreloadingString.ts +7 -5
  55. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +22 -10
  56. package/front_end/panels/changes/CombinedDiffView.ts +1 -0
  57. package/front_end/panels/console/ConsoleInsightTeaser.ts +106 -0
  58. package/front_end/panels/console/ConsolePanel.ts +2 -0
  59. package/front_end/panels/console/ConsolePrompt.ts +12 -2
  60. package/front_end/panels/console/ConsoleSidebar.ts +1 -1
  61. package/front_end/panels/console/ConsoleView.ts +12 -0
  62. package/front_end/panels/console/ConsoleViewMessage.ts +27 -0
  63. package/front_end/panels/{explain → console}/PromptBuilder.ts +12 -7
  64. package/front_end/panels/console/console.ts +6 -0
  65. package/front_end/panels/console/consoleInsightTeaser.css +55 -0
  66. package/front_end/panels/coverage/CoverageListView.ts +141 -277
  67. package/front_end/panels/coverage/CoverageView.ts +330 -324
  68. package/front_end/panels/coverage/coverageView.css +17 -0
  69. package/front_end/panels/elements/ComputedStyleWidget.ts +1 -0
  70. package/front_end/panels/elements/LayoutPane.ts +1 -0
  71. package/front_end/panels/elements/NodeStackTraceWidget.ts +1 -0
  72. package/front_end/panels/elements/StylePropertyTreeElement.ts +5 -1
  73. package/front_end/panels/elements/stylePropertiesTreeOutline.css +17 -0
  74. package/front_end/panels/emulation/DeviceModeView.ts +2 -0
  75. package/front_end/panels/explain/ActionDelegate.ts +1 -2
  76. package/front_end/panels/explain/components/ConsoleInsight.ts +14 -12
  77. package/front_end/panels/explain/explain.ts +0 -1
  78. package/front_end/panels/js_timeline/js_timeline-meta.ts +1 -1
  79. package/front_end/panels/layer_viewer/Layers3DView.ts +2 -0
  80. package/front_end/panels/lighthouse/LighthouseReportSelector.ts +1 -0
  81. package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorPane.ts +12 -19
  82. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +27 -43
  83. package/front_end/panels/media/MainView.ts +1 -0
  84. package/front_end/panels/media/TickingFlameChart.ts +2 -0
  85. package/front_end/panels/network/BlockedURLsPane.ts +111 -85
  86. package/front_end/panels/network/EventSourceMessagesView.ts +1 -0
  87. package/front_end/panels/network/NetworkItemView.ts +1 -0
  88. package/front_end/panels/network/NetworkLogView.ts +9 -7
  89. package/front_end/panels/network/NetworkOverview.ts +1 -0
  90. package/front_end/panels/network/RequestCookiesView.ts +1 -0
  91. package/front_end/panels/network/RequestHTMLView.ts +1 -0
  92. package/front_end/panels/network/RequestInitiatorView.ts +1 -0
  93. package/front_end/panels/network/RequestPayloadView.ts +1 -0
  94. package/front_end/panels/network/RequestPreviewView.ts +1 -0
  95. package/front_end/panels/network/RequestResponseView.ts +2 -1
  96. package/front_end/panels/network/RequestTimingView.ts +2 -0
  97. package/front_end/panels/network/ResourceDirectSocketChunkView.ts +1 -0
  98. package/front_end/panels/network/ResourceWebSocketFrameView.ts +1 -0
  99. package/front_end/panels/network/components/RequestHeadersView.ts +2 -0
  100. package/front_end/panels/network/components/RequestTrustTokensView.ts +2 -0
  101. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +2 -0
  102. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +2 -0
  103. package/front_end/panels/profiler/HeapSnapshotView.ts +7 -0
  104. package/front_end/panels/profiler/IsolateSelector.ts +1 -0
  105. package/front_end/panels/profiler/LiveHeapProfileView.ts +1 -0
  106. package/front_end/panels/profiler/ProfileView.ts +1 -0
  107. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +1 -0
  108. package/front_end/panels/recorder/RecorderPanel.ts +2 -0
  109. package/front_end/panels/screencast/ScreencastView.ts +1 -0
  110. package/front_end/panels/search/SearchView.ts +1 -0
  111. package/front_end/panels/settings/AISettingsTab.ts +3 -3
  112. package/front_end/panels/settings/WorkspaceSettingsTab.ts +2 -0
  113. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +2 -2
  114. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +12 -0
  115. package/front_end/panels/sources/BreakpointsView.ts +1 -0
  116. package/front_end/panels/sources/DebuggerPlugin.ts +1 -0
  117. package/front_end/panels/sources/UISourceCodeFrame.ts +17 -2
  118. package/front_end/panels/timeline/README.md +2 -2
  119. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +1 -1
  120. package/front_end/panels/timeline/TimelineFlameChartView.ts +4 -3
  121. package/front_end/panels/timeline/TimelineLayersView.ts +1 -0
  122. package/front_end/panels/timeline/TimelinePaintProfilerView.ts +114 -37
  123. package/front_end/panels/timeline/TimelinePanel.ts +43 -62
  124. package/front_end/panels/timeline/TimelineTreeView.ts +1 -0
  125. package/front_end/panels/timeline/components/LiveMetricsView.ts +4 -8
  126. package/front_end/panels/timeline/components/Sidebar.ts +2 -0
  127. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
  128. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +7 -7
  129. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +1 -1
  130. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +4 -4
  131. package/front_end/panels/web_audio/WebAudioView.ts +1 -0
  132. package/front_end/third_party/chromium/README.chromium +1 -1
  133. package/front_end/third_party/lighthouse/README.chromium +2 -2
  134. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1530 -2426
  135. package/front_end/third_party/lighthouse/locales/ar-XB.json +107 -455
  136. package/front_end/third_party/lighthouse/locales/ar.json +107 -455
  137. package/front_end/third_party/lighthouse/locales/bg.json +96 -444
  138. package/front_end/third_party/lighthouse/locales/ca.json +96 -444
  139. package/front_end/third_party/lighthouse/locales/cs.json +96 -444
  140. package/front_end/third_party/lighthouse/locales/da.json +96 -444
  141. package/front_end/third_party/lighthouse/locales/de.json +96 -444
  142. package/front_end/third_party/lighthouse/locales/el.json +96 -444
  143. package/front_end/third_party/lighthouse/locales/en-GB.json +96 -444
  144. package/front_end/third_party/lighthouse/locales/en-US.json +116 -467
  145. package/front_end/third_party/lighthouse/locales/en-XA.json +93 -441
  146. package/front_end/third_party/lighthouse/locales/en-XL.json +116 -467
  147. package/front_end/third_party/lighthouse/locales/es-419.json +96 -444
  148. package/front_end/third_party/lighthouse/locales/es.json +96 -444
  149. package/front_end/third_party/lighthouse/locales/fi.json +96 -444
  150. package/front_end/third_party/lighthouse/locales/fil.json +96 -444
  151. package/front_end/third_party/lighthouse/locales/fr.json +96 -444
  152. package/front_end/third_party/lighthouse/locales/he.json +118 -466
  153. package/front_end/third_party/lighthouse/locales/hi.json +96 -444
  154. package/front_end/third_party/lighthouse/locales/hr.json +100 -448
  155. package/front_end/third_party/lighthouse/locales/hu.json +96 -444
  156. package/front_end/third_party/lighthouse/locales/id.json +96 -444
  157. package/front_end/third_party/lighthouse/locales/it.json +96 -444
  158. package/front_end/third_party/lighthouse/locales/ja.json +96 -444
  159. package/front_end/third_party/lighthouse/locales/ko.json +97 -445
  160. package/front_end/third_party/lighthouse/locales/lt.json +96 -444
  161. package/front_end/third_party/lighthouse/locales/lv.json +97 -445
  162. package/front_end/third_party/lighthouse/locales/nl.json +96 -444
  163. package/front_end/third_party/lighthouse/locales/no.json +96 -444
  164. package/front_end/third_party/lighthouse/locales/pl.json +96 -444
  165. package/front_end/third_party/lighthouse/locales/pt-PT.json +96 -444
  166. package/front_end/third_party/lighthouse/locales/pt.json +97 -445
  167. package/front_end/third_party/lighthouse/locales/ro.json +97 -445
  168. package/front_end/third_party/lighthouse/locales/ru.json +96 -444
  169. package/front_end/third_party/lighthouse/locales/sk.json +96 -444
  170. package/front_end/third_party/lighthouse/locales/sl.json +96 -444
  171. package/front_end/third_party/lighthouse/locales/sr-Latn.json +96 -444
  172. package/front_end/third_party/lighthouse/locales/sr.json +96 -444
  173. package/front_end/third_party/lighthouse/locales/sv.json +96 -444
  174. package/front_end/third_party/lighthouse/locales/ta.json +96 -444
  175. package/front_end/third_party/lighthouse/locales/te.json +97 -445
  176. package/front_end/third_party/lighthouse/locales/th.json +96 -444
  177. package/front_end/third_party/lighthouse/locales/tr.json +96 -444
  178. package/front_end/third_party/lighthouse/locales/uk.json +96 -444
  179. package/front_end/third_party/lighthouse/locales/vi.json +96 -444
  180. package/front_end/third_party/lighthouse/locales/zh-HK.json +96 -444
  181. package/front_end/third_party/lighthouse/locales/zh-TW.json +97 -445
  182. package/front_end/third_party/lighthouse/locales/zh.json +96 -444
  183. package/front_end/third_party/lighthouse/report/bundle.d.ts +8 -14
  184. package/front_end/third_party/lighthouse/report/bundle.js +10 -49
  185. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +1 -1
  186. package/front_end/third_party/web-vitals/README.chromium +5 -8
  187. package/front_end/third_party/web-vitals/package/README.md +191 -152
  188. package/front_end/third_party/web-vitals/package/dist/modules/attribution/index.d.ts +0 -1
  189. package/front_end/third_party/web-vitals/package/dist/modules/attribution/index.js +0 -1
  190. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onCLS.d.ts +2 -2
  191. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onCLS.js +45 -26
  192. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.d.ts +2 -2
  193. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.js +3 -3
  194. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.d.ts +10 -10
  195. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +307 -206
  196. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.d.ts +2 -2
  197. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +69 -49
  198. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.d.ts +2 -2
  199. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.js +2 -2
  200. package/front_end/third_party/web-vitals/package/dist/modules/index.d.ts +0 -1
  201. package/front_end/third_party/web-vitals/package/dist/modules/index.js +0 -1
  202. package/front_end/third_party/web-vitals/package/dist/modules/lib/InteractionManager.d.ts +33 -0
  203. package/front_end/third_party/web-vitals/package/dist/modules/lib/InteractionManager.js +111 -0
  204. package/front_end/third_party/web-vitals/package/dist/modules/lib/LCPEntryManager.d.ts +4 -0
  205. package/front_end/third_party/web-vitals/package/dist/modules/{attribution/deprecated.js → lib/LCPEntryManager.js} +6 -7
  206. package/front_end/third_party/web-vitals/package/dist/modules/lib/LayoutShiftManager.d.ts +6 -0
  207. package/front_end/third_party/web-vitals/package/dist/modules/lib/LayoutShiftManager.js +44 -0
  208. package/front_end/third_party/web-vitals/package/dist/modules/lib/bindReporter.js +1 -1
  209. package/front_end/third_party/web-vitals/package/dist/modules/lib/generateUniqueID.js +1 -1
  210. package/front_end/third_party/web-vitals/package/dist/modules/lib/getActivationStart.js +1 -1
  211. package/front_end/third_party/web-vitals/package/dist/modules/lib/getNavigationEntry.js +5 -7
  212. package/front_end/third_party/web-vitals/package/dist/modules/lib/getSelector.d.ts +1 -1
  213. package/front_end/third_party/web-vitals/package/dist/modules/lib/getSelector.js +9 -12
  214. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.d.ts +1 -0
  215. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.js +52 -33
  216. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.d.ts +0 -2
  217. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.js +2 -2
  218. package/front_end/third_party/web-vitals/package/dist/modules/lib/initUnique.d.ts +6 -0
  219. package/front_end/third_party/web-vitals/package/dist/modules/{deprecated.js → lib/initUnique.js} +11 -4
  220. package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.js +3 -6
  221. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.js +6 -6
  222. package/front_end/third_party/web-vitals/package/dist/modules/lib/{whenIdle.d.ts → whenIdleOrHidden.d.ts} +1 -1
  223. package/front_end/third_party/web-vitals/package/dist/modules/lib/{whenIdle.js → whenIdleOrHidden.js} +10 -8
  224. package/front_end/third_party/web-vitals/package/dist/modules/onCLS.js +17 -35
  225. package/front_end/third_party/web-vitals/package/dist/modules/onFCP.js +3 -5
  226. package/front_end/third_party/web-vitals/package/dist/modules/onINP.d.ts +9 -7
  227. package/front_end/third_party/web-vitals/package/dist/modules/onINP.js +27 -19
  228. package/front_end/third_party/web-vitals/package/dist/modules/onLCP.js +33 -26
  229. package/front_end/third_party/web-vitals/package/dist/modules/onTTFB.js +2 -4
  230. package/front_end/third_party/web-vitals/package/dist/modules/types/base.d.ts +6 -5
  231. package/front_end/third_party/web-vitals/package/dist/modules/types/cls.d.ts +5 -3
  232. package/front_end/third_party/web-vitals/package/dist/modules/types/inp.d.ts +80 -33
  233. package/front_end/third_party/web-vitals/package/dist/modules/types/lcp.d.ts +6 -2
  234. package/front_end/third_party/web-vitals/package/dist/modules/types.d.ts +28 -4
  235. package/front_end/third_party/web-vitals/package/dist/modules/types.js +0 -1
  236. package/front_end/third_party/web-vitals/package/package.json +4 -10
  237. package/front_end/third_party/web-vitals/package/src/attribution/index.ts +0 -1
  238. package/front_end/third_party/web-vitals/package/src/attribution/onCLS.ts +58 -33
  239. package/front_end/third_party/web-vitals/package/src/attribution/onFCP.ts +4 -4
  240. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +382 -258
  241. package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +96 -69
  242. package/front_end/third_party/web-vitals/package/src/attribution/onTTFB.ts +3 -3
  243. package/front_end/third_party/web-vitals/package/src/index.ts +0 -1
  244. package/front_end/third_party/web-vitals/package/src/lib/InteractionManager.ts +146 -0
  245. package/front_end/third_party/web-vitals/package/src/{attribution/deprecated.ts → lib/LCPEntryManager.ts} +6 -9
  246. package/front_end/third_party/web-vitals/package/src/lib/LayoutShiftManager.ts +50 -0
  247. package/front_end/third_party/web-vitals/package/src/lib/bindReporter.ts +1 -1
  248. package/front_end/third_party/web-vitals/package/src/lib/generateUniqueID.ts +1 -1
  249. package/front_end/third_party/web-vitals/package/src/lib/getActivationStart.ts +1 -1
  250. package/front_end/third_party/web-vitals/package/src/lib/getNavigationEntry.ts +5 -8
  251. package/front_end/third_party/web-vitals/package/src/lib/getSelector.ts +12 -12
  252. package/front_end/third_party/web-vitals/package/src/lib/getVisibilityWatcher.ts +57 -35
  253. package/front_end/third_party/web-vitals/package/src/lib/initMetric.ts +2 -2
  254. package/front_end/third_party/web-vitals/package/src/{deprecated.ts → lib/initUnique.ts} +14 -8
  255. package/front_end/third_party/web-vitals/package/src/lib/observe.ts +3 -11
  256. package/front_end/third_party/web-vitals/package/src/lib/polyfills/interactionCountPolyfill.ts +12 -6
  257. package/front_end/third_party/web-vitals/package/src/lib/{whenIdle.ts → whenIdleOrHidden.ts} +10 -8
  258. package/front_end/third_party/web-vitals/package/src/onCLS.ts +17 -38
  259. package/front_end/third_party/web-vitals/package/src/onFCP.ts +3 -6
  260. package/front_end/third_party/web-vitals/package/src/onINP.ts +33 -28
  261. package/front_end/third_party/web-vitals/package/src/onLCP.ts +36 -29
  262. package/front_end/third_party/web-vitals/package/src/onTTFB.ts +2 -5
  263. package/front_end/third_party/web-vitals/package/src/types/base.ts +5 -5
  264. package/front_end/third_party/web-vitals/package/src/types/cls.ts +5 -3
  265. package/front_end/third_party/web-vitals/package/src/types/inp.ts +88 -33
  266. package/front_end/third_party/web-vitals/package/src/types/lcp.ts +6 -2
  267. package/front_end/third_party/web-vitals/package/src/types.ts +47 -4
  268. package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +75 -0
  269. package/front_end/third_party/web-vitals/rebuild.sh +32 -18
  270. package/front_end/third_party/web-vitals/web-vitals-tsconfig.json +5 -10
  271. package/front_end/third_party/web-vitals/web-vitals.ts +0 -2
  272. package/front_end/ui/components/buttons/Button.ts +1 -1
  273. package/front_end/ui/components/docs/console_insight/basic.ts +3 -2
  274. package/front_end/ui/components/legacy_wrapper/LegacyWrapper.ts +2 -0
  275. package/front_end/ui/components/text_editor/TextEditor.ts +0 -2
  276. package/front_end/ui/legacy/EmptyWidget.ts +11 -1
  277. package/front_end/ui/legacy/InspectorView.ts +2 -0
  278. package/front_end/ui/legacy/SplitWidget.ts +2 -0
  279. package/front_end/ui/legacy/TabbedPane.ts +1 -0
  280. package/front_end/ui/legacy/TargetCrashedScreen.ts +1 -0
  281. package/front_end/ui/legacy/Toolbar.ts +25 -4
  282. package/front_end/ui/legacy/UIUtils.ts +28 -13
  283. package/front_end/ui/legacy/ViewManager.ts +1 -0
  284. package/front_end/ui/legacy/Widget.ts +5 -0
  285. package/front_end/ui/legacy/components/color_picker/FormatPickerContextMenu.ts +7 -20
  286. package/front_end/ui/legacy/components/color_picker/Spectrum.ts +2 -0
  287. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +1 -0
  288. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +1 -1
  289. package/front_end/ui/legacy/components/inline_editor/BezierEditor.ts +1 -0
  290. package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +1 -0
  291. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +1 -0
  292. package/front_end/ui/legacy/components/source_frame/FontView.ts +1 -0
  293. package/front_end/ui/legacy/components/source_frame/ImageView.ts +1 -0
  294. package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -0
  295. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +1 -0
  296. package/front_end/ui/legacy/components/source_frame/StreamingContentHexView.ts +9 -8
  297. package/front_end/ui/visual_logging/KnownContextValues.ts +17 -0
  298. package/mcp/README.md +7 -0
  299. package/mcp/mcp.ts +8 -0
  300. package/package.json +1 -1
  301. package/front_end/models/live-metrics/web-vitals-injected/OnEachInteraction.ts +0 -34
  302. package/front_end/third_party/web-vitals/package/attribution.d.ts +0 -16
  303. package/front_end/third_party/web-vitals/package/attribution.js +0 -18
  304. package/front_end/third_party/web-vitals/package/dist/modules/attribution/deprecated.d.ts +0 -7
  305. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFID.d.ts +0 -11
  306. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFID.js +0 -46
  307. package/front_end/third_party/web-vitals/package/dist/modules/deprecated.d.ts +0 -5
  308. package/front_end/third_party/web-vitals/package/dist/modules/lib/interactions.d.ts +0 -31
  309. package/front_end/third_party/web-vitals/package/dist/modules/lib/interactions.js +0 -107
  310. package/front_end/third_party/web-vitals/package/dist/modules/lib/onHidden.d.ts +0 -1
  311. package/front_end/third_party/web-vitals/package/dist/modules/lib/onHidden.js +0 -22
  312. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/firstInputPolyfill.d.ts +0 -7
  313. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/firstInputPolyfill.js +0 -147
  314. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.d.ts +0 -1
  315. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/getFirstHiddenTimePolyfill.js +0 -25
  316. package/front_end/third_party/web-vitals/package/dist/modules/onFID.d.ts +0 -13
  317. package/front_end/third_party/web-vitals/package/dist/modules/onFID.js +0 -70
  318. package/front_end/third_party/web-vitals/package/dist/modules/types/fid.d.ts +0 -46
  319. package/front_end/third_party/web-vitals/package/dist/modules/types/fid.js +0 -16
  320. package/front_end/third_party/web-vitals/package/src/attribution/onFID.ts +0 -62
  321. package/front_end/third_party/web-vitals/package/src/lib/interactions.ts +0 -139
  322. package/front_end/third_party/web-vitals/package/src/lib/onHidden.ts +0 -23
  323. package/front_end/third_party/web-vitals/package/src/lib/polyfills/firstInputPolyfill.ts +0 -174
  324. package/front_end/third_party/web-vitals/package/src/onFID.ts +0 -105
  325. package/front_end/third_party/web-vitals/package/src/types/fid.ts +0 -65
  326. package/front_end/ui/components/text_editor/textEditor.css +0 -18
  327. package/front_end/ui/legacy/inlineButton.css +0 -22
  328. /package/front_end/entrypoints/{rehydrated_devtools_app/rehydrated_devtools_app.ts → trace_app/trace_app.ts} +0 -0
@@ -474,7 +474,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
474
474
  }
475
475
  } else if (setting.name === 'ai-assistance-enabled' && !setting.get()) {
476
476
  // If the "AI Assistance" is toggled off, we remove all the history entries related to the feature.
477
- void AiAssistanceModel.AiHistoryStorage.instance().deleteAll();
477
+ void AiAssistanceModel.AiHistoryStorage.AiHistoryStorage.instance().deleteAll();
478
478
  }
479
479
  void this.render();
480
480
  }
@@ -551,7 +551,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
551
551
  if (!settingData) {
552
552
  return Lit.nothing;
553
553
  }
554
- const disabledReasons = AiAssistanceModel.getDisabledReasons(this.#aidaAvailability);
554
+ const disabledReasons = AiAssistanceModel.AiUtils.getDisabledReasons(this.#aidaAvailability);
555
555
  const isDisabled = disabledReasons.length > 0;
556
556
  const disabledReasonsJoined = disabledReasons.join('\n') || undefined;
557
557
  const detailsClasses = {
@@ -639,7 +639,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
639
639
  }
640
640
 
641
641
  override async render(): Promise<void> {
642
- const disabledReasons = AiAssistanceModel.getDisabledReasons(this.#aidaAvailability);
642
+ const disabledReasons = AiAssistanceModel.AiUtils.getDisabledReasons(this.#aidaAvailability);
643
643
 
644
644
  // Disabled until https://crbug.com/1079231 is fixed.
645
645
  // clang-format off
@@ -106,6 +106,7 @@ export class WorkspaceSettingsTab extends UI.Widget.VBox {
106
106
  }
107
107
 
108
108
  override wasShown(): void {
109
+ super.wasShown();
109
110
  this.#eventListeners = [
110
111
  Persistence.IsolatedFileSystemManager.IsolatedFileSystemManager.instance().addEventListener(
111
112
  Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, this.requestUpdate.bind(this)),
@@ -117,6 +118,7 @@ export class WorkspaceSettingsTab extends UI.Widget.VBox {
117
118
  }
118
119
 
119
120
  override willHide(): void {
121
+ super.willHide();
120
122
  Common.EventTarget.removeEventListeners(this.#eventListeners);
121
123
  this.#eventListeners = [];
122
124
  }
@@ -868,14 +868,14 @@ export class UserAgentClientHintsForm extends HTMLElement {
868
868
  <devtools-icon name=triangle-down></devtools-icon>
869
869
  ${i18nString(UIStrings.title)}
870
870
  </div>
871
- <devtools-icon class=info-icon name=info title=${i18nString(UIStrings.userAgentClientHintsInfo)}></devtools-icon>
871
+ <devtools-icon tabindex=${this.#isFormDisabled ? '-1' : '0'} class=info-icon name=info aria-label=${i18nString(UIStrings.userAgentClientHintsInfo)} title=${i18nString(UIStrings.userAgentClientHintsInfo)}></devtools-icon>
872
872
  <x-link
873
873
  tabindex=${this.#isFormDisabled ? '-1' : '0'}
874
874
  href="https://web.dev/user-agent-client-hints/"
875
875
  target="_blank"
876
876
  class="link"
877
877
  @keypress=${this.#handleLinkPress}
878
- aria-label=${i18nString(UIStrings.userAgentClientHintsInfo)}
878
+ aria-label=${i18nString(UIStrings.learnMore)}
879
879
  jslog=${VisualLogging.link('learn-more').track({click: true})}
880
880
  >
881
881
  ${i18nString(UIStrings.learnMore)}
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
+ import * as i18n from '../../core/i18n/i18n.js';
7
8
  import * as Root from '../../core/root/root.js';
8
9
  import * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
9
10
  import type * as Workspace from '../../models/workspace/workspace.js';
@@ -334,6 +335,17 @@ export class AiCodeCompletionPlugin extends Plugin {
334
335
  }
335
336
 
336
337
  #isAiCodeCompletionEnabled(): boolean {
338
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
339
+ const aidaAvailability = Root.Runtime.hostConfig.aidaAvailability;
340
+ if (!devtoolsLocale.locale.startsWith('en-')) {
341
+ return false;
342
+ }
343
+ if (aidaAvailability?.blockedByGeo) {
344
+ return false;
345
+ }
346
+ if (aidaAvailability?.blockedByAge) {
347
+ return false;
348
+ }
337
349
  return Boolean(Root.Runtime.hostConfig.devToolsAiCodeCompletion?.enabled);
338
350
  }
339
351
 
@@ -720,6 +720,7 @@ export class BreakpointsView extends UI.Widget.VBox {
720
720
  }
721
721
 
722
722
  override wasShown(): void {
723
+ super.wasShown();
723
724
  this.requestUpdate();
724
725
  }
725
726
 
@@ -449,6 +449,7 @@ export class DebuggerPlugin extends Plugin {
449
449
  }
450
450
 
451
451
  override willHide(): void {
452
+ super.willHide();
452
453
  this.popoverHelper?.hidePopover();
453
454
  }
454
455
 
@@ -6,6 +6,7 @@
6
6
 
7
7
  import * as Common from '../../core/common/common.js';
8
8
  import * as Host from '../../core/host/host.js';
9
+ import * as i18n from '../../core/i18n/i18n.js';
9
10
  import * as Root from '../../core/root/root.js';
10
11
  import * as FormatterActions from '../../entrypoints/formatter_worker/FormatterActions.js'; // eslint-disable-line rulesdir/es-modules-import
11
12
  import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
@@ -320,8 +321,7 @@ export class UISourceCodeFrame extends Common.ObjectWrapper
320
321
  AiWarningInfobarPlugin,
321
322
  ];
322
323
 
323
- if (Root.Runtime.hostConfig.aidaAvailability?.enabled &&
324
- Root.Runtime.hostConfig.devToolsAiCodeCompletion?.enabled) {
324
+ if (this.#isAiCodeCompletionEnabled()) {
325
325
  sourceFramePluginsList.push(AiCodeCompletionPlugin);
326
326
  }
327
327
  return sourceFramePluginsList;
@@ -511,6 +511,21 @@ export class UISourceCodeFrame extends Common.ObjectWrapper
511
511
  this.#uiSourceCode.url().startsWith('debugger://'));
512
512
  Host.userMetrics.sourcesPanelFileOpened(mediaType);
513
513
  }
514
+
515
+ static #isAiCodeCompletionEnabled(): boolean {
516
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
517
+ const aidaAvailability = Root.Runtime.hostConfig.aidaAvailability;
518
+ if (!devtoolsLocale.locale.startsWith('en-')) {
519
+ return false;
520
+ }
521
+ if (aidaAvailability?.blockedByGeo) {
522
+ return false;
523
+ }
524
+ if (aidaAvailability?.blockedByAge) {
525
+ return false;
526
+ }
527
+ return Boolean(aidaAvailability?.enabled && Root.Runtime.hostConfig.devToolsAiCodeCompletion?.enabled);
528
+ }
514
529
  }
515
530
 
516
531
  function getIconDataForLevel(level: Workspace.UISourceCode.Message.Level): IconButton.Icon.IconWithName {
@@ -28,8 +28,8 @@ This option loads the DevTools frontend in a browser tab in Chrome, but requires
28
28
 
29
29
  1. Head to `devtools-frontend/test/unittests/fixtures/traces` and run `npx statikk --cors`. [This is a tool built by @paulirish to serve local files on a server](https://github.com/paulirish/statikk).
30
30
  2. Build and run the Chrome for Testing binary from devtools-frontend.
31
- 3. Visit `devtools://devtools/bundled/devtools_app.html` and let it load (you only need to do this the first time you load up the Chrome for Testing binary).
32
- 4. Update the URL by appending `?loadTimelineFromURL=http://localhost:1234/name-of-trace-file.json`. **Swap the port to the one `statikk` is using on your machine**.
31
+ 3. Visit `devtools://devtools/bundled/trace_app.html` and let it load (you only need to do this the first time you load up the Chrome for Testing binary).
32
+ 4. Update the URL by appending `?traceURL=http://localhost:1234/name-of-trace-file.json`. **Swap the port to the one `statikk` is using on your machine**.
33
33
  5. When you make changes and rebuild DevTools, simply refresh the URL! **Make sure you disable network caching in your DevTools on DevTools instance.**
34
34
 
35
35
  Each one has its pros and cons, but typically **this option is preferred** for quick iteration because you don't have to manually record or import a trace every time you reload.
@@ -252,7 +252,7 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
252
252
 
253
253
  const contextMenu = new UI.ContextMenu.ContextMenu(mouseEvent);
254
254
  if (perfAIEntryPointEnabled && this.parsedTrace) {
255
- const callTree = AIAssistance.AICallTree.fromEvent(entry, this.parsedTrace);
255
+ const callTree = AIAssistance.AICallTree.AICallTree.fromEvent(entry, this.parsedTrace);
256
256
  if (callTree) {
257
257
  const action = UI.ActionRegistry.ActionRegistry.instance().getAction(PERF_AI_ACTION_ID);
258
258
 
@@ -1408,6 +1408,7 @@ export class TimelineFlameChartView extends Common.ObjectWrapper.eventMixin<Even
1408
1408
  }
1409
1409
 
1410
1410
  override willHide(): void {
1411
+ super.willHide();
1411
1412
  this.#networkPersistedGroupConfigSetting.removeChangeListener(this.resizeToPreferredHeights, this);
1412
1413
  Workspace.IgnoreListManager.IgnoreListManager.instance().removeChangeListener(this.#boundRefreshAfterIgnoreList);
1413
1414
  }
@@ -1535,16 +1536,16 @@ export class TimelineFlameChartView extends Common.ObjectWrapper.eventMixin<Even
1535
1536
 
1536
1537
  const event = selectionIsEvent(selection) ? selection.event : null;
1537
1538
 
1538
- let focus = UI.Context.Context.instance().flavor(AIAssistance.AgentFocus);
1539
+ let focus = UI.Context.Context.instance().flavor(AIAssistance.AIContext.AgentFocus);
1539
1540
  if (focus) {
1540
1541
  focus = focus.withEvent(event);
1541
1542
  } else if (event) {
1542
- focus = AIAssistance.AgentFocus.fromEvent(this.#parsedTrace, event);
1543
+ focus = AIAssistance.AIContext.AgentFocus.fromEvent(this.#parsedTrace, event);
1543
1544
  } else {
1544
1545
  focus = null;
1545
1546
  }
1546
1547
 
1547
- UI.Context.Context.instance().setFlavor(AIAssistance.AgentFocus, focus);
1548
+ UI.Context.Context.instance().setFlavor(AIAssistance.AIContext.AgentFocus, focus);
1548
1549
  });
1549
1550
  }
1550
1551
 
@@ -55,6 +55,7 @@ export class TimelineLayersView extends UI.SplitWidget.SplitWidget {
55
55
  }
56
56
 
57
57
  override wasShown(): void {
58
+ super.wasShown();
58
59
  if (this.updateWhenVisible) {
59
60
  this.updateWhenVisible = false;
60
61
  this.update();
@@ -8,11 +8,15 @@ import type * as Protocol from '../../generated/protocol.js';
8
8
  import * as Geometry from '../../models/geometry/geometry.js';
9
9
  import * as Trace from '../../models/trace/trace.js';
10
10
  import * as UI from '../../ui/legacy/legacy.js';
11
+ import * as Lit from '../../ui/lit/lit.js';
11
12
  import * as LayerViewer from '../layer_viewer/layer_viewer.js';
12
13
 
13
14
  import timelinePaintProfilerStyles from './timelinePaintProfiler.css.js';
14
15
  import {TracingFrameLayerTree} from './TracingLayerTree.js';
15
16
 
17
+ const {html, render} = Lit;
18
+ const {createRef, ref} = Lit.Directives;
19
+
16
20
  export class TimelinePaintProfilerView extends UI.SplitWidget.SplitWidget {
17
21
  private readonly logAndImageSplitWidget: UI.SplitWidget.SplitWidget;
18
22
  private readonly imageView: TimelinePaintImageView;
@@ -27,14 +31,12 @@ export class TimelinePaintProfilerView extends UI.SplitWidget.SplitWidget {
27
31
 
28
32
  constructor(parsedTrace: Trace.TraceModel.ParsedTrace) {
29
33
  super(false, false);
30
- this.element.classList.add('timeline-paint-profiler-view');
31
34
  this.setSidebarSize(60);
32
35
  this.setResizable(false);
33
36
 
34
37
  this.#parsedTrace = parsedTrace;
35
38
 
36
- this.logAndImageSplitWidget = new UI.SplitWidget.SplitWidget(true, false);
37
- this.logAndImageSplitWidget.element.classList.add('timeline-paint-profiler-log-split');
39
+ this.logAndImageSplitWidget = new UI.SplitWidget.SplitWidget(true, false, 'timeline-paint-profiler-log-split');
38
40
  this.setMainWidget(this.logAndImageSplitWidget);
39
41
  this.imageView = new TimelinePaintImageView();
40
42
  this.logAndImageSplitWidget.setMainWidget(this.imageView);
@@ -204,53 +206,112 @@ export class TimelinePaintProfilerView extends UI.SplitWidget.SplitWidget {
204
206
  }
205
207
  }
206
208
 
209
+ export interface TimelinePaintImageViewInput {
210
+ maskElementHidden: boolean;
211
+ imageContainerHidden: boolean;
212
+ imageURL: string;
213
+ imageContainerWebKitTransform: string;
214
+ maskElementStyle: {
215
+ width?: string,
216
+ height?: string,
217
+ borderLeftWidth?: string,
218
+ borderTopWidth?: string,
219
+ borderRightWidth?: string,
220
+ borderBottomWidth?: string,
221
+ };
222
+ }
223
+
224
+ export const DEFAULT_VIEW = (input: TimelinePaintImageViewInput, output: undefined, target: HTMLElement): {
225
+ imageElementNaturalHeight: number,
226
+ imageElementNaturalWidth: number,
227
+ } => {
228
+ const imageElementRef = createRef<HTMLImageElement>();
229
+ // clang-format off
230
+ render(html`
231
+ <div class="paint-profiler-image-view fill">
232
+ <div class="paint-profiler-image-container" style="-webkit-transform: ${input.imageContainerWebKitTransform}">
233
+ <img src=${input.imageURL} display=${input.imageContainerHidden ? 'none' : 'block'} ${ref(imageElementRef)}>
234
+ <div style=${Lit.Directives.styleMap({
235
+ display: input.maskElementHidden ? 'none' : 'block',
236
+ ...input.maskElementStyle,})}>
237
+ </div>
238
+ </div>
239
+ </div>`,
240
+ target);
241
+ // clang-format on
242
+
243
+ // The elements are guaranteed to exist after render completes
244
+ // because they are not conditionally rendered within the template.
245
+ const imageElement = imageElementRef.value;
246
+
247
+ if (!imageElement?.naturalHeight || !imageElement.naturalWidth) {
248
+ throw new Error('ImageElement were not found in the TimelinePaintImageView.');
249
+ }
250
+
251
+ return {imageElementNaturalHeight: imageElement.naturalHeight, imageElementNaturalWidth: imageElement.naturalWidth};
252
+ };
207
253
  export class TimelinePaintImageView extends UI.Widget.Widget {
208
- private imageContainer: HTMLElement;
209
- private imageElement: HTMLImageElement;
210
- private readonly maskElement: HTMLElement;
211
254
  private transformController: LayerViewer.TransformController.TransformController;
212
255
  private maskRectangle?: Protocol.DOM.Rect|null;
213
- constructor() {
214
- super({useShadowDom: true});
215
- this.registerRequiredCSS(timelinePaintProfilerStyles);
216
256
 
217
- this.contentElement.classList.add('fill', 'paint-profiler-image-view');
218
- this.imageContainer = this.contentElement.createChild('div', 'paint-profiler-image-container');
219
- this.imageElement = this.imageContainer.createChild('img');
220
- this.maskElement = this.imageContainer.createChild('div');
221
- this.imageElement.addEventListener('load', this.updateImagePosition.bind(this), false);
257
+ #inputData: TimelinePaintImageViewInput = {
258
+ maskElementHidden: true,
259
+ imageContainerHidden: true,
260
+ imageURL: '',
261
+ imageContainerWebKitTransform: '',
262
+ maskElementStyle: {},
263
+ };
264
+
265
+ #view: typeof DEFAULT_VIEW;
266
+ #imageElementDimensions?: {
267
+ naturalHeight: number,
268
+ naturalWidth: number,
269
+ };
270
+
271
+ constructor(view = DEFAULT_VIEW) {
272
+ super();
273
+ this.registerRequiredCSS(timelinePaintProfilerStyles);
274
+ this.#view = view;
222
275
  this.transformController = new LayerViewer.TransformController.TransformController((this.contentElement), true);
223
276
  this.transformController.addEventListener(
224
277
  LayerViewer.TransformController.Events.TRANSFORM_CHANGED, this.updateImagePosition, this);
225
278
  }
226
279
 
227
280
  override onResize(): void {
228
- if (this.imageElement.src) {
229
- this.updateImagePosition();
230
- }
281
+ this.requestUpdate();
282
+ this.updateImagePosition();
231
283
  }
232
284
 
233
285
  private updateImagePosition(): void {
234
- const width = this.imageElement.naturalWidth;
235
- const height = this.imageElement.naturalHeight;
286
+ if (!this.#imageElementDimensions) {
287
+ return;
288
+ }
289
+
290
+ const width = this.#imageElementDimensions.naturalWidth;
291
+ const height = this.#imageElementDimensions.naturalHeight;
236
292
  const clientWidth = this.contentElement.clientWidth;
237
293
  const clientHeight = this.contentElement.clientHeight;
238
294
 
239
295
  const paddingFraction = 0.1;
240
296
  const paddingX = clientWidth * paddingFraction;
241
- const paddingY = clientHeight * paddingFraction;
242
- const scaleX = (clientWidth - paddingX) / width;
243
- const scaleY = (clientHeight - paddingY) / height;
244
- const scale = Math.min(scaleX, scaleY);
297
+ const scale = clientHeight / height;
245
298
 
299
+ const oldMaskStyle = JSON.stringify(this.#inputData.maskElementStyle);
300
+ let newMaskStyle = {};
246
301
  if (this.maskRectangle) {
247
- const style = this.maskElement.style;
248
- style.width = width + 'px';
249
- style.height = height + 'px';
250
- style.borderLeftWidth = this.maskRectangle.x + 'px';
251
- style.borderTopWidth = this.maskRectangle.y + 'px';
252
- style.borderRightWidth = (width - this.maskRectangle.x - this.maskRectangle.width) + 'px';
253
- style.borderBottomWidth = (height - this.maskRectangle.y - this.maskRectangle.height) + 'px';
302
+ newMaskStyle = {
303
+ width: width + 'px',
304
+ height: height + 'px',
305
+ borderLeftWidth: this.maskRectangle.x + 'px',
306
+ borderTopWidth: this.maskRectangle.y + 'px',
307
+ borderRightWidth: (width - this.maskRectangle.x - this.maskRectangle.width) + 'px',
308
+ borderBottomWidth: (height - this.maskRectangle.y - this.maskRectangle.height) + 'px',
309
+ };
310
+ }
311
+ this.#inputData.maskElementStyle = newMaskStyle;
312
+
313
+ if (!this.transformController) {
314
+ return;
254
315
  }
255
316
  this.transformController.setScaleConstraints(0.5, 10 / scale);
256
317
  let matrix = new WebKitCSSMatrix()
@@ -259,24 +320,40 @@ export class TimelinePaintImageView extends UI.Widget.Widget {
259
320
  .scale(scale, scale)
260
321
  .translate(-width / 2, -height / 2);
261
322
  const bounds = Geometry.boundsForTransformedPoints(matrix, [0, 0, 0, width, height, 0]);
262
- this.transformController.clampOffsets(
263
- paddingX - bounds.maxX, clientWidth - paddingX - bounds.minX, paddingY - bounds.maxY,
264
- clientHeight - paddingY - bounds.minY);
323
+ this.transformController.clampOffsets(paddingX - bounds.maxX, clientWidth - paddingX - bounds.minX, 0, 0);
265
324
  matrix = new WebKitCSSMatrix()
266
325
  .translate(this.transformController.offsetX(), this.transformController.offsetY())
267
326
  .multiply(matrix);
268
- this.imageContainer.style.webkitTransform = matrix.toString();
327
+
328
+ const oldTransform = this.#inputData.imageContainerWebKitTransform;
329
+ const newTransform = matrix.toString();
330
+ this.#inputData.imageContainerWebKitTransform = newTransform;
331
+
332
+ if (oldTransform !== newTransform || oldMaskStyle !== JSON.stringify(newMaskStyle)) {
333
+ this.requestUpdate();
334
+ }
269
335
  }
270
336
 
271
337
  showImage(imageURL?: string): void {
272
- this.imageContainer.classList.toggle('hidden', !imageURL);
338
+ this.#inputData.imageContainerHidden = !imageURL;
273
339
  if (imageURL) {
274
- this.imageElement.src = imageURL;
340
+ this.#inputData.imageURL = imageURL;
275
341
  }
342
+ this.requestUpdate();
276
343
  }
277
344
 
278
345
  setMask(maskRectangle: Protocol.DOM.Rect|null): void {
279
346
  this.maskRectangle = maskRectangle;
280
- this.maskElement.classList.toggle('hidden', !maskRectangle);
347
+
348
+ this.#inputData.maskElementHidden = !maskRectangle;
349
+ this.requestUpdate();
350
+ }
351
+
352
+ override performUpdate(): void {
353
+ const {imageElementNaturalHeight, imageElementNaturalWidth} =
354
+ this.#view(this.#inputData, undefined, this.contentElement);
355
+ this.#imageElementDimensions = {naturalHeight: imageElementNaturalHeight, naturalWidth: imageElementNaturalWidth};
356
+ // Image can only be updated to correctly fit the component when the component has loaded.
357
+ this.updateImagePosition();
281
358
  }
282
359
  }