chrome-devtools-frontend 1.0.1512349 → 1.0.1513662

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 (324) hide show
  1. package/docs/cookbook/release_management.md +15 -13
  2. package/docs/get_the_code.md +114 -35
  3. package/front_end/core/common/Color.ts +40 -44
  4. package/front_end/core/common/Console.ts +4 -4
  5. package/front_end/core/common/ParsedURL.ts +14 -14
  6. package/front_end/core/common/ResourceType.ts +20 -20
  7. package/front_end/core/common/SegmentedRange.ts +13 -14
  8. package/front_end/core/common/Settings.ts +4 -4
  9. package/front_end/core/common/StringOutputStream.ts +4 -4
  10. package/front_end/core/host/GdpClient.ts +38 -0
  11. package/front_end/core/host/InspectorFrontendHost.ts +4 -1
  12. package/front_end/core/host/InspectorFrontendHostAPI.ts +2 -0
  13. package/front_end/core/host/ResourceLoader.ts +2 -2
  14. package/front_end/core/host/UserMetrics.ts +0 -2
  15. package/front_end/core/protocol_client/InspectorBackend.ts +9 -9
  16. package/front_end/core/root/Runtime.ts +5 -2
  17. package/front_end/core/sdk/AccessibilityModel.ts +48 -48
  18. package/front_end/core/sdk/AnimationModel.ts +78 -79
  19. package/front_end/core/sdk/CPUProfilerModel.ts +5 -5
  20. package/front_end/core/sdk/CPUThrottlingManager.ts +17 -17
  21. package/front_end/core/sdk/CSSMatchedStyles.ts +44 -44
  22. package/front_end/core/sdk/CSSMedia.ts +22 -22
  23. package/front_end/core/sdk/CSSModel.ts +4 -4
  24. package/front_end/core/sdk/CSSProperty.ts +9 -9
  25. package/front_end/core/sdk/CSSPropertyParser.ts +1 -2
  26. package/front_end/core/sdk/CSSRule.ts +3 -3
  27. package/front_end/core/sdk/CSSStyleDeclaration.ts +27 -28
  28. package/front_end/core/sdk/CSSStyleSheetHeader.ts +13 -13
  29. package/front_end/core/sdk/CategorizedBreakpoint.ts +4 -4
  30. package/front_end/core/sdk/ChildTargetManager.ts +6 -6
  31. package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +4 -4
  32. package/front_end/core/sdk/ConsoleModel.ts +24 -24
  33. package/front_end/core/sdk/Cookie.ts +16 -16
  34. package/front_end/core/sdk/CookieParser.ts +6 -6
  35. package/front_end/core/sdk/DOMDebuggerModel.ts +88 -89
  36. package/front_end/core/sdk/DOMModel.ts +113 -113
  37. package/front_end/core/sdk/DebuggerModel.ts +102 -103
  38. package/front_end/core/sdk/EmulationModel.ts +6 -6
  39. package/front_end/core/sdk/EventBreakpointsModel.ts +5 -5
  40. package/front_end/core/sdk/HeapProfilerModel.ts +5 -5
  41. package/front_end/core/sdk/IsolateManager.ts +26 -26
  42. package/front_end/core/sdk/LayerTreeBase.ts +29 -30
  43. package/front_end/core/sdk/OverlayModel.ts +6 -6
  44. package/front_end/core/sdk/Resource.ts +43 -43
  45. package/front_end/core/sdk/ResourceTreeModel.ts +58 -61
  46. package/front_end/core/sdk/RuntimeModel.ts +12 -13
  47. package/front_end/core/sdk/SDKModel.ts +3 -3
  48. package/front_end/core/sdk/Script.ts +17 -17
  49. package/front_end/core/sdk/SecurityOriginManager.ts +14 -14
  50. package/front_end/core/sdk/ServerTiming.ts +2 -2
  51. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +15 -15
  52. package/front_end/core/sdk/ServiceWorkerManager.ts +19 -24
  53. package/front_end/core/sdk/SourceMap.ts +10 -10
  54. package/front_end/core/sdk/StorageKeyManager.ts +12 -12
  55. package/front_end/core/sdk/Target.ts +33 -34
  56. package/front_end/core/sdk/TargetManager.ts +20 -20
  57. package/front_end/entrypoints/formatter_worker/AcornTokenizer.ts +8 -8
  58. package/front_end/entrypoints/formatter_worker/HTMLFormatter.ts +7 -7
  59. package/front_end/entrypoints/heap_snapshot_worker/AllocationProfile.ts +7 -7
  60. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +24 -24
  61. package/front_end/entrypoints/main/GlobalAiButton.ts +3 -3
  62. package/front_end/entrypoints/main/MainImpl.ts +16 -14
  63. package/front_end/entrypoints/main/main-meta.ts +1 -2
  64. package/front_end/generated/InspectorBackendCommands.js +3 -2
  65. package/front_end/generated/SupportedCSSProperties.js +20 -0
  66. package/front_end/generated/protocol-mapping.d.ts +4 -0
  67. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  68. package/front_end/generated/protocol.ts +20 -0
  69. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -16
  70. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +127 -0
  71. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +149 -26
  72. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +6 -0
  73. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +9 -10
  74. package/front_end/models/badges/AiExplorerBadge.ts +21 -0
  75. package/front_end/models/badges/Badge.ts +3 -5
  76. package/front_end/models/badges/CodeWhispererBadge.ts +21 -0
  77. package/front_end/models/badges/DOMDetectiveBadge.ts +4 -3
  78. package/front_end/models/badges/SpeedsterBadge.ts +6 -4
  79. package/front_end/models/badges/StarterBadge.ts +4 -3
  80. package/front_end/models/badges/UserBadges.ts +29 -3
  81. package/front_end/models/bindings/CSSWorkspaceBinding.ts +6 -6
  82. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +18 -18
  83. package/front_end/models/bindings/FileUtils.ts +15 -15
  84. package/front_end/models/bindings/ResourceScriptMapping.ts +14 -14
  85. package/front_end/models/elements/ElementUpdateRecord.ts +11 -11
  86. package/front_end/models/emulation/DeviceModeModel.ts +123 -131
  87. package/front_end/models/emulation/EmulatedDevices.ts +22 -22
  88. package/front_end/models/extensions/ExtensionPanel.ts +24 -24
  89. package/front_end/models/extensions/ExtensionServer.ts +4 -4
  90. package/front_end/models/javascript_metadata/NativeFunctions.js +14 -2
  91. package/front_end/models/persistence/IsolatedFileSystem.ts +18 -19
  92. package/front_end/models/persistence/IsolatedFileSystemManager.ts +13 -13
  93. package/front_end/models/trace/EventsSerializer.ts +5 -5
  94. package/front_end/models/trace/LanternComputationData.ts +10 -10
  95. package/front_end/models/trace/ModelImpl.ts +32 -41
  96. package/front_end/models/trace/Processor.ts +28 -30
  97. package/front_end/models/trace/extras/FilmStrip.ts +6 -6
  98. package/front_end/models/trace/extras/StackTraceForEvent.ts +22 -25
  99. package/front_end/models/trace/extras/ThirdParties.ts +16 -17
  100. package/front_end/models/trace/extras/TraceFilter.ts +1 -1
  101. package/front_end/models/trace/handlers/Threads.ts +10 -10
  102. package/front_end/models/trace/handlers/helpers.ts +9 -9
  103. package/front_end/models/trace/handlers/types.ts +3 -3
  104. package/front_end/models/trace/insights/CLSCulprits.ts +12 -14
  105. package/front_end/models/trace/insights/Cache.ts +8 -4
  106. package/front_end/models/trace/insights/DOMSize.ts +8 -5
  107. package/front_end/models/trace/insights/DocumentLatency.ts +2 -2
  108. package/front_end/models/trace/insights/DuplicatedJavaScript.ts +3 -3
  109. package/front_end/models/trace/insights/FontDisplay.ts +3 -4
  110. package/front_end/models/trace/insights/ForcedReflow.ts +3 -3
  111. package/front_end/models/trace/insights/INPBreakdown.ts +2 -2
  112. package/front_end/models/trace/insights/ImageDelivery.ts +11 -11
  113. package/front_end/models/trace/insights/LCPBreakdown.ts +4 -4
  114. package/front_end/models/trace/insights/LCPDiscovery.ts +4 -4
  115. package/front_end/models/trace/insights/LegacyJavaScript.ts +2 -2
  116. package/front_end/models/trace/insights/ModernHTTP.ts +4 -5
  117. package/front_end/models/trace/insights/NetworkDependencyTree.ts +12 -12
  118. package/front_end/models/trace/insights/RenderBlocking.ts +9 -10
  119. package/front_end/models/trace/insights/SlowCSSSelector.ts +2 -2
  120. package/front_end/models/trace/insights/ThirdParties.ts +4 -5
  121. package/front_end/models/trace/insights/Viewport.ts +8 -5
  122. package/front_end/models/trace/insights/types.ts +1 -0
  123. package/front_end/models/trace/lantern/testing/MetricTestUtils.ts +10 -10
  124. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +52 -52
  125. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +8 -8
  126. package/front_end/panels/animation/AnimationTimeline.ts +5 -5
  127. package/front_end/panels/animation/AnimationUI.ts +22 -23
  128. package/front_end/panels/application/ApplicationPanelSidebar.ts +12 -12
  129. package/front_end/panels/application/DOMStorageModel.ts +23 -23
  130. package/front_end/panels/application/ExtensionStorageModel.ts +31 -31
  131. package/front_end/panels/application/IndexedDBModel.ts +1 -0
  132. package/front_end/panels/application/PreloadingTreeElement.ts +8 -8
  133. package/front_end/panels/application/ServiceWorkersView.ts +0 -53
  134. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -2
  135. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -2
  136. package/front_end/panels/common/BadgeNotification.ts +24 -4
  137. package/front_end/panels/common/GdpSignUpDialog.ts +5 -0
  138. package/front_end/panels/common/badgeNotification.css +26 -9
  139. package/front_end/panels/console/ConsoleContextSelector.ts +9 -9
  140. package/front_end/panels/console/ConsolePrompt.ts +8 -5
  141. package/front_end/panels/console/ConsoleView.ts +13 -13
  142. package/front_end/panels/console/ConsoleViewport.ts +29 -29
  143. package/front_end/panels/coverage/CoverageModel.ts +22 -22
  144. package/front_end/panels/elements/ClassesPaneWidget.ts +1 -1
  145. package/front_end/panels/elements/ComputedStyleModel.ts +17 -18
  146. package/front_end/panels/elements/DOMPath.ts +2 -2
  147. package/front_end/panels/elements/ElementsPanel.ts +13 -13
  148. package/front_end/panels/elements/ElementsTreeElement.ts +18 -18
  149. package/front_end/panels/elements/ElementsTreeOutline.ts +41 -48
  150. package/front_end/panels/elements/ShortcutTreeElement.ts +4 -4
  151. package/front_end/panels/elements/StylePropertiesSection.ts +4 -4
  152. package/front_end/panels/elements/StylePropertyTreeElement.ts +49 -50
  153. package/front_end/panels/elements/StylesSidebarPane.ts +19 -19
  154. package/front_end/panels/emulation/DeviceModeToolbar.ts +7 -7
  155. package/front_end/panels/emulation/DeviceModeView.ts +6 -6
  156. package/front_end/panels/emulation/MediaQueryInspector.ts +18 -18
  157. package/front_end/panels/event_listeners/EventListenersView.ts +13 -14
  158. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +3 -3
  159. package/front_end/panels/layer_viewer/LayerViewHost.ts +13 -13
  160. package/front_end/panels/layer_viewer/PaintProfilerView.ts +9 -10
  161. package/front_end/panels/layer_viewer/TransformController.ts +34 -36
  162. package/front_end/panels/layers/LayerTreeModel.ts +41 -40
  163. package/front_end/panels/lighthouse/LighthouseReportSelector.ts +13 -13
  164. package/front_end/panels/lighthouse/LighthouseStartView.ts +7 -7
  165. package/front_end/panels/media/PlayerMessagesView.ts +5 -5
  166. package/front_end/panels/media/TickingFlameChart.ts +24 -24
  167. package/front_end/panels/media/TickingFlameChartHelpers.ts +32 -32
  168. package/front_end/panels/network/NetworkItemView.ts +4 -4
  169. package/front_end/panels/network/NetworkLogViewColumns.ts +29 -29
  170. package/front_end/panels/network/NetworkPanel.ts +8 -5
  171. package/front_end/panels/network/ResourceWebSocketFrameView.ts +10 -10
  172. package/front_end/panels/profiler/HeapDetachedElementsView.ts +3 -3
  173. package/front_end/panels/profiler/HeapProfileView.ts +1 -1
  174. package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +3 -4
  175. package/front_end/panels/profiler/ProfileHeader.ts +25 -25
  176. package/front_end/panels/profiler/ProfileLauncherView.ts +5 -6
  177. package/front_end/panels/recorder/components/ReplaySection.ts +3 -1
  178. package/front_end/panels/security/OriginTreeElement.ts +8 -8
  179. package/front_end/panels/security/SecurityPanel.ts +5 -5
  180. package/front_end/panels/settings/SettingsScreen.ts +18 -12
  181. package/front_end/panels/settings/components/SyncSection.ts +20 -6
  182. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +3 -0
  183. package/front_end/panels/sources/DebuggerPausedMessage.ts +8 -9
  184. package/front_end/panels/sources/NavigatorView.ts +43 -46
  185. package/front_end/panels/sources/SourcesPanel.ts +35 -35
  186. package/front_end/panels/sources/SourcesView.ts +13 -13
  187. package/front_end/panels/sources/TabbedEditorContainer.ts +19 -22
  188. package/front_end/panels/sources/UISourceCodeFrame.ts +4 -4
  189. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +34 -36
  190. package/front_end/panels/timeline/AnimationsTrackAppender.ts +3 -3
  191. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +8 -8
  192. package/front_end/panels/timeline/CountersGraph.ts +16 -16
  193. package/front_end/panels/timeline/EntriesFilter.ts +4 -3
  194. package/front_end/panels/timeline/EventsTimelineTreeView.ts +3 -3
  195. package/front_end/panels/timeline/GPUTrackAppender.ts +3 -3
  196. package/front_end/panels/timeline/Initiators.ts +10 -10
  197. package/front_end/panels/timeline/InteractionsTrackAppender.ts +5 -5
  198. package/front_end/panels/timeline/LayoutShiftsTrackAppender.ts +7 -7
  199. package/front_end/panels/timeline/ModificationsManager.ts +8 -15
  200. package/front_end/panels/timeline/TargetForEvent.ts +2 -2
  201. package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -1
  202. package/front_end/panels/timeline/ThreadAppender.ts +13 -13
  203. package/front_end/panels/timeline/TimelineDetailsView.ts +6 -14
  204. package/front_end/panels/timeline/TimelineEventOverview.ts +27 -26
  205. package/front_end/panels/timeline/TimelineFilters.ts +5 -5
  206. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +54 -53
  207. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +34 -34
  208. package/front_end/panels/timeline/TimelineFlameChartView.ts +18 -31
  209. package/front_end/panels/timeline/TimelineHistoryManager.ts +17 -18
  210. package/front_end/panels/timeline/TimelineMiniMap.ts +6 -6
  211. package/front_end/panels/timeline/TimelinePaintProfilerView.ts +6 -6
  212. package/front_end/panels/timeline/TimelinePanel.ts +52 -59
  213. package/front_end/panels/timeline/TimelineSelectorStatsView.ts +7 -5
  214. package/front_end/panels/timeline/TimelineTreeView.ts +10 -10
  215. package/front_end/panels/timeline/TimelineUIUtils.ts +43 -43
  216. package/front_end/panels/timeline/TimingsTrackAppender.ts +12 -12
  217. package/front_end/panels/timeline/TracingLayerTree.ts +43 -43
  218. package/front_end/panels/timeline/TrackConfigBanner.ts +6 -6
  219. package/front_end/panels/timeline/TrackConfiguration.ts +1 -1
  220. package/front_end/panels/timeline/components/DetailsView.ts +4 -4
  221. package/front_end/panels/timeline/components/LayoutShiftDetails.ts +12 -21
  222. package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -1
  223. package/front_end/panels/timeline/components/NetworkRequestDetails.ts +5 -5
  224. package/front_end/panels/timeline/components/Sidebar.ts +4 -14
  225. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +13 -36
  226. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +21 -19
  227. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +1 -1
  228. package/front_end/panels/timeline/components/insights/Cache.ts +4 -0
  229. package/front_end/panels/timeline/components/insights/DOMSize.ts +5 -1
  230. package/front_end/panels/timeline/components/insights/Helpers.ts +19 -0
  231. package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +1 -1
  232. package/front_end/panels/timeline/components/insights/Viewport.ts +4 -0
  233. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +1 -1
  234. package/front_end/panels/timeline/utils/AICallTree.ts +11 -11
  235. package/front_end/panels/timeline/utils/AIContext.ts +17 -19
  236. package/front_end/panels/timeline/utils/EntityMapper.ts +6 -5
  237. package/front_end/panels/timeline/utils/EntryName.ts +2 -2
  238. package/front_end/panels/timeline/utils/EntryNodes.ts +5 -5
  239. package/front_end/panels/timeline/utils/EntryStyles.ts +4 -4
  240. package/front_end/panels/timeline/utils/FreshRecording.ts +3 -3
  241. package/front_end/panels/timeline/utils/Helpers.ts +0 -18
  242. package/front_end/panels/timeline/utils/InsightAIContext.ts +6 -6
  243. package/front_end/panels/timeline/utils/SourceMapsResolver.ts +7 -7
  244. package/front_end/panels/webauthn/WebauthnPane.ts +1 -0
  245. package/front_end/third_party/chromium/README.chromium +1 -1
  246. package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
  247. package/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -1
  248. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  249. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  250. package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
  251. package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
  252. package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
  253. package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
  254. package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
  255. package/front_end/third_party/codemirror.next/chunk/legacy.js.map +1 -1
  256. package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
  257. package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
  258. package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
  259. package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
  260. package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
  261. package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
  262. package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
  263. package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
  264. package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
  265. package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
  266. package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
  267. package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
  268. package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
  269. package/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -1
  270. package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
  271. package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
  272. package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
  273. package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
  274. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  275. package/front_end/third_party/codemirror.next/package.json +1 -1
  276. package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
  277. package/front_end/third_party/json5/rebuild.sh +1 -1
  278. package/front_end/third_party/legacy-javascript/{update.sh → rebuild.sh} +1 -1
  279. package/front_end/third_party/lit/lib/decorators.d.ts +26 -9
  280. package/front_end/third_party/lit/lib/decorators.js +5 -5
  281. package/front_end/third_party/lit/lib/decorators.js.map +1 -1
  282. package/front_end/third_party/lit/lib/directive.js.map +1 -1
  283. package/front_end/third_party/lit/lib/directives.js +8 -13
  284. package/front_end/third_party/lit/lib/directives.js.map +1 -1
  285. package/front_end/third_party/lit/lib/lit.d.ts +26 -9
  286. package/front_end/third_party/lit/lib/lit.js +5 -5
  287. package/front_end/third_party/lit/lib/lit.js.map +1 -1
  288. package/front_end/third_party/lit/lib/static-html.js +2 -2
  289. package/front_end/third_party/lit/lib/static-html.js.map +1 -1
  290. package/front_end/third_party/lit/rebuild.sh +1 -1
  291. package/front_end/third_party/third-party-web/rebuild.sh +1 -1
  292. package/front_end/ui/components/dialogs/Dialog.ts +6 -7
  293. package/front_end/ui/legacy/ActionRegistration.ts +9 -9
  294. package/front_end/ui/legacy/DockController.ts +18 -18
  295. package/front_end/ui/legacy/FilterBar.ts +7 -7
  296. package/front_end/ui/legacy/Fragment.ts +4 -4
  297. package/front_end/ui/legacy/GlassPane.ts +12 -12
  298. package/front_end/ui/legacy/InspectorView.ts +5 -15
  299. package/front_end/ui/legacy/ListControl.ts +27 -27
  300. package/front_end/ui/legacy/ListWidget.ts +4 -4
  301. package/front_end/ui/legacy/PopoverHelper.ts +4 -4
  302. package/front_end/ui/legacy/ShortcutRegistry.ts +17 -17
  303. package/front_end/ui/legacy/TabbedPane.ts +74 -75
  304. package/front_end/ui/legacy/TextPrompt.ts +31 -31
  305. package/front_end/ui/legacy/Toolbar.ts +13 -14
  306. package/front_end/ui/legacy/ViewManager.ts +30 -31
  307. package/front_end/ui/legacy/Widget.ts +6 -6
  308. package/front_end/ui/legacy/XLink.ts +9 -9
  309. package/front_end/ui/legacy/ZoomManager.ts +9 -9
  310. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +27 -27
  311. package/front_end/ui/legacy/components/color_picker/ContrastInfo.ts +30 -32
  312. package/front_end/ui/legacy/components/color_picker/Spectrum.ts +15 -15
  313. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +64 -64
  314. package/front_end/ui/legacy/components/data_grid/ShowMoreDataGridNode.ts +2 -2
  315. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +10 -11
  316. package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +12 -12
  317. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +3 -3
  318. package/front_end/ui/legacy/components/perf_ui/TimelineGrid.ts +14 -14
  319. package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +8 -8
  320. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +5 -5
  321. package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +4 -4
  322. package/front_end/ui/legacy/theme_support/ThemeSupport.ts +4 -4
  323. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -2
  324. package/package.json +1 -1
@@ -14,12 +14,12 @@ import {bytes, micros, millis} from './UnitFormatters.js';
14
14
  /**
15
15
  * For a given frame ID and navigation ID, returns the LCP Event and the LCP Request, if the resource was an image.
16
16
  */
17
- function getLCPData(parsedTrace: Trace.Handlers.Types.ParsedTrace, frameId: string, navigationId: string): {
17
+ function getLCPData(parsedTrace: Trace.TraceModel.ParsedTrace, frameId: string, navigationId: string): {
18
18
  lcpEvent: Trace.Types.Events.LargestContentfulPaintCandidate,
19
19
  metricScore: Trace.Handlers.ModelHandlers.PageLoadMetrics.LCPMetricScore,
20
20
  lcpRequest?: Trace.Types.Events.SyntheticNetworkRequest,
21
21
  }|null {
22
- const navMetrics = parsedTrace.PageLoadMetrics.metricScoresByFrameId.get(frameId)?.get(navigationId);
22
+ const navMetrics = parsedTrace.data.PageLoadMetrics.metricScoresByFrameId.get(frameId)?.get(navigationId);
23
23
  if (!navMetrics) {
24
24
  return null;
25
25
  }
@@ -35,16 +35,16 @@ function getLCPData(parsedTrace: Trace.Handlers.Types.ParsedTrace, frameId: stri
35
35
 
36
36
  return {
37
37
  lcpEvent,
38
- lcpRequest: parsedTrace.LargestImagePaint.lcpRequestByNavigationId.get(navigationId),
38
+ lcpRequest: parsedTrace.data.LargestImagePaint.lcpRequestByNavigationId.get(navigationId),
39
39
  metricScore: metric,
40
40
  };
41
41
  }
42
42
 
43
43
  export class PerformanceInsightFormatter {
44
44
  #insight: Trace.Insights.Types.InsightModel;
45
- #parsedTrace: Trace.Handlers.Types.ParsedTrace;
45
+ #parsedTrace: Trace.TraceModel.ParsedTrace;
46
46
 
47
- constructor(parsedTrace: Trace.Handlers.Types.ParsedTrace, insight: Trace.Insights.Types.InsightModel) {
47
+ constructor(parsedTrace: Trace.TraceModel.ParsedTrace, insight: Trace.Insights.Types.InsightModel) {
48
48
  this.#insight = insight;
49
49
  this.#parsedTrace = parsedTrace;
50
50
  }
@@ -181,6 +181,87 @@ export class PerformanceInsightFormatter {
181
181
  }
182
182
  }
183
183
 
184
+ /**
185
+ * Create an AI prompt string out of the Cache Insight model to use with Ask AI.
186
+ * Note: This function accesses the UIStrings within Cache to help build the
187
+ * AI prompt, but does not (and should not) call i18nString to localize these strings. They
188
+ * should all be sent in English (at least for now).
189
+ * @param insight The Cache Insight Model to query.
190
+ * @returns a string formatted for sending to Ask AI.
191
+ */
192
+ formatCacheInsight(insight: Trace.Insights.Models.Cache.CacheInsightModel): string {
193
+ if (insight.requests.length === 0) {
194
+ return Trace.Insights.Models.Cache.UIStrings.noRequestsToCache + '.';
195
+ }
196
+
197
+ let output = 'The following resources were associated with ineffficient cache policies:\n';
198
+
199
+ for (const entry of insight.requests) {
200
+ output += `\n- ${entry.request.args.data.url}`;
201
+ output += `\n - Cache Time to Live (TTL): ${entry.ttl} seconds`;
202
+ output += `\n - Wasted bytes: ${bytes(entry.wastedBytes)}`;
203
+ }
204
+
205
+ output += '\n\n' + Trace.Insights.Models.Cache.UIStrings.description;
206
+ return output;
207
+ }
208
+
209
+ /**
210
+ * Create an AI prompt string out of the DOM Size model to use with Ask AI.
211
+ * Note: This function accesses the UIStrings within DomSize to help build the
212
+ * AI prompt, but does not (and should not) call i18nString to localize these strings. They
213
+ * should all be sent in English (at least for now).
214
+ * @param insight The DOM Size Insight Model to query.
215
+ * @returns a string formatted for sending to Ask AI.
216
+ */
217
+ formatDomSizeInsight(insight: Trace.Insights.Models.DOMSize.DOMSizeInsightModel): string {
218
+ if (insight.state === 'pass') {
219
+ return 'No DOM size issues were detected.';
220
+ }
221
+
222
+ let output = Trace.Insights.Models.DOMSize.UIStrings.description + '\n';
223
+
224
+ if (insight.maxDOMStats) {
225
+ output += '\n' + Trace.Insights.Models.DOMSize.UIStrings.statistic + ':\n\n';
226
+
227
+ const maxDepthStats = insight.maxDOMStats.args.data.maxDepth;
228
+ const maxChildrenStats = insight.maxDOMStats.args.data.maxChildren;
229
+ output += Trace.Insights.Models.DOMSize.UIStrings.totalElements + ': ' +
230
+ insight.maxDOMStats.args.data.totalElements + '.\n';
231
+ if (maxDepthStats) {
232
+ output += Trace.Insights.Models.DOMSize.UIStrings.maxDOMDepth + ': ' + maxDepthStats.depth +
233
+ ` nodes, starting with element '${maxDepthStats.nodeName}'` +
234
+ ' (node id: ' + maxDepthStats.nodeId + ').\n';
235
+ }
236
+ if (maxChildrenStats) {
237
+ output += Trace.Insights.Models.DOMSize.UIStrings.maxChildren + ': ' + maxChildrenStats.numChildren +
238
+ `, for parent '${maxChildrenStats.nodeName}'` +
239
+ ' (node id: ' + maxChildrenStats.nodeId + ').\n';
240
+ }
241
+ }
242
+
243
+ if (insight.largeLayoutUpdates.length > 0 || insight.largeStyleRecalcs.length > 0) {
244
+ output += `\nLarge layout updates/style calculations:\n`;
245
+ }
246
+
247
+ if (insight.largeLayoutUpdates.length > 0) {
248
+ for (const update of insight.largeLayoutUpdates) {
249
+ output += `\n - Layout update: Duration: ${this.#formatMicro(update.dur)},`;
250
+ output += ` with ${update.args.beginData.dirtyObjects} of ${
251
+ update.args.beginData.totalObjects} nodes needing layout.`;
252
+ }
253
+ }
254
+
255
+ if (insight.largeStyleRecalcs.length > 0) {
256
+ for (const recalc of insight.largeStyleRecalcs) {
257
+ output += `\n - Style recalculation: Duration: ${this.#formatMicro(recalc.dur)}, `;
258
+ output += `with ${recalc.args.elementCount} elements affected.`;
259
+ }
260
+ }
261
+
262
+ return output;
263
+ }
264
+
184
265
  /**
185
266
  * Create an AI prompt string out of the NetworkDependencyTree Insight model to use with Ask AI.
186
267
  * Note: This function accesses the UIStrings within NetworkDependencyTree to help build the
@@ -432,6 +513,32 @@ export class PerformanceInsightFormatter {
432
513
  return output;
433
514
  }
434
515
 
516
+ /**
517
+ * Create an AI prompt string out of the Viewport [Mobile] Insight model to use with Ask AI.
518
+ * Note: This function accesses the UIStrings within Viewport to help build the
519
+ * AI prompt, but does not (and should not) call i18nString to localize these strings. They
520
+ * should all be sent in English (at least for now).
521
+ * @param insight The Network Dependency Tree Insight Model to query.
522
+ * @returns a string formatted for sending to Ask AI.
523
+ */
524
+ formatViewportInsight(insight: Trace.Insights.Models.Viewport.ViewportInsightModel): string {
525
+ let output = '';
526
+
527
+ output += 'The webpage is ' + (insight.mobileOptimized ? 'already' : 'not') + ' optimized for mobile viewing.\n';
528
+
529
+ const hasMetaTag = insight.viewportEvent;
530
+ if (hasMetaTag) {
531
+ output += `\nThe viewport meta tag was found: \`${insight.viewportEvent?.args?.data.content}\`.`;
532
+ } else {
533
+ output += `\nThe viewport meta tag is missing.`;
534
+ }
535
+
536
+ if (!hasMetaTag) {
537
+ output += '\n\n' + Trace.Insights.Models.Viewport.UIStrings.description;
538
+ }
539
+ return output;
540
+ }
541
+
435
542
  /**
436
543
  * Formats and outputs the insight's data.
437
544
  * Pass `{headingLevel: X}` to determine what heading level to use for the
@@ -609,7 +716,7 @@ ${checklistBulletPoints.map(point => `- ${point.name}: ${point.passed ? 'PASSED'
609
716
  return '';
610
717
  }
611
718
 
612
- const baseTime = this.#parsedTrace.Meta.traceBounds.min;
719
+ const baseTime = this.#parsedTrace.data.Meta.traceBounds.min;
613
720
 
614
721
  const clusterTimes = {
615
722
  start: worstCluster.ts - baseTime,
@@ -682,6 +789,14 @@ Legacy JavaScript by file:
682
789
  ${filesFormatted}`;
683
790
  }
684
791
 
792
+ if (Trace.Insights.Models.Cache.isCacheInsight(this.#insight)) {
793
+ return this.formatCacheInsight(this.#insight);
794
+ }
795
+
796
+ if (Trace.Insights.Models.DOMSize.isDomSizeInsight(this.#insight)) {
797
+ return this.formatDomSizeInsight(this.#insight);
798
+ }
799
+
685
800
  if (Trace.Insights.Models.FontDisplay.isFontDisplayInsight(this.#insight)) {
686
801
  return this.formatFontDisplayInsight(this.#insight);
687
802
  }
@@ -702,6 +817,10 @@ ${filesFormatted}`;
702
817
  return this.formatThirdPartiesInsight(this.#insight);
703
818
  }
704
819
 
820
+ if (Trace.Insights.Models.Viewport.isViewportInsight(this.#insight)) {
821
+ return this.formatViewportInsight(this.#insight);
822
+ }
823
+
705
824
  return '';
706
825
  }
707
826
 
@@ -724,7 +843,7 @@ ${filesFormatted}`;
724
843
  case 'DocumentLatency':
725
844
  return '- https://web.dev/articles/optimize-ttfb';
726
845
  case 'DOMSize':
727
- return '';
846
+ return '- https://developer.chrome.com/docs/lighthouse/performance/dom-size/';
728
847
  case 'DuplicatedJavaScript':
729
848
  return '';
730
849
  case 'FontDisplay':
@@ -757,9 +876,9 @@ ${filesFormatted}`;
757
876
  case 'ThirdParties':
758
877
  return '- https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/';
759
878
  case 'Viewport':
760
- return '';
879
+ return '- https://developer.chrome.com/blog/300ms-tap-delay-gone-away/';
761
880
  case 'Cache':
762
- return '';
881
+ return '- https://web.dev/uses-long-cache-ttl/';
763
882
  case 'ModernHTTP':
764
883
  return '- https://developer.chrome.com/docs/lighthouse/best-practices/uses-http2';
765
884
  case 'LegacyJavaScript':
@@ -781,7 +900,11 @@ ${filesFormatted}`;
781
900
  2. Did the server respond in 600ms or less? We want developers to aim for as close to 100ms as possible, but our threshold for this insight is 600ms.
782
901
  3. Was there compression applied to the response to minimize the transfer size?`;
783
902
  case 'DOMSize':
784
- return '';
903
+ return `This insight evaluates some key metrics about the Document Object Model (DOM) and identifies excess in the DOM tree, for example:
904
+ - The maximum number of elements within the DOM.
905
+ - The maximum number of children for any given element.
906
+ - Excessive depth of the DOM structure.
907
+ - The largest layout and style recalculation events.`;
785
908
  case 'DuplicatedJavaScript':
786
909
  return `This insight identifies large, duplicated JavaScript modules that are present in your application and create redundant code.
787
910
  This wastes network bandwidth and slows down your page, as the user's browser must download and process the same code multiple times.`;
@@ -827,9 +950,9 @@ It is important that all of these checks pass to minimize the delay between the
827
950
  case 'ThirdParties':
828
951
  return 'This insight analyzes the performance impact of resources loaded from third-party servers and aggregates the performance cost, in terms of download transfer sizes and total amount of time that third party scripts spent executing on the main thread.';
829
952
  case 'Viewport':
830
- return '';
953
+ return 'The insight identifies web pages that are not specifying the viewport meta tag for mobile devies, which avoids the artificial 300-350ms delay designed to help differentiate between tap and double-click.';
831
954
  case 'Cache':
832
- return '';
955
+ return 'This insight identifies static resources that are not cached effectively by the browser.';
833
956
  case 'ModernHTTP':
834
957
  return `Modern HTTP protocols, such as HTTP/2, are more efficient than older versions like HTTP/1.1 because they allow for multiple requests and responses to be sent over a single network connection, significantly improving page load performance by reducing latency and overhead. This insight identifies requests that can be upgraded to a modern HTTP protocol.
835
958
 
@@ -854,9 +977,9 @@ export interface NetworkRequestFormatOptions {
854
977
 
855
978
  export class TraceEventFormatter {
856
979
  static layoutShift(
857
- shift: Trace.Types.Events.SyntheticLayoutShift, index: number, parsedTrace: Trace.Handlers.Types.ParsedTrace,
980
+ shift: Trace.Types.Events.SyntheticLayoutShift, index: number, parsedTrace: Trace.TraceModel.ParsedTrace,
858
981
  rootCauses?: Trace.Insights.Models.CLSCulprits.LayoutShiftRootCausesData): string {
859
- const baseTime = parsedTrace.Meta.traceBounds.min;
982
+ const baseTime = parsedTrace.data.Meta.traceBounds.min;
860
983
 
861
984
  const potentialRootCauses: string[] = [];
862
985
  if (rootCauses) {
@@ -895,7 +1018,7 @@ ${rootCauseText}`;
895
1018
 
896
1019
  // Stringify network requests for the LLM model.
897
1020
  static networkRequests(
898
- requests: readonly Trace.Types.Events.SyntheticNetworkRequest[], parsedTrace: Trace.Handlers.Types.ParsedTrace,
1021
+ requests: readonly Trace.Types.Events.SyntheticNetworkRequest[], parsedTrace: Trace.TraceModel.ParsedTrace,
899
1022
  options?: NetworkRequestFormatOptions): string {
900
1023
  if (requests.length === 0) {
901
1024
  return '';
@@ -929,7 +1052,7 @@ ${rootCauseText}`;
929
1052
  * talk to jacktfranklin@.
930
1053
  */
931
1054
  static #networkRequestVerbosely(
932
- request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.Handlers.Types.ParsedTrace,
1055
+ request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.TraceModel.ParsedTrace,
933
1056
  customTitle?: string): string {
934
1057
  const {
935
1058
  url,
@@ -950,9 +1073,9 @@ ${rootCauseText}`;
950
1073
  const navigationForEvent = Trace.Helpers.Trace.getNavigationForTraceEvent(
951
1074
  request,
952
1075
  request.args.data.frame,
953
- parsedTrace.Meta.navigationsByFrameId,
1076
+ parsedTrace.data.Meta.navigationsByFrameId,
954
1077
  );
955
- const baseTime = navigationForEvent?.ts ?? parsedTrace.Meta.traceBounds.min;
1078
+ const baseTime = navigationForEvent?.ts ?? parsedTrace.data.Meta.traceBounds.min;
956
1079
 
957
1080
  // Gets all the timings for this request, relative to the base time.
958
1081
  // Note that this is the start time, not total time. E.g. "queuedAt: X"
@@ -969,7 +1092,7 @@ ${rootCauseText}`;
969
1092
  const downloadTime = syntheticData.finishTime - syntheticData.downloadStart;
970
1093
 
971
1094
  const renderBlocking = Trace.Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(request);
972
- const initiator = parsedTrace.NetworkRequests.eventToInitiator.get(request);
1095
+ const initiator = parsedTrace.data.NetworkRequests.eventToInitiator.get(request);
973
1096
 
974
1097
  const priorityLines = [];
975
1098
  if (initialPriority === priority) {
@@ -1029,7 +1152,7 @@ ${NetworkRequestFormatter.formatHeaders('Response headers', responseHeaders ?? [
1029
1152
  // format description.
1030
1153
  static #networkRequestsArrayCompressed(
1031
1154
  requests: readonly Trace.Types.Events.SyntheticNetworkRequest[],
1032
- parsedTrace: Trace.Handlers.Types.ParsedTrace): string {
1155
+ parsedTrace: Trace.TraceModel.ParsedTrace): string {
1033
1156
  const networkDataString = `
1034
1157
  Network requests data:
1035
1158
 
@@ -1095,8 +1218,8 @@ The order of headers corresponds to an internal fixed list. If a header is not p
1095
1218
  * See `networkDataFormatDescription` above for specifics.
1096
1219
  */
1097
1220
  static #networkRequestCompressedFormat(
1098
- urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest,
1099
- parsedTrace: Trace.Handlers.Types.ParsedTrace, urlIdToIndex: Map<string, number>): string {
1221
+ urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.TraceModel.ParsedTrace,
1222
+ urlIdToIndex: Map<string, number>): string {
1100
1223
  const {
1101
1224
  statusCode,
1102
1225
  initialPriority,
@@ -1111,9 +1234,9 @@ The order of headers corresponds to an internal fixed list. If a header is not p
1111
1234
  const navigationForEvent = Trace.Helpers.Trace.getNavigationForTraceEvent(
1112
1235
  request,
1113
1236
  request.args.data.frame,
1114
- parsedTrace.Meta.navigationsByFrameId,
1237
+ parsedTrace.data.Meta.navigationsByFrameId,
1115
1238
  );
1116
- const baseTime = navigationForEvent?.ts ?? parsedTrace.Meta.traceBounds.min;
1239
+ const baseTime = navigationForEvent?.ts ?? parsedTrace.data.Meta.traceBounds.min;
1117
1240
  const queuedTime = micros(request.ts - baseTime);
1118
1241
  const requestSentTime = micros(syntheticData.sendStartTime - baseTime);
1119
1242
  const downloadCompleteTime = micros(syntheticData.finishTime - baseTime);
@@ -1168,13 +1291,13 @@ The order of headers corresponds to an internal fixed list. If a header is not p
1168
1291
  }
1169
1292
 
1170
1293
  static #getInitiatorChain(
1171
- parsedTrace: Trace.Handlers.Types.ParsedTrace,
1294
+ parsedTrace: Trace.TraceModel.ParsedTrace,
1172
1295
  request: Trace.Types.Events.SyntheticNetworkRequest): Trace.Types.Events.SyntheticNetworkRequest[] {
1173
1296
  const initiators: Trace.Types.Events.SyntheticNetworkRequest[] = [];
1174
1297
 
1175
1298
  let cur: Trace.Types.Events.SyntheticNetworkRequest|undefined = request;
1176
1299
  while (cur) {
1177
- const initiator = parsedTrace.NetworkRequests.eventToInitiator.get(cur);
1300
+ const initiator = parsedTrace.data.NetworkRequests.eventToInitiator.get(cur);
1178
1301
  if (initiator) {
1179
1302
  // Should never happen, but if it did that would be an infinite loop.
1180
1303
  if (initiators.includes(initiator)) {
@@ -900,6 +900,12 @@ Available insights:
900
900
  description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page's content.
901
901
  relevant trace bounds: {min: 157423742399, max: 157427277086}
902
902
  example question: Which third parties are having the largest impact on my page performance?
903
+ - insight name: Cache
904
+ description: A long cache lifetime can speed up repeat visits to your page. [Learn more](https://web.dev/uses-long-cache-ttl/).
905
+ relevant trace bounds: {min: 157423742399, max: 157426980482}
906
+ estimated metric savings: FCP 0 ms, LCP 0 ms
907
+ estimated wasted bytes: 847.4 kB
908
+ example question: What caching strategies can I apply to improve my page performance?
903
909
  - insight name: LegacyJavaScript
904
910
  description: Polyfills and transforms enable older browsers to use new JavaScript features. However, many aren't necessary for modern browsers. Consider modifying your JavaScript build process to not transpile [Baseline](https://web.dev/articles/baseline-and-polyfills) features, unless you know you must support older browsers. [Learn why most sites can deploy ES6+ code without transpiling](https://philipwalton.com/articles/the-state-of-es5-on-the-web/)
905
911
  relevant trace bounds: {min: 157423489126, max: 157426132225}
@@ -9,9 +9,8 @@ import {PerformanceInsightFormatter, TraceEventFormatter} from './PerformanceIns
9
9
  import {bytes, micros, millis} from './UnitFormatters.js';
10
10
 
11
11
  export class PerformanceTraceFormatter {
12
- #parsedTrace: Trace.Handlers.Types.ParsedTrace;
12
+ #parsedTrace: Trace.TraceModel.ParsedTrace;
13
13
  #insightSet: Trace.Insights.Types.InsightSet|null;
14
- #traceMetadata: Trace.Types.File.MetaData;
15
14
  #eventsSerializer: Trace.EventsSerializer.EventsSerializer;
16
15
 
17
16
  constructor(focus: TimelineUtils.AIContext.AgentFocus, eventsSerializer: Trace.EventsSerializer.EventsSerializer) {
@@ -21,7 +20,6 @@ export class PerformanceTraceFormatter {
21
20
 
22
21
  this.#parsedTrace = focus.data.parsedTrace;
23
22
  this.#insightSet = focus.data.insightSet;
24
- this.#traceMetadata = focus.data.traceMetadata;
25
23
  this.#eventsSerializer = eventsSerializer;
26
24
  }
27
25
 
@@ -37,7 +35,8 @@ export class PerformanceTraceFormatter {
37
35
  formatTraceSummary(): string {
38
36
  const parsedTrace = this.#parsedTrace;
39
37
  const insightSet = this.#insightSet;
40
- const traceMetadata = this.#traceMetadata;
38
+ const traceMetadata = this.#parsedTrace.metadata;
39
+ const data = parsedTrace.data;
41
40
 
42
41
  const parts = [];
43
42
 
@@ -45,8 +44,8 @@ export class PerformanceTraceFormatter {
45
44
  const cls = insightSet ? Trace.Insights.Common.getCLS(insightSet) : null;
46
45
  const inp = insightSet ? Trace.Insights.Common.getINP(insightSet) : null;
47
46
 
48
- parts.push(`URL: ${parsedTrace.Meta.mainFrameURL}`);
49
- parts.push(`Bounds: ${this.serializeBounds(parsedTrace.Meta.traceBounds)}`);
47
+ parts.push(`URL: ${data.Meta.mainFrameURL}`);
48
+ parts.push(`Bounds: ${this.serializeBounds(data.Meta.traceBounds)}`);
50
49
  parts.push('CPU throttling: ' + (traceMetadata.cpuThrottling ? `${traceMetadata.cpuThrottling}x` : 'none'));
51
50
  parts.push(`Network throttling: ${traceMetadata.networkThrottling ?? 'none'}`);
52
51
  if (lcp || cls || inp) {
@@ -178,7 +177,7 @@ export class PerformanceTraceFormatter {
178
177
  const parsedTrace = this.#parsedTrace;
179
178
  const insightSet = this.#insightSet;
180
179
 
181
- const bounds = parsedTrace.Meta.traceBounds;
180
+ const bounds = parsedTrace.data.Meta.traceBounds;
182
181
  const rootNode = TimelineUtils.InsightAIContext.AIQueries.mainThreadActivityBottomUp(
183
182
  insightSet?.navigation?.args.data?.navigationId,
184
183
  bounds,
@@ -231,7 +230,7 @@ export class PerformanceTraceFormatter {
231
230
  const parsedTrace = this.#parsedTrace;
232
231
  const insightSet = this.#insightSet;
233
232
 
234
- const bounds = parsedTrace.Meta.traceBounds;
233
+ const bounds = parsedTrace.data.Meta.traceBounds;
235
234
  const longestTaskTrees = TimelineUtils.InsightAIContext.AIQueries.longestTasks(
236
235
  insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
237
236
  if (!longestTaskTrees || longestTaskTrees.length === 0) {
@@ -312,7 +311,7 @@ export class PerformanceTraceFormatter {
312
311
  results.push(this.#serializeBottomUpRootNode(bottomUpRootNode, 20));
313
312
  }
314
313
 
315
- const thirdPartySummaries = Trace.Extras.ThirdParties.summarizeByThirdParty(this.#parsedTrace, bounds);
314
+ const thirdPartySummaries = Trace.Extras.ThirdParties.summarizeByThirdParty(this.#parsedTrace.data, bounds);
316
315
  if (thirdPartySummaries.length) {
317
316
  results.push('# Third parties');
318
317
  results.push(this.#formatThirdPartyEntitySummaries(thirdPartySummaries));
@@ -337,7 +336,7 @@ export class PerformanceTraceFormatter {
337
336
  formatNetworkTrackSummary(bounds: Trace.Types.Timing.TraceWindowMicro): string {
338
337
  const results = [];
339
338
 
340
- const requests = this.#parsedTrace.NetworkRequests.byTime.filter(
339
+ const requests = this.#parsedTrace.data.NetworkRequests.byTime.filter(
341
340
  request => Trace.Helpers.Timing.eventIsInBounds(request, bounds));
342
341
  const requestsText = TraceEventFormatter.networkRequests(requests, this.#parsedTrace, {verbose: false});
343
342
  results.push('# Network requests summary');
@@ -0,0 +1,21 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import {Badge, type BadgeAction} from './Badge.js';
6
+
7
+ const AI_EXPLORER_BADGE_URI = new URL('../../Images/ai-explorer-badge.svg', import.meta.url).toString();
8
+ export class AiExplorerBadge extends Badge {
9
+ override readonly name =
10
+ 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fai-explorer';
11
+ override readonly title = 'AI Explorer';
12
+ override readonly imageUri = AI_EXPLORER_BADGE_URI;
13
+
14
+ override readonly interestedActions = [
15
+ // TODO(ergunsh): Instrument related actions.
16
+ ] as const;
17
+
18
+ handleAction(_action: BadgeAction): void {
19
+ this.trigger();
20
+ }
21
+ }
@@ -5,9 +5,11 @@
5
5
  import * as Common from '../../core/common/common.js';
6
6
 
7
7
  export enum BadgeAction {
8
+ GDP_SIGN_UP_COMPLETE = 'gdp-sign-up-complete',
8
9
  CSS_RULE_MODIFIED = 'css-rule-modified',
9
10
  DOM_ELEMENT_OR_ATTRIBUTE_EDITED = 'dom-element-or-attribute-edited',
10
11
  MODERN_DOM_BADGE_CLICKED = 'modern-dom-badge-clicked',
12
+ // TODO(ergunsh): Instrument performance insight clicks.
11
13
  PERFORMANCE_INSIGHT_CLICKED = 'performance-insight-clicked',
12
14
  }
13
15
 
@@ -47,11 +49,6 @@ export abstract class Badge {
47
49
  }
48
50
 
49
51
  activate(): void {
50
- // We don't reactivate a badge that's triggered before.
51
- if (this.#triggeredBefore) {
52
- return;
53
- }
54
-
55
52
  // The event listeners are already registered, we don't re-register them.
56
53
  if (this.#eventListeners.length > 0) {
57
54
  return;
@@ -70,5 +67,6 @@ export abstract class Badge {
70
67
 
71
68
  Common.EventTarget.removeEventListeners(this.#eventListeners);
72
69
  this.#eventListeners = [];
70
+ this.#triggeredBefore = false;
73
71
  }
74
72
  }
@@ -0,0 +1,21 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import {Badge, type BadgeAction} from './Badge.js';
6
+
7
+ const CODE_WHISPERER_BADGE_IMAGE_URI = new URL('../../Images/code-whisperer-badge.svg', import.meta.url).toString();
8
+ export class CodeWhispererBadge extends Badge {
9
+ override readonly name =
10
+ 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fcode-whisperer';
11
+ override readonly title = 'Code Whisperer';
12
+ override readonly imageUri = CODE_WHISPERER_BADGE_IMAGE_URI;
13
+
14
+ override readonly interestedActions = [
15
+ // TODO(ergunsh): Instrument related actions.
16
+ ] as const;
17
+
18
+ handleAction(_action: BadgeAction): void {
19
+ this.trigger();
20
+ }
21
+ }
@@ -4,14 +4,15 @@
4
4
 
5
5
  import {Badge, BadgeAction} from './Badge.js';
6
6
 
7
- const DOM_DETECTIVE_BADGE_IMAGE_URI = new URL('../../Images/gdp-logo-standalone.svg', import.meta.url).toString();
7
+ const DOM_DETECTIVE_BADGE_IMAGE_URI = new URL('../../Images/dom-detective-badge.svg', import.meta.url).toString();
8
8
  export class DOMDetectiveBadge extends Badge {
9
- override readonly name = 'awards/dom-detective-badge';
9
+ override readonly name =
10
+ 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fdom-detective';
10
11
  override readonly title = 'DOM Detective';
11
12
  override readonly imageUri = DOM_DETECTIVE_BADGE_IMAGE_URI;
12
13
 
13
14
  override readonly interestedActions = [
14
- BadgeAction.DOM_ELEMENT_OR_ATTRIBUTE_EDITED,
15
+ BadgeAction.MODERN_DOM_BADGE_CLICKED,
15
16
  ] as const;
16
17
 
17
18
  handleAction(_action: BadgeAction): void {
@@ -4,12 +4,14 @@
4
4
 
5
5
  import {Badge, BadgeAction} from './Badge.js';
6
6
 
7
- const SPEEDSTER_BADGE_URI = new URL('../../Images/gdp-logo-standalone.svg', import.meta.url).toString();
7
+ const SPEEDSTER_BADGE_URI = new URL('../../Images/speedster-badge.svg', import.meta.url).toString();
8
8
  export class SpeedsterBadge extends Badge {
9
- // TODO(ergunsh): Update the name to be the actual badge for DevTools.
10
- override readonly name = 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Flegacy%2Ftest';
9
+ override readonly name =
10
+ 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fspeedster';
11
11
  override readonly title = 'Speedster';
12
- override readonly interestedActions = [BadgeAction.PERFORMANCE_INSIGHT_CLICKED] as const;
12
+ override readonly interestedActions = [
13
+ BadgeAction.PERFORMANCE_INSIGHT_CLICKED,
14
+ ] as const;
13
15
  override readonly imageUri = SPEEDSTER_BADGE_URI;
14
16
 
15
17
  handleAction(_action: BadgeAction): void {
@@ -4,16 +4,17 @@
4
4
 
5
5
  import {Badge, BadgeAction} from './Badge.js';
6
6
 
7
- const STARTER_BADGE_IMAGE_URI = new URL('../../Images/gdp-logo-standalone.svg', import.meta.url).toString();
7
+ const STARTER_BADGE_IMAGE_URI = new URL('../../Images/devtools-user-badge.svg', import.meta.url).toString();
8
8
  export class StarterBadge extends Badge {
9
9
  override readonly isStarterBadge = true;
10
- // TODO(ergunsh): Update the name to be the actual badge for DevTools.
11
- override readonly name = 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Fprofile%2Fcreated-profile';
10
+ override readonly name =
11
+ 'profiles/me/awards/developers.google.com%2Fprofile%2Fbadges%2Factivity%2Fchrome-devtools%2Fchrome-devtools-user';
12
12
  override readonly title = 'Chrome DevTools User';
13
13
  override readonly imageUri = STARTER_BADGE_IMAGE_URI;
14
14
 
15
15
  // TODO(ergunsh): Add remaining non-trivial event definitions
16
16
  override readonly interestedActions = [
17
+ BadgeAction.GDP_SIGN_UP_COMPLETE,
17
18
  BadgeAction.CSS_RULE_MODIFIED,
18
19
  BadgeAction.DOM_ELEMENT_OR_ATTRIBUTE_EDITED,
19
20
  ] as const;
@@ -5,7 +5,9 @@
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
 
8
+ import {AiExplorerBadge} from './AiExplorerBadge.js';
8
9
  import type {Badge, BadgeAction, BadgeActionEvents, BadgeContext} from './Badge.js';
10
+ import {CodeWhispererBadge} from './CodeWhispererBadge.js';
9
11
  import {DOMDetectiveBadge} from './DOMDetectiveBadge.js';
10
12
  import {SpeedsterBadge} from './SpeedsterBadge.js';
11
13
  import {StarterBadge} from './StarterBadge.js';
@@ -31,6 +33,8 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
31
33
  StarterBadge,
32
34
  SpeedsterBadge,
33
35
  DOMDetectiveBadge,
36
+ CodeWhispererBadge,
37
+ AiExplorerBadge,
34
38
  ];
35
39
 
36
40
  private constructor() {
@@ -98,7 +102,6 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
98
102
  }
99
103
 
100
104
  // TODO(ergunsh): Implement starter badge dismissal, snooze count & timestamp checks.
101
- // TODO(ergunsh): Implement checking for previously awarded badges.
102
105
  async #reconcileBadges(): Promise<void> {
103
106
  const syncInfo = await new Promise<Host.InspectorFrontendHostAPI.SyncInformation>(
104
107
  resolve => Host.InspectorFrontendHost.InspectorFrontendHostInstance.getSyncInformation(resolve));
@@ -120,8 +123,31 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
120
123
  return;
121
124
  }
122
125
 
123
- const receiveBadgesSettingEnabled = Boolean(this.#receiveBadgesSetting?.get());
126
+ let awardedBadgeNames: Set<string>|null = null;
127
+ if (gdpProfile) {
128
+ awardedBadgeNames = await Host.GdpClient.GdpClient.instance().getAwardedBadgeNames(
129
+ {names: this.#allBadges.map(badge => badge.name)});
130
+ // This is a conservative approach. We bail out if `awardedBadgeNames` is null
131
+ // when there is a profile to prevent a negative user experience.
132
+ //
133
+ // A failure here (e.g., from a typo in a badge name) could cause us to
134
+ // re-trigger the "Receive badges" nudge for a user who has already earned the
135
+ // starter badge and opted out of receiving badges.
136
+ //
137
+ // The trade-off is, we silently failing to enable badge mechanism rather than annoying the user.
138
+ if (!awardedBadgeNames) {
139
+ this.#deactivateAllBadges();
140
+ return;
141
+ }
142
+ }
143
+
144
+ const receiveBadgesSettingEnabled = Boolean(this.#receiveBadgesSetting.get());
124
145
  for (const badge of this.#allBadges) {
146
+ if (awardedBadgeNames?.has(badge.name)) {
147
+ badge.deactivate();
148
+ continue;
149
+ }
150
+
125
151
  const shouldActivateStarterBadge = badge.isStarterBadge && isEligibleToCreateProfile;
126
152
  const shouldActivateActivityBasedBadge =
127
153
  !badge.isStarterBadge && Boolean(gdpProfile) && receiveBadgesSettingEnabled;
@@ -139,6 +165,6 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
139
165
  }
140
166
 
141
167
  isReceiveBadgesSettingEnabled(): boolean {
142
- return Boolean(this.#receiveBadgesSetting?.get());
168
+ return Boolean(this.#receiveBadgesSetting.get());
143
169
  }
144
170
  }
@@ -283,7 +283,7 @@ export class LiveLocation extends LiveLocationWithPool {
283
283
  readonly #lineNumber: number;
284
284
  readonly #columnNumber: number;
285
285
  readonly #info: ModelInfo;
286
- headerInternal: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null;
286
+ #header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null;
287
287
  constructor(
288
288
  rawLocation: SDK.CSSModel.CSSLocation, info: ModelInfo,
289
289
  updateDelegate: (arg0: LiveLocationInterface) => Promise<void>, locationPool: LiveLocationPool) {
@@ -292,22 +292,22 @@ export class LiveLocation extends LiveLocationWithPool {
292
292
  this.#lineNumber = rawLocation.lineNumber;
293
293
  this.#columnNumber = rawLocation.columnNumber;
294
294
  this.#info = info;
295
- this.headerInternal = null;
295
+ this.#header = null;
296
296
  }
297
297
 
298
298
  header(): SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null {
299
- return this.headerInternal;
299
+ return this.#header;
300
300
  }
301
301
 
302
302
  setHeader(header: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null): void {
303
- this.headerInternal = header;
303
+ this.#header = header;
304
304
  }
305
305
 
306
306
  override async uiLocation(): Promise<Workspace.UISourceCode.UILocation|null> {
307
- if (!this.headerInternal) {
307
+ if (!this.#header) {
308
308
  return null;
309
309
  }
310
- const rawLocation = new SDK.CSSModel.CSSLocation(this.headerInternal, this.#lineNumber, this.#columnNumber);
310
+ const rawLocation = new SDK.CSSModel.CSSLocation(this.#header, this.#lineNumber, this.#columnNumber);
311
311
  return CSSWorkspaceBinding.instance().rawLocationToUILocation(rawLocation);
312
312
  }
313
313