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
@@ -313,7 +313,7 @@ export function renderNodeTitle(nodeTitle: string): LitTemplate|null {
313
313
  match[3] && html`<span class=webkit-html-attribute-name>${match[3]}</span>`}`;
314
314
  }
315
315
 
316
- export function renderTrustedType(description: string, className: string): LitTemplate {
316
+ export function renderTrustedType(description: string, className: string|null): LitTemplate {
317
317
  return html`${className} <span class=object-value-string title=${description}>"${
318
318
  description.replace(/\n/g, '\u21B5')}"</span>`;
319
319
  }
@@ -41,7 +41,7 @@
41
41
  .object-value-regexp,
42
42
  .object-value-symbol {
43
43
  white-space: pre;
44
- unicode-bidi: -webkit-isolate;
44
+ unicode-bidi: isolate;
45
45
  color: var(--sys-color-token-property-special);
46
46
  }
47
47
 
@@ -90,6 +90,7 @@
90
90
  .name {
91
91
  color: var(--sys-color-token-tag);
92
92
  flex-shrink: 0;
93
+ unicode-bidi: isolate;
93
94
  }
94
95
 
95
96
  .object-properties-preview .name {
@@ -6,8 +6,8 @@
6
6
  import * as Common from '../../../../core/common/common.js';
7
7
  import * as i18n from '../../../../core/i18n/i18n.js';
8
8
  import * as Platform from '../../../../core/platform/platform.js';
9
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
9
10
  import * as Geometry from '../../../../models/geometry/geometry.js';
10
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
11
11
  import * as Diff from '../../../../third_party/diff/diff.js';
12
12
  import * as TextPrompt from '../../../../ui/components/text_prompt/text_prompt.js';
13
13
  import {type LitTemplate, nothing, render} from '../../../lit/lit.js';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import type * as Common from '../../../../core/common/common.js';
6
6
  import type * as Platform from '../../../../core/platform/platform.js';
7
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
7
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
8
8
 
9
9
  import {ResourceSourceFrame} from './ResourceSourceFrame.js';
10
10
  import {StreamingContentHexView} from './StreamingContentHexView.js';
@@ -32,7 +32,7 @@
32
32
 
33
33
  import * as i18n from '../../../../core/i18n/i18n.js';
34
34
  import type * as Platform from '../../../../core/platform/platform.js';
35
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
35
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
36
36
  import {Directives, html, render} from '../../../lit/lit.js';
37
37
  import * as VisualLogging from '../../../visual_logging/visual_logging.js';
38
38
  import * as UI from '../../legacy.js';
@@ -35,7 +35,7 @@ import * as Common from '../../../../core/common/common.js';
35
35
  import * as Host from '../../../../core/host/host.js';
36
36
  import * as i18n from '../../../../core/i18n/i18n.js';
37
37
  import * as Platform from '../../../../core/platform/platform.js';
38
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
38
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
39
39
  import * as Workspace from '../../../../models/workspace/workspace.js';
40
40
  import {createIcon} from '../../../kit/kit.js';
41
41
  import * as VisualLogging from '../../../visual_logging/visual_logging.js';
@@ -4,9 +4,8 @@
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
5
 
6
6
  import * as i18n from '../../../../core/i18n/i18n.js';
7
- import * as Platform from '../../../../core/platform/platform.js';
8
7
  import * as SDK from '../../../../core/sdk/sdk.js';
9
- import * as Highlighting from '../../../components/highlighting/highlighting.js';
8
+ import {html, render} from '../../../lit/lit.js';
10
9
  import * as VisualLogging from '../../../visual_logging/visual_logging.js';
11
10
  import * as UI from '../../legacy.js';
12
11
  import * as ObjectUI from '../object_ui/object_ui.js';
@@ -22,26 +21,48 @@ const UIStrings = {
22
21
  const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/source_frame/JSONView.ts', UIStrings);
23
22
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
24
23
 
24
+ export interface ViewInput {
25
+ objectTree: ObjectUI.ObjectPropertiesSection.ObjectTree;
26
+ parsedJSON: ParsedJSON;
27
+ }
28
+
29
+ export type ViewOutput = undefined;
30
+
31
+ const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTMLElement): void => {
32
+ const obj = SDK.RemoteObject.RemoteObject.fromLocalObject(input.parsedJSON.data);
33
+ const titleText = input.parsedJSON.prefix + obj.description + input.parsedJSON.suffix;
34
+ const title = html`<span>${titleText}</span>`;
35
+ render(html`
36
+ <style>${jsonViewStyles}</style>
37
+ ${ObjectUI.ObjectPropertiesSection.renderObjectPropertiesSection(input.objectTree, title)}
38
+ `,
39
+ target, {
40
+
41
+ container: {
42
+ classes: ['json-view'],
43
+ attributes: {
44
+ jslog: VisualLogging.section('json-view'),
45
+ },
46
+ },
47
+ });
48
+ };
49
+
50
+ type View = typeof DEFAULT_VIEW;
51
+
25
52
  export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Searchable {
26
- private initialized: boolean;
27
- private readonly parsedJSON: ParsedJSON;
28
- private startCollapsed: boolean;
29
- private searchableView!: UI.SearchableView.SearchableView|null;
30
- private treeOutline!: ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection;
31
- private currentSearchFocusIndex: number;
32
- private currentSearchTreeElements: ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement[];
33
- private searchRegex: RegExp|null;
34
- constructor(parsedJSON: ParsedJSON, startCollapsed?: boolean) {
35
- super();
36
- this.initialized = false;
37
- this.registerRequiredCSS(jsonViewStyles);
38
- this.parsedJSON = parsedJSON;
53
+ #parsedJSON: ParsedJSON;
54
+ private readonly startCollapsed: boolean;
55
+ private searchableView: UI.SearchableView.SearchableView|null = null;
56
+ private objectTree: ObjectUI.ObjectPropertiesSection.ObjectTree|null = null;
57
+ private readonly search: UI.TreeOutline.TreeSearch<ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase>;
58
+ private readonly view: View;
59
+
60
+ constructor(parsedJSON: ParsedJSON, startCollapsed?: boolean, element?: HTMLElement, view: View = DEFAULT_VIEW) {
61
+ super(element);
62
+ this.#parsedJSON = parsedJSON;
39
63
  this.startCollapsed = Boolean(startCollapsed);
40
- this.element.classList.add('json-view');
41
- this.element.setAttribute('jslog', `${VisualLogging.section('json-view')}`);
42
- this.currentSearchFocusIndex = 0;
43
- this.currentSearchTreeElements = [];
44
- this.searchRegex = null;
64
+ this.search = new UI.TreeOutline.TreeSearch();
65
+ this.view = view;
45
66
  }
46
67
 
47
68
  static async createView(content: string): Promise<UI.SearchableView.SearchableView|null> {
@@ -69,6 +90,17 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
69
90
  return searchableView;
70
91
  }
71
92
 
93
+ set parsedJSON(parsedJSON: ParsedJSON) {
94
+ if (this.objectTree) {
95
+ this.objectTree.removeEventListener(ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase.Events.CHILDREN_CHANGED,
96
+ this.#onChildrenChanged, this);
97
+ }
98
+ this.#parsedJSON = parsedJSON;
99
+ this.objectTree = null;
100
+ this.onSearchCanceled();
101
+ this.requestUpdate();
102
+ }
103
+
72
104
  setSearchableView(searchableView: UI.SearchableView.SearchableView): void {
73
105
  this.searchableView = searchableView;
74
106
  }
@@ -137,129 +169,89 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
137
169
  override wasShown(): void {
138
170
  super.wasShown();
139
171
  this.initialize();
172
+ this.requestUpdate();
140
173
  }
141
174
 
142
175
  private initialize(): void {
143
- if (this.initialized) {
176
+ if (this.objectTree) {
144
177
  return;
145
178
  }
146
- this.initialized = true;
147
-
148
- const obj = SDK.RemoteObject.RemoteObject.fromLocalObject(this.parsedJSON.data);
149
- const title = this.parsedJSON.prefix + obj.description + this.parsedJSON.suffix;
150
- this.treeOutline = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection(
151
- obj, title, undefined, true /* showOverflow */, false /* editable */);
152
- this.treeOutline.enableContextMenu();
179
+ const obj = SDK.RemoteObject.RemoteObject.fromLocalObject(this.#parsedJSON.data);
180
+ this.objectTree = new ObjectUI.ObjectPropertiesSection.ObjectTree(obj, {
181
+ readOnly: true,
182
+ propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
183
+ search: this.search,
184
+ });
153
185
  if (!this.startCollapsed) {
154
- this.treeOutline.expand();
155
- }
156
- this.element.appendChild(this.treeOutline.element);
157
- const firstChild = this.treeOutline.firstChild();
158
- if (firstChild) {
159
- firstChild.select(true /* omitFocus */, false /* selectedByUser */);
186
+ this.objectTree.expanded = true;
160
187
  }
188
+ this.objectTree.addEventListener(ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase.Events.CHILDREN_CHANGED,
189
+ this.#onChildrenChanged, this);
161
190
  }
162
191
 
163
- private jumpToMatch(index: number): void {
164
- if (!this.searchRegex) {
165
- return;
166
- }
167
- const previousFocusElement = this.currentSearchTreeElements[this.currentSearchFocusIndex];
168
- if (previousFocusElement) {
169
- previousFocusElement.setSearchRegex(this.searchRegex);
170
- }
171
-
172
- const newFocusElement = this.currentSearchTreeElements[index];
173
- if (newFocusElement) {
174
- this.updateSearchIndex(index);
175
- newFocusElement.setSearchRegex(this.searchRegex, Highlighting.highlightedCurrentSearchResultClassName);
176
- newFocusElement.reveal();
177
- } else {
178
- this.updateSearchIndex(0);
179
- }
192
+ #onChildrenChanged(): void {
193
+ this.requestUpdate();
180
194
  }
181
195
 
182
- private updateSearchCount(count: number): void {
183
- if (!this.searchableView) {
196
+ override performUpdate(): void {
197
+ this.initialize();
198
+ if (!this.objectTree) {
184
199
  return;
185
200
  }
186
- this.searchableView.updateSearchMatchesCount(count);
201
+ this.view({objectTree: this.objectTree, parsedJSON: this.#parsedJSON}, undefined, this.contentElement);
187
202
  }
188
203
 
189
- private updateSearchIndex(index: number): void {
190
- this.currentSearchFocusIndex = index;
191
- if (!this.searchableView) {
192
- return;
204
+ private jumpToMatch(): void {
205
+ if (this.searchableView) {
206
+ this.search.updateSearchableView(this.searchableView);
207
+ }
208
+ const currentMatch = this.search.currentMatch();
209
+ if (currentMatch) {
210
+ let current = currentMatch.node.parent;
211
+ while (current) {
212
+ current.expanded = true;
213
+ current = current.parent;
214
+ }
193
215
  }
194
- this.searchableView.updateCurrentMatchIndex(index);
195
216
  }
196
217
 
197
218
  onSearchCanceled(): void {
198
- this.searchRegex = null;
199
- this.currentSearchTreeElements = [];
200
-
201
- let element: UI.TreeOutline.TreeElement|null;
202
- for (element = this.treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) {
203
- if (!(element instanceof ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement)) {
204
- continue;
205
- }
206
- element.revertHighlightChanges();
219
+ this.search.reset();
220
+ if (this.searchableView) {
221
+ this.search.updateSearchableView(this.searchableView);
207
222
  }
208
- this.updateSearchCount(0);
209
- this.updateSearchIndex(0);
210
223
  }
211
224
 
212
- performSearch(searchConfig: UI.SearchableView.SearchConfig, _shouldJump: boolean, jumpBackwards?: boolean): void {
213
- let newIndex: number = this.currentSearchFocusIndex;
214
- const previousSearchFocusElement = this.currentSearchTreeElements[newIndex];
225
+ performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards?: boolean): void {
226
+ this.initialize();
215
227
  this.onSearchCanceled();
216
- this.searchRegex = searchConfig.toSearchRegex(true).regex;
228
+ const searchRegex = searchConfig.toSearchRegex(true).regex;
229
+ if (!this.objectTree) {
230
+ return;
231
+ }
217
232
 
218
- let element: UI.TreeOutline.TreeElement|null;
219
- for (element = this.treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) {
220
- if (!(element instanceof ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement)) {
221
- continue;
222
- }
223
- const hasMatch = element.setSearchRegex(this.searchRegex);
224
- if (hasMatch) {
225
- this.currentSearchTreeElements.push(element);
233
+ this.search.search(this.objectTree, jumpBackwards ?? false, (node, closeTag) => {
234
+ if (closeTag || !searchRegex) {
235
+ return [];
226
236
  }
227
- if (previousSearchFocusElement === element) {
228
- const currentIndex = this.currentSearchTreeElements.length - 1;
229
- if (hasMatch || jumpBackwards) {
230
- newIndex = currentIndex;
231
- } else {
232
- newIndex = currentIndex + 1;
233
- }
234
- }
235
- }
236
- this.updateSearchCount(this.currentSearchTreeElements.length);
237
+ return node.match(searchRegex);
238
+ });
237
239
 
238
- if (!this.currentSearchTreeElements.length) {
239
- this.updateSearchIndex(-1);
240
- return;
240
+ if (shouldJump) {
241
+ this.jumpToMatch();
242
+ } else if (this.searchableView) {
243
+ this.search.updateSearchableView(this.searchableView);
241
244
  }
242
- newIndex = Platform.NumberUtilities.mod(newIndex, this.currentSearchTreeElements.length);
243
-
244
- this.jumpToMatch(newIndex);
245
245
  }
246
246
 
247
247
  jumpToNextSearchResult(): void {
248
- if (!this.currentSearchTreeElements.length) {
249
- return;
250
- }
251
- const newIndex =
252
- Platform.NumberUtilities.mod(this.currentSearchFocusIndex + 1, this.currentSearchTreeElements.length);
253
- this.jumpToMatch(newIndex);
248
+ this.search.next();
249
+ this.jumpToMatch();
254
250
  }
255
251
 
256
252
  jumpToPreviousSearchResult(): void {
257
- if (!this.currentSearchTreeElements.length) {
258
- return;
259
- }
260
- const newIndex =
261
- Platform.NumberUtilities.mod(this.currentSearchFocusIndex - 1, this.currentSearchTreeElements.length);
262
- this.jumpToMatch(newIndex);
253
+ this.search.prev();
254
+ this.jumpToMatch();
263
255
  }
264
256
 
265
257
  supportsCaseSensitiveSearch(): boolean {
@@ -301,11 +293,9 @@ export class SearchableJsonView extends UI.SearchableView.SearchableView {
301
293
  }
302
294
 
303
295
  set jsonObject(obj: Object|null|undefined) {
304
- const jsonView = new JSONView(new ParsedJSON(obj, '', ''));
305
- this.#jsonView.detach();
306
- this.#jsonView = jsonView;
307
- this.searchProvider = jsonView;
308
- jsonView.show(this.element);
296
+ this.#jsonView.parsedJSON = new ParsedJSON(obj, '', '');
297
+ this.searchProvider = this.#jsonView;
298
+ this.#jsonView.show(this.element);
309
299
  this.requestUpdate();
310
300
  }
311
301
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  import * as Common from '../../../../core/common/common.js';
7
7
  import * as i18n from '../../../../core/i18n/i18n.js';
8
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
8
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
9
9
  import * as UI from '../../legacy.js';
10
10
 
11
11
  import {FontView} from './FontView.js';
@@ -36,8 +36,8 @@ import '../../legacy.js';
36
36
 
37
37
  import * as Common from '../../../../core/common/common.js';
38
38
  import * as i18n from '../../../../core/i18n/i18n.js';
39
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
39
40
  import * as FormatterActions from '../../../../entrypoints/formatter_worker/FormatterActions.js'; // eslint-disable-line @devtools/es-modules-import
40
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
41
41
  import {render} from '../../../../ui/lit/lit.js';
42
42
  import * as UI from '../../legacy.js';
43
43
 
@@ -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 Root from '../../../../core/root/root.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 Formatter from '../../../../models/formatter/formatter.js';
13
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
14
14
  import * as PanelCommon from '../../../../panels/common/common.js';
15
15
  import * as CodeMirror from '../../../../third_party/codemirror.next/codemirror.next.js';
16
16
  import * as CodeHighlighter from '../../../components/code_highlighter/code_highlighter.js';
@@ -73,7 +73,7 @@ const UIStrings = {
73
73
  * @example {allow pasting} PH1
74
74
  */
75
75
  doNotPaste:
76
- 'Don\'t paste code you do not understand or have not reviewed yourself into DevTools. This could allow attackers to steal your identity or take control of your computer. Please type “{PH1}” below to allow pasting.',
76
+ 'Dont paste code you do not understand or have not reviewed yourself into DevTools. This could allow attackers to steal your identity or take control of your computer. Please type “{PH1}” below to allow pasting.',
77
77
  /**
78
78
  * @description Text a user needs to type in order to confirm that they are aware of the danger of pasting code into the DevTools console.
79
79
  */
@@ -88,7 +88,7 @@ const UIStrings = {
88
88
  * a text editor.
89
89
  */
90
90
  binaryContentError:
91
- 'Editor can\'t show binary data. Use the "Response" tab in the "Network" panel to inspect this resource.',
91
+ 'Editor cant show binary data. Use the "Response" tab in the "Network" panel to inspect this resource.',
92
92
  } as const;
93
93
  const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/source_frame/SourceFrame.ts', UIStrings);
94
94
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -4,7 +4,7 @@
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
5
 
6
6
  import type * as Common from '../../../../core/common/common.js';
7
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
7
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
8
8
  import * as LinearMemoryInspectorComponents from '../../../../panels/linear_memory_inspector/components/components.js';
9
9
  import * as UI from '../../legacy.js';
10
10
 
@@ -5,7 +5,7 @@
5
5
  import '../../../components/highlighting/highlighting.js';
6
6
 
7
7
  import * as i18n from '../../../../core/i18n/i18n.js';
8
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
8
+ import * as TextUtils from '../../../../core/text_utils/text_utils.js';
9
9
  import * as Lit from '../../../lit/lit.js';
10
10
  import * as VisualLogging from '../../../visual_logging/visual_logging.js';
11
11
  import * as UI from '../../legacy.js';
@@ -249,6 +249,10 @@ export class XMLTreeViewNode {
249
249
  return this.#children;
250
250
  }
251
251
 
252
+ treeNodeChildren(): Iterable<XMLTreeViewNode> {
253
+ return this.children();
254
+ }
255
+
252
256
  match(regex: RegExp, closeTag: boolean): RegExpStringIterator<RegExpExecArray> {
253
257
  return textView(this, closeTag).matchAll(regex);
254
258
  }
@@ -8,3 +8,7 @@
8
8
  padding: 2px 6px;
9
9
  overflow: auto;
10
10
  }
11
+
12
+ devtools-tree {
13
+ display: block;
14
+ }
@@ -9,11 +9,11 @@ import * as Host from '../../../../core/host/host.js';
9
9
  import * as i18n from '../../../../core/i18n/i18n.js';
10
10
  import * as Platform from '../../../../core/platform/platform.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 type * as Protocol from '../../../../generated/protocol.js';
13
14
  import * as Bindings from '../../../../models/bindings/bindings.js';
14
15
  import * as Breakpoints from '../../../../models/breakpoints/breakpoints.js';
15
16
  import type * as StackTrace from '../../../../models/stack_trace/stack_trace.js';
16
- import * as TextUtils from '../../../../models/text_utils/text_utils.js';
17
17
  import type * as Trace from '../../../../models/trace/trace.js';
18
18
  import * as Workspace from '../../../../models/workspace/workspace.js';
19
19
  import * as UIHelpers from '../../../helpers/helpers.js';
@@ -141,9 +141,11 @@ iframe.widget {
141
141
  display: none !important; /* stylelint-disable-line declaration-no-important */
142
142
  }
143
143
 
144
- .highlighted-search-result,:host::highlight(highlighted-search-result) {
144
+ .highlighted-search-result,
145
+ :host::highlight(highlighted-search-result) {
145
146
  border-radius: 1px;
146
147
  background-color: var(--sys-color-yellow-container);
148
+ color: var(--sys-color-on-yellow-container);
147
149
  outline: 1px solid var(--sys-color-yellow-container);
148
150
  }
149
151
 
@@ -320,7 +322,8 @@ input[type='range']:disabled::-webkit-slider-thumb {
320
322
  }
321
323
  }
322
324
 
323
- .highlighted-search-result.current-search-result,:host::highlight(current-search-result) {
325
+ .highlighted-search-result.current-search-result,
326
+ :host::highlight(current-search-result) {
324
327
  /* Note: this value is used in light & dark mode */
325
328
  --override-current-search-result-background-color: rgb(255 127 0 / 80%);
326
329
 
@@ -329,6 +332,7 @@ input[type='range']:disabled::-webkit-slider-thumb {
329
332
  padding: 1px;
330
333
  margin: -1px;
331
334
  background-color: var(--override-current-search-result-background-color);
335
+ color: var(--sys-color-on-surface);
332
336
  }
333
337
 
334
338
  .dimmed {
@@ -1221,7 +1225,7 @@ devtools-toolbar {
1221
1225
 
1222
1226
  .webkit-html-text-node {
1223
1227
  color: var(--text-primary);
1224
- unicode-bidi: -webkit-isolate;
1228
+ unicode-bidi: isolate;
1225
1229
  }
1226
1230
 
1227
1231
  .webkit-html-entity-value {
@@ -1229,7 +1233,7 @@ devtools-toolbar {
1229
1233
  /* See: crbug.com/1152736 for color variable migration. */
1230
1234
  /* stylelint-disable-next-line plugin/use_theme_colors */
1231
1235
  background-color: rgb(0 0 0 / 15%);
1232
- unicode-bidi: -webkit-isolate;
1236
+ unicode-bidi: isolate;
1233
1237
  }
1234
1238
 
1235
1239
  .webkit-html-doctype {
@@ -1242,13 +1246,13 @@ devtools-toolbar {
1242
1246
  .webkit-html-attribute-name {
1243
1247
  /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */
1244
1248
  color: var(--sys-color-token-attribute);
1245
- unicode-bidi: -webkit-isolate;
1249
+ unicode-bidi: isolate;
1246
1250
  }
1247
1251
 
1248
1252
  .webkit-html-attribute-value {
1249
1253
  /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */
1250
1254
  color: var(--sys-color-token-attribute-value);
1251
- unicode-bidi: -webkit-isolate;
1255
+ unicode-bidi: isolate;
1252
1256
  word-break: break-all;
1253
1257
  }
1254
1258
 
@@ -27,6 +27,7 @@ export {
27
27
  } from './render.js';
28
28
  export {
29
29
  html,
30
+ isLitDirective,
30
31
  } from './strip-whitespace.js';
31
32
 
32
33
  export type LitTemplate = Lit.TemplateResult|typeof Lit.nothing;
@@ -15,6 +15,13 @@ export interface RenderOptions extends Lit.RenderOptions {
15
15
 
16
16
  const renderOptions = new WeakMap<HTMLElement|DocumentFragment, RenderOptions|undefined>();
17
17
 
18
+ interface ListenerEntry {
19
+ listener: EventListenerOrEventListenerObject;
20
+ wrapper: EventListener;
21
+ }
22
+
23
+ const containerListeners = new WeakMap<HTMLElement|DocumentFragment, Map<string, ListenerEntry>>();
24
+
18
25
  export function render(template: unknown, container: HTMLElement|DocumentFragment, options?: RenderOptions):
19
26
  ReturnType<typeof Lit.render> {
20
27
  const host = container instanceof ShadowRoot ? container.host : container;
@@ -62,22 +69,49 @@ export function render(template: unknown, container: HTMLElement|DocumentFragmen
62
69
  }
63
70
  }
64
71
 
65
- const oldListeners = renderOptions.get(container)?.container?.listeners;
66
- const newListeners = options?.container?.listeners;
67
- if (oldListeners) {
68
- for (const [name, listener] of Object.entries(oldListeners)) {
69
- if (newListeners?.[name] !== listener) {
70
- host.removeEventListener(name, listener);
71
- }
72
- }
72
+ let listenersMap = containerListeners.get(container);
73
+ if (!listenersMap) {
74
+ listenersMap = new Map();
75
+ containerListeners.set(container, listenersMap);
73
76
  }
77
+
78
+ const newListeners = options?.container?.listeners;
74
79
  if (newListeners) {
75
80
  for (const [name, listener] of Object.entries(newListeners)) {
76
- if (oldListeners?.[name] !== listener) {
77
- host.addEventListener(name, listener);
81
+ const entry = listenersMap.get(name);
82
+ if (entry) {
83
+ entry.listener = listener;
84
+ } else {
85
+ let currentListener = listener;
86
+ const newEntry: ListenerEntry = {
87
+ get listener() {
88
+ return currentListener;
89
+ },
90
+ set listener(val: EventListenerOrEventListenerObject) {
91
+ currentListener = val;
92
+ },
93
+ wrapper: (event: Event) => {
94
+ if (typeof currentListener === 'function') {
95
+ return currentListener.call(host, event);
96
+ }
97
+ if (currentListener && 'handleEvent' in currentListener) {
98
+ return currentListener.handleEvent(event);
99
+ }
100
+ }
101
+ };
102
+ listenersMap.set(name, newEntry);
103
+ host.addEventListener(name, newEntry.wrapper);
78
104
  }
79
105
  }
80
106
  }
107
+
108
+ // Remove old listeners that are no longer present
109
+ for (const [name, entry] of listenersMap.entries()) {
110
+ if (!newListeners || !(name in newListeners)) {
111
+ host.removeEventListener(name, entry.wrapper);
112
+ listenersMap.delete(name);
113
+ }
114
+ }
81
115
  renderOptions.set(container, options);
82
116
  return Lit.render(template, container, options);
83
117
  }
@@ -1,11 +1,16 @@
1
- // Copyright 2025 The Chromium Authors
1
+ // Copyright 2026 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
+ import * as Platform from '../../core/platform/platform.js';
5
6
  import * as Lit from '../../third_party/lit/lit.js';
6
7
 
7
8
  const templates = new WeakMap<TemplateStringsArray, TemplateStringsArray>();
8
9
 
10
+ export function isLitDirective(value: unknown): value is {values: unknown[]} {
11
+ return Boolean(typeof value === 'object' && value && '_$litDirective$' in value && 'values' in value);
12
+ }
13
+
9
14
  export function html(strings: TemplateStringsArray, ...values: unknown[]): Lit.TemplateResult {
10
15
  let stripped = templates.get(strings);
11
16
  if (!stripped) {
@@ -16,7 +21,23 @@ export function html(strings: TemplateStringsArray, ...values: unknown[]): Lit.T
16
21
  }
17
22
  }
18
23
  templates.set(strings, stripped);
19
- return Lit.html(stripped, ...values);
24
+
25
+ const escapeValue = (val: unknown): unknown => {
26
+ if (typeof val === 'string') {
27
+ return Platform.StringUtilities.safeEscapeUnicode(val);
28
+ }
29
+ if (Array.isArray(val)) {
30
+ return val.map(escapeValue);
31
+ }
32
+ if (isLitDirective(val)) {
33
+ val.values = val.values.map(escapeValue);
34
+ return val;
35
+ }
36
+ return val;
37
+ };
38
+ const escapedValues = values.map(escapeValue);
39
+
40
+ return Lit.html(stripped, ...escapedValues);
20
41
  }
21
42
 
22
43
  function strip(strings: TemplateStringsArray): TemplateStringsArray {