chrome-devtools-frontend 1.0.1662289 → 1.0.1664496

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 (319) hide show
  1. package/.agents/skills/{creating-a-model → devtools-model-management}/SKILL.md +0 -1
  2. package/.agents/skills/devtools-unicode-escaping/SKILL.md +64 -0
  3. package/.agents/skills/devtools-ux-writing-refactor/SKILL.md +2 -1
  4. package/.agents/skills/fixing-skipped-tests/SKILL.md +3 -3
  5. package/.agents/skills/merging-devtools-module/SKILL.md +1 -1
  6. package/.agents/skills/migrate-chromium-test/SKILL.md +32 -6
  7. package/.agents/skills/repro-flaky-tests/SKILL.md +71 -31
  8. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +1 -0
  9. package/docs/ui_engineering.md +2 -0
  10. package/eslint.config.mjs +1 -0
  11. package/front_end/core/common/SettingRegistration.ts +0 -5
  12. package/front_end/core/common/Settings.ts +144 -3
  13. package/front_end/core/platform/StringUtilities.ts +38 -6
  14. package/front_end/core/protocol_client/PuppeteerDevToolsConnection.ts +112 -0
  15. package/front_end/core/sdk/CPUProfilerModel.ts +21 -13
  16. package/front_end/core/sdk/CSSContainerQuery.ts +1 -1
  17. package/front_end/core/sdk/CSSLayer.ts +1 -1
  18. package/front_end/core/sdk/CSSMedia.ts +1 -1
  19. package/front_end/core/sdk/CSSModel.ts +1 -1
  20. package/front_end/core/sdk/CSSNavigation.ts +1 -1
  21. package/front_end/core/sdk/CSSProperty.ts +1 -1
  22. package/front_end/core/sdk/CSSQuery.ts +1 -1
  23. package/front_end/core/sdk/CSSRule.ts +1 -1
  24. package/front_end/core/sdk/CSSScope.ts +1 -1
  25. package/front_end/core/sdk/CSSStartingStyle.ts +1 -1
  26. package/front_end/core/sdk/CSSStyleDeclaration.ts +1 -1
  27. package/front_end/core/sdk/CSSStyleSheetHeader.ts +1 -1
  28. package/front_end/core/sdk/CSSSupports.ts +1 -1
  29. package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +1 -1
  30. package/front_end/core/sdk/NetworkManager.ts +1 -1
  31. package/front_end/core/sdk/NetworkRequest.ts +7 -7
  32. package/front_end/core/sdk/Resource.ts +1 -1
  33. package/front_end/core/sdk/ScopeTreeCache.ts +1 -1
  34. package/front_end/core/sdk/Script.ts +1 -1
  35. package/front_end/core/sdk/ServerSentEvents.ts +1 -1
  36. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -10
  37. package/front_end/core/sdk/SourceMap.ts +1 -1
  38. package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
  39. package/front_end/core/sdk/StorageBucketsModel.ts +0 -10
  40. package/front_end/core/sdk/sdk-meta.ts +3 -4
  41. package/front_end/{models → core}/text_utils/ContentProvider.ts +4 -6
  42. package/front_end/{models → core}/text_utils/StaticContentProvider.ts +4 -6
  43. package/front_end/{models → core}/text_utils/StreamingContentData.ts +1 -2
  44. package/front_end/{models → core}/text_utils/TextRange.ts +6 -3
  45. package/front_end/{models → core}/text_utils/TextUtils.ts +7 -7
  46. package/front_end/{models → core}/text_utils/WasmDisassembly.ts +2 -2
  47. package/front_end/core/text_utils/text_utils.ts +27 -0
  48. package/front_end/entrypoints/formatter_worker/AcornTokenizer.ts +1 -1
  49. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +1 -1
  50. package/front_end/entrypoints/inspector_main/OutermostTargetSelector.ts +0 -13
  51. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +8 -3
  52. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +3 -3
  53. package/front_end/entrypoints/main/MainImpl.ts +21 -3
  54. package/front_end/foundation/Universe.ts +16 -0
  55. package/front_end/generated/InspectorBackendCommands.ts +2 -14
  56. package/front_end/generated/protocol-mapping.d.ts +0 -53
  57. package/front_end/generated/protocol-proxy-api.d.ts +0 -46
  58. package/front_end/generated/protocol.ts +0 -148
  59. package/front_end/models/ai_assistance/AgentProject.ts +1 -1
  60. package/front_end/models/ai_assistance/AiAgent2.ts +3 -3
  61. package/front_end/models/ai_assistance/AiConversation.ts +21 -10
  62. package/front_end/models/ai_assistance/AiHistoryStorage.ts +21 -10
  63. package/front_end/models/ai_assistance/ChangeManager.ts +2 -2
  64. package/front_end/models/ai_assistance/ExtensionScope.ts +6 -2
  65. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +4 -7
  66. package/front_end/models/ai_assistance/agents/AiAgent.ts +9 -2
  67. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +19 -11
  68. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +2 -2
  69. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +23 -10
  70. package/front_end/models/ai_assistance/agents/StorageAgent.ts +19 -18
  71. package/front_end/models/ai_assistance/agents/StylingAgent.ts +3 -4
  72. package/front_end/models/ai_assistance/contexts/FileContext.ts +7 -3
  73. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +39 -11
  74. package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +6 -3
  75. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +1 -1
  76. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +4 -4
  77. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +8 -8
  78. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +76 -3
  79. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +11 -1
  80. package/front_end/models/badges/AiExplorerBadge.ts +8 -3
  81. package/front_end/models/badges/Badge.ts +1 -0
  82. package/front_end/models/badges/UserBadges.ts +43 -23
  83. package/front_end/models/bindings/CompilerScriptMapping.ts +1 -1
  84. package/front_end/models/bindings/ContentProviderBasedProject.ts +1 -1
  85. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +2 -2
  86. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +1 -1
  87. package/front_end/models/bindings/DefaultScriptMapping.ts +1 -1
  88. package/front_end/models/bindings/FileUtils.ts +1 -1
  89. package/front_end/models/bindings/NetworkProject.ts +16 -4
  90. package/front_end/models/bindings/PresentationConsoleMessageHelper.ts +7 -10
  91. package/front_end/models/bindings/ResourceMapping.ts +1 -1
  92. package/front_end/models/bindings/ResourceScriptMapping.ts +1 -1
  93. package/front_end/models/bindings/SASSSourceMapping.ts +1 -1
  94. package/front_end/models/bindings/StylesSourceMapping.ts +1 -1
  95. package/front_end/models/breakpoints/BreakpointManager.ts +1 -1
  96. package/front_end/models/crux-manager/CrUXManager.ts +1 -1
  97. package/front_end/models/emulation/DeviceModeModel.ts +67 -5
  98. package/front_end/models/emulation/EmulatedDevices.ts +3 -2
  99. package/front_end/models/extensions/RecorderPluginManager.ts +10 -6
  100. package/front_end/models/har/Importer.ts +1 -1
  101. package/front_end/models/har/Log.snapshot.txt +193 -0
  102. package/front_end/models/har/Log.ts +3 -2
  103. package/front_end/models/har/Writer.ts +1 -1
  104. package/front_end/models/issues_manager/IssueAggregator.ts +9 -0
  105. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  106. package/front_end/models/issues_manager/LazyLoadImageIssue.ts +76 -0
  107. package/front_end/models/issues_manager/descriptions/lazyLoadImageZeroSize.md +7 -0
  108. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  109. package/front_end/models/javascript_metadata/NativeFunctions.js +9 -10
  110. package/front_end/models/live-metrics/LiveMetrics.ts +2 -3
  111. package/front_end/models/logs/NetworkLog.ts +4 -3
  112. package/front_end/models/logs/logs-meta.ts +3 -3
  113. package/front_end/models/network_time_calculator/NetworkTimeCalculator.ts +4 -4
  114. package/front_end/models/persistence/Automapping.ts +1 -1
  115. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +2 -2
  116. package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +1 -1
  117. package/front_end/models/persistence/IsolatedFileSystem.ts +2 -2
  118. package/front_end/models/persistence/NetworkPersistenceManager.ts +1 -1
  119. package/front_end/models/persistence/PersistenceImpl.ts +1 -1
  120. package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
  121. package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +8 -6
  122. package/front_end/models/source_map_scopes/NamesResolver.ts +37 -31
  123. package/front_end/models/stack_trace/StackTrace.ts +17 -0
  124. package/front_end/models/text_utils/text_utils.ts +2 -24
  125. package/front_end/models/trace/insights/ImageDelivery.ts +2 -2
  126. package/front_end/models/trace/insights/LegacyJavaScript.ts +1 -1
  127. package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
  128. package/front_end/models/trace/insights/ThirdParties.ts +1 -1
  129. package/front_end/models/workspace/FileManager.ts +1 -1
  130. package/front_end/models/workspace/UISourceCode.ts +1 -1
  131. package/front_end/models/workspace/WorkspaceImpl.ts +1 -1
  132. package/front_end/models/workspace_diff/WorkspaceDiff.ts +1 -1
  133. package/front_end/panels/accessibility/AccessibilityNodeView.ts +1 -1
  134. package/front_end/panels/accessibility/AccessibilityStrings.ts +2 -2
  135. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +1 -1
  136. package/front_end/panels/ai_assistance/ExportConversation.ts +1 -1
  137. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +1 -1
  138. package/front_end/panels/ai_assistance/components/ChatMessage.ts +1 -1
  139. package/front_end/panels/application/AppManifestView.ts +4 -4
  140. package/front_end/panels/application/ApplicationPanelSidebar.ts +1 -2
  141. package/front_end/panels/application/CrashReportContextView.ts +1 -1
  142. package/front_end/panels/application/DOMStorageItemsView.ts +1 -1
  143. package/front_end/panels/application/DeviceBoundSessionsView.ts +4 -4
  144. package/front_end/panels/application/ExtensionStorageItemsView.ts +1 -1
  145. package/front_end/panels/application/FrameDetailsView.ts +1 -1
  146. package/front_end/panels/application/IndexedDBModel.ts +0 -10
  147. package/front_end/panels/application/IndexedDBViews.ts +240 -164
  148. package/front_end/panels/application/ServiceWorkerCacheTreeElement.ts +12 -2
  149. package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
  150. package/front_end/panels/application/SharedStorageModel.ts +0 -10
  151. package/front_end/panels/application/application.ts +2 -0
  152. package/front_end/panels/application/components/AdsView.ts +23 -0
  153. package/front_end/panels/application/components/BackForwardCacheView.ts +21 -5
  154. package/front_end/panels/application/components/CrashReportContextGrid.ts +1 -1
  155. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +1 -1
  156. package/front_end/panels/application/components/TrustTokensView.ts +2 -2
  157. package/front_end/panels/application/components/adsView.css +21 -1
  158. package/front_end/panels/application/indexedDBViews.css +1 -1
  159. package/front_end/panels/application/preloading/PreloadingView.ts +1 -1
  160. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -2
  161. package/front_end/panels/application/preloading/components/PreloadingString.ts +2 -2
  162. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +4 -4
  163. package/front_end/panels/autofill/AutofillView.ts +1 -1
  164. package/front_end/panels/common/AiCodeCompletionTeaser.ts +1 -1
  165. package/front_end/panels/common/ExtensionServer.ts +1 -1
  166. package/front_end/panels/console/ConsoleFilter.ts +1 -1
  167. package/front_end/panels/console/ConsoleSidebar.ts +1 -1
  168. package/front_end/panels/console/ConsoleView.ts +1 -1
  169. package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
  170. package/front_end/panels/console/PromptBuilder.ts +1 -1
  171. package/front_end/panels/coverage/CoverageDecorationManager.ts +9 -1
  172. package/front_end/panels/coverage/CoverageModel.ts +1 -1
  173. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +1 -1
  174. package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
  175. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +1 -1
  176. package/front_end/panels/elements/AccessibilityTreeView.ts +38 -3
  177. package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +1 -1
  178. package/front_end/panels/elements/ElementIssueUtils.ts +2 -2
  179. package/front_end/panels/elements/ElementsTreeElement.ts +10 -3
  180. package/front_end/panels/elements/StandaloneStylesContainer.ts +1 -1
  181. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  182. package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
  183. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +1 -1
  184. package/front_end/panels/elements/StylesContainer.ts +1 -1
  185. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  186. package/front_end/panels/elements/components/CSSPropertyDocsView.ts +1 -1
  187. package/front_end/panels/explain/components/ConsoleInsight.ts +2 -2
  188. package/front_end/panels/issues/AffectedLazyLoadImagesView.ts +76 -0
  189. package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
  190. package/front_end/panels/issues/CorsIssueDetailsView.ts +1 -1
  191. package/front_end/panels/issues/IssueView.ts +2 -0
  192. package/front_end/panels/issues/issues.ts +2 -0
  193. package/front_end/panels/layer_viewer/Layers3DView.ts +1 -1
  194. package/front_end/panels/lighthouse/LighthouseController.ts +5 -0
  195. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +1 -1
  196. package/front_end/panels/network/BinaryResourceView.ts +1 -1
  197. package/front_end/panels/network/NetworkDataGridNode.ts +72 -8
  198. package/front_end/panels/network/NetworkLogView.ts +1 -1
  199. package/front_end/panels/network/NetworkLogViewColumns.ts +6 -6
  200. package/front_end/panels/network/NetworkPanel.ts +4 -4
  201. package/front_end/panels/network/NetworkSearchScope.ts +1 -1
  202. package/front_end/panels/network/RequestConditionsDrawer.ts +1 -1
  203. package/front_end/panels/network/RequestHTMLView.ts +1 -1
  204. package/front_end/panels/network/RequestInitiatorView.ts +24 -2
  205. package/front_end/panels/network/RequestPayloadView.ts +1 -1
  206. package/front_end/panels/network/RequestPreviewView.ts +1 -1
  207. package/front_end/panels/network/RequestResponseView.ts +1 -1
  208. package/front_end/panels/network/ResourceChunkView.ts +1 -1
  209. package/front_end/panels/network/ResourceDirectSocketChunkView.ts +1 -1
  210. package/front_end/panels/network/ResourceWebSocketFrameView.ts +1 -1
  211. package/front_end/panels/network/components/ResponseHeaderSection.ts +1 -1
  212. package/front_end/panels/network/forward/UIRequestLocation.ts +1 -1
  213. package/front_end/panels/network/network-meta.ts +3 -3
  214. package/front_end/panels/network/networkLogView.css +5 -0
  215. package/front_end/panels/network/requestInitiatorViewTree.css +5 -0
  216. package/front_end/panels/profiler/HeapProfileView.ts +200 -81
  217. package/front_end/panels/profiler/HeapSnapshotView.ts +1 -1
  218. package/front_end/panels/profiler/ProfileDataGrid.ts +12 -8
  219. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +1 -1
  220. package/front_end/panels/recorder/README.md +1 -2
  221. package/front_end/panels/recorder/RecorderPanel.ts +1861 -17
  222. package/front_end/panels/recorder/RecordingListView.ts +8 -37
  223. package/front_end/panels/recorder/RecordingView.ts +54 -27
  224. package/front_end/panels/recorder/SelectorPicker.ts +0 -13
  225. package/front_end/panels/recorder/StepEditor.ts +6 -14
  226. package/front_end/panels/recorder/StepView.ts +36 -105
  227. package/front_end/panels/recorder/recorder.ts +0 -2
  228. package/front_end/panels/search/SearchResultsPane.ts +1 -1
  229. package/front_end/panels/security/SecurityPanel.ts +3 -3
  230. package/front_end/panels/settings/AISettingsTab.ts +17 -4
  231. package/front_end/panels/settings/components/SyncSection.ts +4 -4
  232. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +3 -3
  233. package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +1 -1
  234. package/front_end/panels/sources/BreakpointsView.ts +1 -1
  235. package/front_end/panels/sources/CoveragePlugin.ts +1 -1
  236. package/front_end/panels/sources/DebuggerPlugin.ts +4 -4
  237. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +27 -3
  238. package/front_end/panels/sources/NavigatorView.ts +1 -1
  239. package/front_end/panels/sources/PersistenceActions.ts +1 -1
  240. package/front_end/panels/sources/SourcesNavigator.ts +1 -1
  241. package/front_end/panels/sources/SourcesSearchScope.ts +1 -1
  242. package/front_end/panels/sources/TabbedEditorContainer.ts +3 -3
  243. package/front_end/panels/sources/UISourceCodeFrame.ts +1 -1
  244. package/front_end/panels/sources/components/HeadersView.ts +1 -1
  245. package/front_end/panels/sources/filteredUISourceCodeListProvider.css +12 -1
  246. package/front_end/panels/sources/sources-meta.ts +1 -1
  247. package/front_end/panels/timeline/StatusDialog.ts +1 -1
  248. package/front_end/panels/timeline/TimelineController.ts +24 -3
  249. package/front_end/panels/timeline/TimelinePanel.ts +116 -25
  250. package/front_end/panels/timeline/TimelineSelectorStatsView.ts +2 -2
  251. package/front_end/panels/timeline/TimelineUIUtils.ts +1 -1
  252. package/front_end/panels/timeline/components/CWVMetrics.ts +1 -1
  253. package/front_end/panels/timeline/components/IgnoreListSetting.ts +1 -1
  254. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -2
  255. package/front_end/panels/timeline/timeline-meta.ts +13 -0
  256. package/front_end/services/tracing/TracingManager.ts +27 -2
  257. package/front_end/third_party/chromium/README.chromium +1 -1
  258. package/front_end/third_party/lighthouse/README.chromium +2 -2
  259. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1418 -1413
  260. package/front_end/third_party/lighthouse/locales/en-US.json +12 -6
  261. package/front_end/third_party/lighthouse/locales/en-XL.json +12 -6
  262. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +1 -1
  263. package/front_end/third_party/puppeteer/puppeteer.ts +20 -1
  264. package/front_end/ui/components/highlighting/HighlightElement.ts +4 -1
  265. package/front_end/ui/components/highlighting/HighlightManager.ts +1 -1
  266. package/front_end/ui/components/highlighting/MarkupHighlight.ts +1 -1
  267. package/front_end/ui/components/markdown_view/MarkdownView.ts +46 -2
  268. package/front_end/ui/components/markdown_view/markdownView.css +23 -0
  269. package/front_end/ui/components/spinners/Spinner.ts +29 -32
  270. package/front_end/ui/components/spinners/spinner.css +32 -84
  271. package/front_end/ui/components/text_editor/config.ts +1 -1
  272. package/front_end/ui/components/tree_outline/TreeOutline.ts +7 -1
  273. package/front_end/ui/legacy/Infobar.ts +1 -1
  274. package/front_end/ui/legacy/InspectorView.ts +12 -7
  275. package/front_end/ui/legacy/SuggestBox.ts +1 -1
  276. package/front_end/ui/legacy/TextPrompt.ts +1 -1
  277. package/front_end/ui/legacy/Toolbar.ts +5 -2
  278. package/front_end/ui/legacy/Treeoutline.ts +40 -13
  279. package/front_end/ui/legacy/UIUtils.ts +25 -10
  280. package/front_end/ui/legacy/Widget.ts +17 -10
  281. package/front_end/ui/legacy/components/color_picker/Spectrum.ts +1 -1
  282. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +37 -8
  283. package/front_end/ui/legacy/components/data_grid/ViewportDataGrid.ts +1 -1
  284. package/front_end/ui/legacy/components/data_grid/dataGrid.css +1 -1
  285. package/front_end/ui/legacy/components/inline_editor/AnimationTimingUI.ts +27 -13
  286. package/front_end/ui/legacy/components/inline_editor/BezierEditor.ts +5 -2
  287. package/front_end/ui/legacy/components/inline_editor/CSSLinearEasingModel.ts +23 -0
  288. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +223 -121
  289. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +1 -1
  290. package/front_end/ui/legacy/components/object_ui/objectValue.css +2 -1
  291. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +1 -1
  292. package/front_end/ui/legacy/components/source_frame/BinaryResourceViewFactory.ts +1 -1
  293. package/front_end/ui/legacy/components/source_frame/FontView.ts +1 -1
  294. package/front_end/ui/legacy/components/source_frame/ImageView.ts +1 -1
  295. package/front_end/ui/legacy/components/source_frame/JSONView.ts +105 -115
  296. package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +1 -1
  297. package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +1 -1
  298. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +3 -3
  299. package/front_end/ui/legacy/components/source_frame/StreamingContentHexView.ts +1 -1
  300. package/front_end/ui/legacy/components/source_frame/XMLView.ts +5 -1
  301. package/front_end/ui/legacy/components/source_frame/jsonView.css +4 -0
  302. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -1
  303. package/front_end/ui/legacy/inspectorCommon.css +10 -6
  304. package/front_end/ui/lit/lit.ts +1 -0
  305. package/front_end/ui/lit/render.ts +44 -10
  306. package/front_end/ui/lit/strip-whitespace.ts +23 -2
  307. package/front_end/ui/settings/SettingUIRegistration.ts +105 -0
  308. package/front_end/ui/settings/settings.ts +9 -0
  309. package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
  310. package/mcp/mcp.ts +1 -0
  311. package/package.json +1 -1
  312. package/front_end/panels/recorder/RecorderController.ts +0 -1759
  313. /package/.agents/skills/{verification → devtools-verification}/SKILL.md +0 -0
  314. /package/front_end/{models → core}/text_utils/CodeMirrorUtils.ts +0 -0
  315. /package/front_end/{models → core}/text_utils/ContentData.ts +0 -0
  316. /package/front_end/{models → core}/text_utils/Text.ts +0 -0
  317. /package/front_end/{models → core}/text_utils/TextCursor.ts +0 -0
  318. /package/front_end/{models → core}/text_utils/TextUtils.snapshot.txt +0 -0
  319. /package/front_end/panels/recorder/{recorderController.css → recorderPanel.css} +0 -0
@@ -3,6 +3,8 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
5
 
6
+ import '../../ui/components/icon_button/icon_button.js';
7
+
6
8
  import * as Common from '../../core/common/common.js';
7
9
  import * as Host from '../../core/host/host.js';
8
10
  import * as i18n from '../../core/i18n/i18n.js';
@@ -12,12 +14,12 @@ import type * as Protocol from '../../generated/protocol.js';
12
14
  import * as Bindings from '../../models/bindings/bindings.js';
13
15
  import * as CPUProfile from '../../models/cpu_profile/cpu_profile.js';
14
16
  import * as Buttons from '../../ui/components/buttons/buttons.js';
15
- import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
17
+ import type * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
16
18
  import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
17
19
  import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.js';
18
20
  import * as Components from '../../ui/legacy/components/utils/utils.js';
19
21
  import * as UI from '../../ui/legacy/legacy.js';
20
- import {Directives, html, nothing, type TemplateResult} from '../../ui/lit/lit.js';
22
+ import {Directives, html, nothing, render, type TemplateResult} from '../../ui/lit/lit.js';
21
23
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
22
24
 
23
25
  import {BottomUpProfileDataGridTree} from './BottomUpProfileDataGrid.js';
@@ -28,6 +30,8 @@ import {ProfileEvents, type ProfileHeader, ProfileType} from './ProfileHeader.js
28
30
  import {TopDownProfileDataGridTree} from './TopDownProfileDataGrid.js';
29
31
  import {WritableProfileHeader} from './WritableProfileHeader.js';
30
32
 
33
+ const {repeat, ref} = Directives;
34
+
31
35
  const UIStrings = {
32
36
  /**
33
37
  * @description The reported total size used in the selected time frame of the allocation sampling profile
@@ -160,11 +164,15 @@ const UIStrings = {
160
164
  * @description Text for selecting different profile views in the JS profiler tool. This option is a tree view.
161
165
  */
162
166
  treeTopDown: 'Tree (Top Down)',
167
+
168
+ /**
169
+ * @description Tooltip to alert developers that some parts of code in execution were not optimized.
170
+ * @example {Optimized too many times} PH1
171
+ */
172
+ notOptimizedS: 'Not optimized: {PH1}',
163
173
  } as const;
164
174
  const str_ = i18n.i18n.registerUIStrings('panels/profiler/HeapProfileView.ts', UIStrings);
165
175
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
166
- const {ref} = Directives;
167
-
168
176
  function convertToSamplingHeapProfile(profileHeader: SamplingHeapProfileHeader):
169
177
  Protocol.HeapProfiler.SamplingHeapProfile {
170
178
  return (profileHeader.profile || profileHeader.protocolProfile()) as Protocol.HeapProfiler.SamplingHeapProfile;
@@ -192,20 +200,24 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
192
200
  readonly timelineOverview: HeapTimelineOverview = new HeapTimelineOverview();
193
201
  profileInternal: CPUProfile.ProfileTreeModel.ProfileTreeModel|null = null;
194
202
  searchableViewInternal!: UI.SearchableView.SearchableView;
195
- dataGrid: DataGrid.DataGrid.DataGridImpl<unknown>;
203
+ dataGrid: UI.Widget.Widget;
196
204
  viewSelectComboBox: HTMLSelectElement|undefined;
197
- focusButton!: UI.Toolbar.ToolbarButton;
198
- excludeButton!: UI.Toolbar.ToolbarButton;
205
+ focusButton: Buttons.Button.Button|undefined;
206
+ excludeButton: Buttons.Button.Button|undefined;
199
207
  resetButton: Buttons.Button.Button|undefined;
208
+ #sortColumnId = 'self';
209
+ #sortAscending = false;
210
+ #selectedNode: ProfileDataGridNode|null = null;
211
+
200
212
  readonly linkifierInternal: Components.Linkifier.Linkifier = new Components.Linkifier.Linkifier(maxLinkLength);
201
- nodeFormatter!: Formatter;
213
+ nodeFormatter!: NodeFormatter;
202
214
  viewType!: Common.Settings.Setting<ViewTypes>;
203
215
  bottomUpProfileDataGridTree?: BottomUpProfileDataGridTree|null;
204
216
  topDownProfileDataGridTree?: TopDownProfileDataGridTree|null;
205
217
  currentSearchResultIndex?: number;
206
218
  dataProvider?: ProfileFlameChartDataProvider;
207
219
  flameChart?: ProfileFlameChart;
208
- visibleView?: ProfileFlameChart|DataGrid.DataGrid.DataGridWidget<unknown>;
220
+ visibleView?: UI.Widget.Widget;
209
221
  searchableElement?: ProfileDataGridTree|ProfileFlameChart;
210
222
  profileDataGridTree?: ProfileDataGridTree;
211
223
 
@@ -225,7 +237,7 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
225
237
 
226
238
  this.#setupSearchableView();
227
239
 
228
- this.dataGrid = this.#createDataGrid();
240
+ this.dataGrid = new UI.Widget.VBox();
229
241
 
230
242
  this.profileHeader = profileHeader;
231
243
  this.profileType = profileHeader.profileType();
@@ -258,40 +270,110 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
258
270
  this.searchableViewInternal.show(this.element);
259
271
  }
260
272
 
261
- #createDataGrid(): DataGrid.DataGrid.DataGridImpl<unknown> {
262
- const columns: DataGrid.DataGrid.ColumnDescriptor[] = [];
263
- columns.push({
264
- id: 'self',
265
- title: this.columnHeader('self'),
266
- width: '120px',
267
- fixedWidth: true,
268
- sortable: true,
269
- sort: DataGrid.DataGrid.Order.Descending,
270
- });
271
- columns.push({
272
- id: 'total',
273
- title: this.columnHeader('total'),
274
- width: '120px',
275
- fixedWidth: true,
276
- sortable: true,
277
- });
278
- columns.push({
279
- id: 'function',
280
- title: i18nString(UIStrings.function),
281
- disclosure: true,
282
- sortable: true,
283
- });
273
+ #renderDataGrid(): void {
274
+ if (!this.profileDataGridTree) {
275
+ return;
276
+ }
277
+ const onSort = (e: CustomEvent<{columnId: string, ascending: boolean}>): void => {
278
+ this.#sortColumnId = e.detail.columnId;
279
+ this.#sortAscending = e.detail.ascending;
280
+ this.sortProfile();
281
+ };
284
282
 
285
- const dataGrid = new DataGrid.DataGrid.DataGridImpl({
286
- displayName: i18nString(UIStrings.profiler),
287
- columns,
288
- });
289
- dataGrid.addEventListener(DataGrid.DataGrid.Events.SORTING_CHANGED, this.sortProfile, this);
290
- dataGrid.addEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, this.nodeSelected.bind(this, true));
291
- dataGrid.addEventListener(DataGrid.DataGrid.Events.DESELECTED_NODE, this.nodeSelected.bind(this, false));
292
- dataGrid.setRowContextMenuCallback(this.populateContextMenu.bind(this));
283
+ const onDeselect = (): void => {
284
+ this.#selectedNode = null;
285
+ this.nodeSelected(false);
286
+ };
293
287
 
294
- return dataGrid;
288
+ // clang-format off
289
+ // eslint-disable-next-line @devtools/no-lit-render-outside-of-view
290
+ render(html`
291
+ <devtools-data-grid class="flex-auto" name=${i18nString(UIStrings.profiler)} striped autofocus resize="last"
292
+ @sort=${onSort} @deselect=${onDeselect} .template=${html`
293
+ <table>
294
+ <tr>
295
+ <th id="self" width="120px" fixed weight="1" sortable
296
+ sort=${this.#sortColumnId === 'self' ? (this.#sortAscending ? 'ascending' : 'descending') : 'none'}>
297
+ ${this.columnHeader('self')}
298
+ </th>
299
+ <th id="total" width="120px" fixed weight="1" sortable
300
+ sort=${this.#sortColumnId === 'total' ? (this.#sortAscending ? 'ascending' : 'descending') : 'none'}>
301
+ ${this.columnHeader('total')}
302
+ </th>
303
+ <th id="function" weight="3" sortable disclosure
304
+ sort=${this.#sortColumnId === 'function' ? (this.#sortAscending ? 'ascending' : 'descending') : 'none'}>
305
+ ${i18nString(UIStrings.function)}
306
+ </th>
307
+ </tr>
308
+ ${repeat(this.profileDataGridTree.children,
309
+ (node: ProfileDataGridNode) => node.callUID,
310
+ (node: ProfileDataGridNode) => this.#renderNode(node))}
311
+ </table>`}>
312
+ </devtools-data-grid>
313
+ `, this.dataGrid.element);
314
+ // clang-format on
315
+ }
316
+
317
+ #renderNode(node: ProfileDataGridNode): TemplateResult {
318
+ const onSelect = (): void => {
319
+ this.#selectedNode = node;
320
+ this.nodeSelected(true);
321
+ };
322
+ const onContextMenu = (event: CustomEvent<UI.ContextMenu.ContextMenu>): void => {
323
+ this.populateContextMenu(event.detail, node);
324
+ };
325
+ const onExpand = (): void => {
326
+ node.expanded = true;
327
+ node.populate();
328
+ this.refresh();
329
+ };
330
+ const onCollapse = (): void => {
331
+ node.expanded = false;
332
+ this.refresh();
333
+ };
334
+
335
+ if (node.profileNode.scriptId !== '0' && !node.linkElement) {
336
+ node.linkElement = this.nodeFormatter.linkifyNode(node);
337
+ if (node.linkElement) {
338
+ (node.linkElement as HTMLElement).style.maxWidth = '75%';
339
+ }
340
+ }
341
+
342
+ // clang-format off
343
+ return html`
344
+ <tr data-uid=${node.callUID} ?selected=${this.#selectedNode === node} ?expanded=${node.expanded} @select=${onSelect}
345
+ @contextmenu=${onContextMenu} @expand=${onExpand} @collapse=${onCollapse}>
346
+ <td data-value=${node.self} class="numeric-column ${node.searchMatchedSelfColumn ? 'highlight' : ''}"
347
+ aria-label=${`${this.nodeFormatter.formatValueAccessibleText(node.self)}, ${this.nodeFormatter.formatPercent(node.selfPercent, node)}`}>
348
+ <div class="profile-multiple-values">
349
+ <span>${this.nodeFormatter.formatValue(node.self)}</span>
350
+ <span class="percent-column">${this.nodeFormatter.formatPercent(node.selfPercent, node)}</span>
351
+ </div>
352
+ </td>
353
+ <td data-value=${node.total} class="numeric-column ${node.searchMatchedTotalColumn ? 'highlight' : ''}"
354
+ aria-label=${`${this.nodeFormatter.formatValueAccessibleText(node.total)}, ${this.nodeFormatter.formatPercent(node.totalPercent, node)}`}>
355
+ <div class="profile-multiple-values">
356
+ <span>${this.nodeFormatter.formatValue(node.total)}</span>
357
+ <span class="percent-column">${this.nodeFormatter.formatPercent(node.totalPercent, node)}</span>
358
+ </div>
359
+ </td>
360
+ <td data-value=${node.functionName} class="${node.searchMatchedFunctionColumn ? 'highlight' : ''} ${node.deoptReason ? 'not-optimized' : ''}">
361
+ ${node.deoptReason ? html`
362
+ <devtools-icon name="warning-filled" class="profile-warn-marker small"
363
+ title=${i18nString(UIStrings.notOptimizedS, {PH1: node.deoptReason})}>
364
+ </devtools-icon>` : nothing}
365
+ ${node.functionName}
366
+ ${node.linkElement ? node.linkElement : nothing}
367
+ </td>
368
+ ${node.hasChildren() ? html`
369
+ <td><table>
370
+ ${node.expanded ? html`${repeat(
371
+ node.children as ProfileDataGridNode[],
372
+ child => child.callUID,
373
+ child => this.#renderNode(child))}` : nothing}
374
+ </table></td>` : nothing}
375
+ </tr>`;
376
+ // clang-format on
295
377
  }
296
378
 
297
379
  override async toolbarItems(): Promise<TemplateResult> {
@@ -322,7 +404,8 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
322
404
  disabled: !this.#isNodeSelected,
323
405
  } as Buttons.Button.ButtonData}
324
406
  @click=${this.focusClicked.bind(this)}
325
- ?hidden=${isFlame}>
407
+ ?hidden=${isFlame}
408
+ ${ref(e => { this.focusButton = e as Buttons.Button.Button; })}>
326
409
  </devtools-button>
327
410
  <devtools-button .data=${{
328
411
  iconName: 'cross',
@@ -332,7 +415,8 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
332
415
  disabled: !this.#isNodeSelected,
333
416
  } as Buttons.Button.ButtonData}
334
417
  @click=${this.excludeClicked.bind(this)}
335
- ?hidden=${isFlame}>
418
+ ?hidden=${isFlame}
419
+ ${ref(e => { this.excludeButton = e as Buttons.Button.Button; })}>
336
420
  </devtools-button>
337
421
  <devtools-button .data=${{
338
422
  iconName: 'refresh',
@@ -441,7 +525,7 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
441
525
  return this.profileInternal;
442
526
  }
443
527
 
444
- initialize(nodeFormatter: Formatter): void {
528
+ initialize(nodeFormatter: NodeFormatter): void {
445
529
  this.nodeFormatter = nodeFormatter;
446
530
 
447
531
  this.viewType = Common.Settings.Settings.instance().createSetting('profile-view', ViewTypes.HEAVY);
@@ -502,22 +586,11 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
502
586
  if (!this.profileDataGridTree) {
503
587
  return;
504
588
  }
505
- this.dataGrid.rootNode().removeChildren();
506
-
507
- const children = this.profileDataGridTree.children;
508
- const count = children.length;
509
-
510
- for (let index = 0; index < count; ++index) {
511
- this.dataGrid.rootNode().appendChild(children[index]);
512
- }
589
+ this.#renderDataGrid();
513
590
  }
514
591
 
515
592
  refreshVisibleData(): void {
516
- let child: (DataGrid.DataGrid.DataGridNode<unknown>|null) = this.dataGrid.rootNode().children[0];
517
- while (child) {
518
- child.refresh();
519
- child = child.traverseNextNode(false, null, true);
520
- }
593
+ this.#renderDataGrid();
521
594
  }
522
595
 
523
596
  searchableView(): UI.SearchableView.SearchableView {
@@ -539,24 +612,44 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
539
612
  onSearchCanceled(): void {
540
613
  if (this.searchableElement) {
541
614
  this.searchableElement.onSearchCanceled();
615
+ this.refresh();
542
616
  }
543
617
  }
544
618
 
545
619
  performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards?: boolean): void {
546
620
  if (this.searchableElement) {
547
621
  this.searchableElement.performSearch(searchConfig, shouldJump, jumpBackwards);
622
+ this.refresh();
548
623
  }
549
624
  }
550
625
 
551
626
  jumpToNextSearchResult(): void {
552
627
  if (this.searchableElement) {
553
628
  this.searchableElement.jumpToNextSearchResult();
629
+ this.#syncSearchSelection();
554
630
  }
555
631
  }
556
632
 
557
633
  jumpToPreviousSearchResult(): void {
558
634
  if (this.searchableElement) {
559
635
  this.searchableElement.jumpToPreviousSearchResult();
636
+ this.#syncSearchSelection();
637
+ }
638
+ }
639
+
640
+ #syncSearchSelection(): void {
641
+ if (this.searchableElement === this.profileDataGridTree && this.profileDataGridTree) {
642
+ const searchResult = this.profileDataGridTree.searchResults[this.profileDataGridTree.searchResultIndex];
643
+ this.#selectedNode = searchResult?.profileNode || null;
644
+
645
+ let node = this.#selectedNode;
646
+ while (node?.parent) {
647
+ node.parent.expanded = true;
648
+ node = node.parent as ProfileDataGridNode;
649
+ }
650
+
651
+ this.nodeSelected(!!this.#selectedNode);
652
+ this.refresh();
560
653
  }
561
654
  }
562
655
 
@@ -595,14 +688,17 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
595
688
  void Common.Revealer.reveal(uiLocation);
596
689
  }
597
690
 
598
- changeView(): void {
691
+ changeView(e?: Event): void {
599
692
  if (!this.profileInternal) {
600
693
  return;
601
694
  }
602
695
 
603
- if (this.viewSelectComboBox) {
604
- this.viewType.set(this.viewSelectComboBox.value as ViewTypes);
696
+ if (e) {
697
+ const select = e.target as HTMLSelectElement;
698
+ this.viewType.set(select.value as ViewTypes);
605
699
  }
700
+ this.#selectedNode = null;
701
+ this.#isNodeSelected = false;
606
702
  this.performUpdate();
607
703
  }
608
704
 
@@ -612,7 +708,7 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
612
708
  }
613
709
 
614
710
  focusClicked(): void {
615
- if (!this.dataGrid.selectedNode) {
711
+ if (!this.#selectedNode) {
616
712
  return;
617
713
  }
618
714
 
@@ -620,7 +716,7 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
620
716
  this.performUpdate();
621
717
  this.resetButton?.focus();
622
718
  if (this.profileDataGridTree) {
623
- this.profileDataGridTree.focus((this.dataGrid.selectedNode as ProfileDataGridNode));
719
+ this.profileDataGridTree.focus(this.#selectedNode);
624
720
  }
625
721
  this.refresh();
626
722
  this.refreshVisibleData();
@@ -628,7 +724,7 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
628
724
  }
629
725
 
630
726
  excludeClicked(): void {
631
- const selectedNode = this.dataGrid.selectedNode;
727
+ const selectedNode = this.#selectedNode;
632
728
 
633
729
  if (!selectedNode) {
634
730
  return;
@@ -638,10 +734,11 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
638
734
  this.performUpdate();
639
735
  this.resetButton?.focus();
640
736
 
641
- selectedNode.deselect();
737
+ this.#selectedNode = null;
738
+ this.nodeSelected(false);
642
739
 
643
740
  if (this.profileDataGridTree) {
644
- this.profileDataGridTree.exclude((selectedNode as ProfileDataGridNode));
741
+ this.profileDataGridTree.exclude(selectedNode);
645
742
  }
646
743
  this.refresh();
647
744
  this.refreshVisibleData();
@@ -651,6 +748,8 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
651
748
  resetClicked(): void {
652
749
  this.viewSelectComboBox?.focus();
653
750
  this.#isResetEnabled = false;
751
+ this.#selectedNode = null;
752
+ this.#isNodeSelected = false;
654
753
  this.performUpdate();
655
754
  if (this.profileDataGridTree) {
656
755
  this.profileDataGridTree.restore();
@@ -664,8 +763,8 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
664
763
  if (!this.profileDataGridTree) {
665
764
  return;
666
765
  }
667
- const sortAscending = this.dataGrid.isSortOrderAscending();
668
- const sortColumnId = this.dataGrid.sortColumnId();
766
+ const sortAscending = this.#sortAscending;
767
+ const sortColumnId = this.#sortColumnId;
669
768
  const sortProperty = sortColumnId === 'function' ? 'functionName' : sortColumnId || '';
670
769
  this.profileDataGridTree.sort(ProfileDataGridTree.propertyComparator(sortProperty, sortAscending), false);
671
770
 
@@ -690,13 +789,13 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
690
789
  case ViewTypes.TREE:
691
790
  this.profileDataGridTree = this.getTopDownProfileDataGridTree();
692
791
  this.sortProfile();
693
- this.visibleView = this.dataGrid.asWidget();
792
+ this.visibleView = this.dataGrid;
694
793
  this.searchableElement = this.profileDataGridTree;
695
794
  break;
696
795
  case ViewTypes.HEAVY:
697
796
  this.profileDataGridTree = this.getBottomUpProfileDataGridTree();
698
797
  this.sortProfile();
699
- this.visibleView = this.dataGrid.asWidget();
798
+ this.visibleView = this.dataGrid;
700
799
  this.searchableElement = this.profileDataGridTree;
701
800
  break;
702
801
  }
@@ -709,16 +808,17 @@ export class HeapProfileView extends UI.View.SimpleView implements UI.Searchable
709
808
  }
710
809
 
711
810
  const isFlame = currentViewType === ViewTypes.FLAME;
712
- const isTreeOrHeavy = !isFlame;
713
-
714
- this.focusButton?.setVisible(isTreeOrHeavy);
715
- this.excludeButton?.setVisible(isTreeOrHeavy);
716
- this.resetButton?.classList.toggle('hidden', !isTreeOrHeavy);
717
-
718
- this.focusButton?.setEnabled(this.#isNodeSelected);
719
- this.excludeButton?.setEnabled(this.#isNodeSelected);
720
811
 
812
+ if (this.focusButton) {
813
+ this.focusButton.hidden = isFlame;
814
+ this.focusButton.disabled = !this.#isNodeSelected;
815
+ }
816
+ if (this.excludeButton) {
817
+ this.excludeButton.hidden = isFlame;
818
+ this.excludeButton.disabled = !this.#isNodeSelected;
819
+ }
721
820
  if (this.resetButton) {
821
+ this.resetButton.hidden = isFlame;
722
822
  this.resetButton.disabled = !this.#isResetEnabled;
723
823
  }
724
824
 
@@ -1120,20 +1220,39 @@ export class SamplingHeapProfileModel extends CPUProfile.ProfileTreeModel.Profil
1120
1220
 
1121
1221
  export class NodeFormatter implements Formatter {
1122
1222
  readonly profileView: HeapProfileView;
1223
+ readonly #formattedValueCache = new Map<number, string>();
1224
+ readonly #formattedValueAccessibleTextCache = new Map<number, string>();
1225
+ readonly #formattedPercentCache = new Map<number, string>();
1226
+
1123
1227
  constructor(profileView: HeapProfileView) {
1124
1228
  this.profileView = profileView;
1125
1229
  }
1126
1230
 
1127
1231
  formatValue(value: number): string {
1128
- return i18n.ByteUtilities.bytesToString(value);
1232
+ let result = this.#formattedValueCache.get(value);
1233
+ if (!result) {
1234
+ result = i18n.ByteUtilities.bytesToString(value);
1235
+ this.#formattedValueCache.set(value, result);
1236
+ }
1237
+ return result;
1129
1238
  }
1130
1239
 
1131
1240
  formatValueAccessibleText(value: number): string {
1132
- return i18nString(UIStrings.sBytes, {PH1: value});
1241
+ let result = this.#formattedValueAccessibleTextCache.get(value);
1242
+ if (!result) {
1243
+ result = i18nString(UIStrings.sBytes, {PH1: value});
1244
+ this.#formattedValueAccessibleTextCache.set(value, result);
1245
+ }
1246
+ return result;
1133
1247
  }
1134
1248
 
1135
1249
  formatPercent(value: number, _node: ProfileDataGridNode): string {
1136
- return i18nString(UIStrings.formatPercent, {PH1: value.toFixed(2)});
1250
+ let result = this.#formattedPercentCache.get(value);
1251
+ if (!result) {
1252
+ result = i18nString(UIStrings.formatPercent, {PH1: value.toFixed(2)});
1253
+ this.#formattedPercentCache.set(value, result);
1254
+ }
1255
+ return result;
1137
1256
  }
1138
1257
 
1139
1258
  linkifyNode(node: ProfileDataGridNode): Element|null {
@@ -277,7 +277,7 @@ const UIStrings = {
277
277
  * @description Text of a DOM element in Heap Snapshot View of a profiler tool
278
278
  */
279
279
  stackWasNotRecordedForThisObject:
280
- 'Stack wasn\'t recorded for this object because it had been allocated before this profile recording started.',
280
+ 'Stack wasnt recorded for this object because it had been allocated before this profile recording started.',
281
281
  /**
282
282
  * @description Text in Heap Snapshot View of a profiler tool.
283
283
  * This text is on a button to undo all previous "Ignore this retainer" actions.
@@ -590,16 +590,20 @@ export class ProfileDataGridTree implements UI.SearchableView.Searchable {
590
590
 
591
591
  this.searchResults = [];
592
592
  const deepSearch = this.deepSearch;
593
- let current: DataGrid.DataGrid.DataGridNode<unknown>|null;
594
- for (current = this.children[0]; current; current = current.traverseNextNode(!deepSearch, null, !deepSearch)) {
595
- const item = (current as ProfileDataGridNode | null);
596
- if (!item) {
597
- break;
598
- }
599
593
 
600
- if (matchesQuery(item)) {
601
- this.searchResults.push({profileNode: item});
594
+ const walk = (node: ProfileDataGridNode): void => {
595
+ if (matchesQuery(node)) {
596
+ this.searchResults.push({profileNode: node});
597
+ }
598
+ if (deepSearch || node.expanded) {
599
+ for (const child of node.children as ProfileDataGridNode[]) {
600
+ walk(child);
601
+ }
602
602
  }
603
+ };
604
+
605
+ for (const child of this.children as ProfileDataGridNode[]) {
606
+ walk(child);
603
607
  }
604
608
  this.searchResultIndex = jumpBackwards ? 0 : this.searchResults.length - 1;
605
609
  this.searchableView.updateSearchMatchesCount(this.searchResults.length);
@@ -9,8 +9,8 @@ import * as i18n from '../../core/i18n/i18n.js';
9
9
  import * as Platform from '../../core/platform/platform.js';
10
10
  import * as ProtocolClient from '../../core/protocol_client/protocol_client.js';
11
11
  import * as SDK from '../../core/sdk/sdk.js';
12
+ import * as TextUtils from '../../core/text_utils/text_utils.js';
12
13
  import * as Bindings from '../../models/bindings/bindings.js';
13
- import * as TextUtils from '../../models/text_utils/text_utils.js';
14
14
  import * as Workspace from '../../models/workspace/workspace.js';
15
15
  import * as Buttons from '../../ui/components/buttons/buttons.js';
16
16
  import * as UIHelpers from '../../ui/helpers/helpers.js';
@@ -8,8 +8,7 @@ Recorder is a panel in DevTools that allows recording and replaying user actions
8
8
  - `images` folder contains Recorder-specific icons and images.
9
9
  - `models` folder contains the "business logic" part of Recorder wrapping DevTools SDK modules and Puppeteer to provide record/replay/import/export functionality. The name `models` is historical and, probably, a better name could be found: record/replay used to be implemented as a single SDK Model and was placed in the `models` folder in DevTools before ending up here.
10
10
  - `injected` folder holds the code that gets injected into the target page. This code is responsible for interpreting client side events and sending information about them to the `models`.
11
- - `RecorderPanel.ts` is a light wrapper around `RecorderController` that integrates with `UI.Panel.Panel`, a generic interface for a top-level panel.
12
- - `RecorderController.ts` is the main class that is responsible for rendering the panel and holds the entire panel state.
11
+ - `RecorderController.ts` is the main component for the Recorder panel. It manages the state and renders the UI.
13
12
 
14
13
  ## How it works
15
14