chrome-devtools-frontend 1.0.1717709 → 1.0.1721762

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 (291) hide show
  1. package/.agents/rules/models-and-core/core-ai-agent-context-and-prompt-discipline.md +29 -0
  2. package/.agents/rules/models-and-core/core-cdp-and-extension-error-handling.md +34 -0
  3. package/.agents/rules/models-and-core/core-gn-build-and-module-layering.md +23 -0
  4. package/.agents/rules/models-and-core/core-runtime-neutrality-and-platform-utils.md +28 -0
  5. package/.agents/rules/models-and-core/core-sdk-model-and-target-lifecycle.md +35 -0
  6. package/.agents/rules/models-and-core/core-security-origin-and-capability-guards.md +33 -0
  7. package/.agents/rules/models-and-core/core-settings-and-storage-migration.md +31 -0
  8. package/.agents/rules/models-and-core/core-sourcemap-and-workspace-mapping.md +28 -0
  9. package/.agents/rules/models-and-core/core-trace-engine-handler-invariants.md +32 -0
  10. package/.agents/rules/models-and-core/core-trace-insight-models-and-timing-types.md +28 -0
  11. package/.agents/rules/tests/test-cleanup-mutated-globals-and-widgets.md +40 -0
  12. package/.agents/rules/tests/test-deterministic-async-synchronization.md +30 -0
  13. package/.agents/rules/tests/test-modular-hooks-and-test-universe.md +38 -0
  14. package/.agents/rules/tests/test-public-api-and-encapsulation.md +30 -0
  15. package/.agents/rules/tests/test-shared-fixture-and-helper-reuse.md +29 -0
  16. package/.agents/rules/tests/test-single-responsibility-and-conciseness.md +37 -0
  17. package/.agents/rules/tests/test-strict-assertions-and-literal-expectations.md +31 -0
  18. package/.agents/rules/tests/test-type-safe-mocks-and-events.md +30 -0
  19. package/.agents/rules/tests/test-view-and-presenter-isolation.md +32 -0
  20. package/.agents/rules/ui-and-widgets/ui-accessibility-and-semantic-html.md +32 -0
  21. package/.agents/rules/ui-and-widgets/ui-await-update-complete-post-render.md +30 -0
  22. package/.agents/rules/ui-and-widgets/ui-css-scoping-and-flex-layout.md +27 -0
  23. package/.agents/rules/ui-and-widgets/ui-declarative-child-widget-composition.md +29 -0
  24. package/.agents/rules/ui-and-widgets/ui-lit-declarative-templates-and-directives.md +33 -0
  25. package/.agents/rules/ui-and-widgets/ui-localization-and-uistrings-hygiene.md +36 -0
  26. package/.agents/rules/ui-and-widgets/ui-modern-component-and-encapsulation-standards.md +32 -0
  27. package/.agents/rules/ui-and-widgets/ui-panel-and-meta-registration.md +35 -0
  28. package/.agents/rules/ui-and-widgets/ui-performance-and-flamechart-rendering.md +34 -0
  29. package/.agents/rules/ui-and-widgets/ui-pure-view-and-presenter-separation.md +31 -0
  30. package/.agents/rules/ui-and-widgets/ui-reactive-widget-update-lifecycle.md +34 -0
  31. package/.agents/rules/ui-and-widgets/ui-security-and-output-sanitization.md +28 -0
  32. package/.agents/rules/ui-and-widgets/ui-type-safety-and-exhaustiveness.md +37 -0
  33. package/.agents/rules/ui-and-widgets/ui-view-output-and-callback-contracts.md +35 -0
  34. package/.agents/rules/ui-and-widgets/ui-visual-logging-instrumentation.md +29 -0
  35. package/.agents/rules/ui-and-widgets/ui-weak-dom-references-and-observer-cleanup.md +29 -0
  36. package/.agents/rules/ui-and-widgets/ui-widget-dom-and-listener-lifecycle.md +38 -0
  37. package/.agents/skills/code-review/SKILL.md +3 -0
  38. package/.agents/skills/devtools-testing-guidance/SKILL.md +1 -0
  39. package/.agents/skills/review-models-core/SKILL.md +73 -0
  40. package/.agents/skills/review-tests/SKILL.md +67 -0
  41. package/.agents/skills/review-ui-widgets/SKILL.md +115 -0
  42. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +19 -3
  43. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +2 -1
  44. package/.agents/skills/ui-widgets/SKILL.md +3 -1
  45. package/AUTHORS +3 -0
  46. package/DIR_METADATA +51 -1
  47. package/eslint.config.mjs +63 -21
  48. package/front_end/core/platform/api/HostRuntime.ts +1 -0
  49. package/front_end/core/platform/browser/HostRuntime.ts +10 -0
  50. package/front_end/core/platform/node/HostRuntime.ts +1 -0
  51. package/front_end/core/sdk/CSSMatchedStyles.ts +60 -20
  52. package/front_end/core/sdk/CSSProperty.ts +2 -2
  53. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +28 -9
  54. package/front_end/core/sdk/NetworkManager.ts +9 -3
  55. package/front_end/core/sdk/OverlayModel.ts +2 -8
  56. package/front_end/core/sdk/PrivateVerificationTokensModel.ts +79 -0
  57. package/front_end/core/sdk/SecurityOrigin.ts +1 -1
  58. package/front_end/core/sdk/SourceMapCache.ts +20 -15
  59. package/front_end/core/sdk/SourceMapManager.ts +28 -9
  60. package/front_end/core/sdk/TargetManager.ts +7 -4
  61. package/front_end/core/sdk/WebAuthnModel.ts +11 -2
  62. package/front_end/core/sdk/sdk.ts +2 -0
  63. package/front_end/entrypoints/inspector_main/InspectorMain.ts +0 -2
  64. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +10 -0
  65. package/front_end/entrypoints/main/GlobalAiButton.ts +1 -1
  66. package/front_end/entrypoints/main/MainImpl.ts +5 -2
  67. package/front_end/foundation/Universe.ts +1 -1
  68. package/front_end/generated/Deprecation.ts +4 -0
  69. package/front_end/generated/InspectorBackendCommands.ts +3 -3
  70. package/front_end/generated/SupportedCSSProperties.ts +89 -17
  71. package/front_end/generated/protocol-mapping.d.ts +1 -0
  72. package/front_end/generated/protocol-proxy-api.d.ts +1 -0
  73. package/front_end/generated/protocol.ts +5 -3
  74. package/front_end/models/{ai_assistance → ai-utils}/AiHistoryStorage.ts +6 -5
  75. package/front_end/models/{ai_assistance → ai-utils}/AiUtils.ts +9 -0
  76. package/front_end/models/{ai_assistance → ai-utils}/BuiltInAi.ts +1 -1
  77. package/front_end/models/ai-utils/ai-utils.ts +17 -0
  78. package/front_end/models/ai_assistance/AiAgent2.ts +3 -1
  79. package/front_end/models/ai_assistance/AiConversation.ts +34 -22
  80. package/front_end/models/ai_assistance/AlwaysAllowedTools.ts +107 -0
  81. package/front_end/models/ai_assistance/ConversationSummary.ts +2 -1
  82. package/front_end/models/ai_assistance/PerformanceAnnotations.ts +3 -1
  83. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +3 -1
  84. package/front_end/models/ai_assistance/agents/AiAgent.ts +15 -7
  85. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +3 -1
  86. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +3 -1
  87. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +1 -1
  88. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -1
  89. package/front_end/models/ai_assistance/ai_assistance.ts +9 -10
  90. package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +27 -6
  91. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +3 -3
  92. package/front_end/models/ai_assistance/skills/sources.md +3 -1
  93. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +1 -0
  94. package/front_end/models/ai_assistance/tools/GetCookieValues.ts +1 -0
  95. package/front_end/models/ai_assistance/tools/GetInsightDetails.ts +3 -1
  96. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +46 -4
  97. package/front_end/models/ai_assistance/tools/GetStorageValues.ts +1 -0
  98. package/front_end/models/ai_assistance/tools/Tool.ts +6 -0
  99. package/front_end/models/breakpoints/BreakpointManager.ts +0 -4
  100. package/front_end/models/change_tracker/ChangeTracker.ts +2 -0
  101. package/front_end/models/comment_manager/CommentManager.ts +12 -0
  102. package/front_end/models/comment_manager/CommentThread.ts +21 -1
  103. package/front_end/models/elements/ChangeTrackingUtils.ts +37 -0
  104. package/front_end/models/elements/DOMChanges.ts +24 -36
  105. package/front_end/models/elements/StyleChanges.ts +97 -0
  106. package/front_end/models/elements/elements.ts +4 -0
  107. package/front_end/models/emulation/DeviceModeModel.ts +19 -0
  108. package/front_end/models/javascript_metadata/NativeFunctions.ts +11 -1
  109. package/front_end/models/trace/EventsSerializer.ts +35 -2
  110. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +17 -21
  111. package/front_end/models/trace/helpers/SyntheticEvents.ts +4 -2
  112. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +12 -8
  113. package/front_end/models/trace/types/File.ts +20 -3
  114. package/front_end/models/trace/types/TraceEvents.ts +8 -3
  115. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +14 -0
  116. package/front_end/panels/ai_assistance/README.md +1 -1
  117. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +1 -1
  118. package/front_end/panels/ai_assistance/ai_assistance.ts +2 -0
  119. package/front_end/panels/ai_assistance/components/ChatInput.ts +5 -43
  120. package/front_end/panels/ai_assistance/components/ChatMessage.ts +52 -147
  121. package/front_end/panels/ai_assistance/components/ChatView.ts +28 -3
  122. package/front_end/panels/ai_assistance/components/PermissionPrompt.ts +151 -0
  123. package/front_end/panels/ai_assistance/components/RelevantDataDisclaimer.ts +73 -0
  124. package/front_end/panels/ai_assistance/components/chatInput.css +0 -59
  125. package/front_end/panels/ai_assistance/components/chatMessage.css +0 -47
  126. package/front_end/panels/ai_assistance/components/chatView.css +5 -30
  127. package/front_end/panels/ai_assistance/components/permissionPrompt.css +55 -0
  128. package/front_end/panels/ai_assistance/components/relevantDataDisclaimer.css +35 -0
  129. package/front_end/panels/application/ApplicationPanelSidebar.ts +3 -7
  130. package/front_end/panels/application/BackgroundServiceView.ts +8 -8
  131. package/front_end/panels/application/IndexedDBViews.ts +102 -73
  132. package/front_end/panels/application/OpenedWindowDetailsView.ts +167 -130
  133. package/front_end/panels/application/ServiceWorkerCacheViews.ts +288 -346
  134. package/front_end/panels/application/StorageBucketsTreeElement.ts +22 -27
  135. package/front_end/panels/application/StorageItemsToolbar.ts +2 -2
  136. package/front_end/panels/application/components/StorageMetadataView.ts +207 -160
  137. package/front_end/panels/application/openedWindowDetailsView.css +7 -30
  138. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +1 -1
  139. package/front_end/panels/changes/changesView.css +0 -6
  140. package/front_end/panels/console/ConsoleInsightTeaser.ts +5 -1
  141. package/front_end/panels/console/ConsolePinPane.ts +1 -1
  142. package/front_end/panels/console/ConsoleView.ts +1 -0
  143. package/front_end/panels/elements/CSSValueTraceView.ts +5 -5
  144. package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +14 -6
  145. package/front_end/panels/elements/ComputedStyleWidget.ts +14 -5
  146. package/front_end/panels/elements/DOMTreeElementWidget.ts +2 -2
  147. package/front_end/panels/elements/DOMTreeWidget.ts +7 -3
  148. package/front_end/panels/elements/EventListenersWidget.ts +1 -1
  149. package/front_end/panels/elements/LayersWidget.ts +1 -1
  150. package/front_end/panels/elements/PropertyRenderer.ts +91 -16
  151. package/front_end/panels/elements/StandaloneStylesContainer.ts +33 -6
  152. package/front_end/panels/elements/StylePropertiesSection.ts +1 -0
  153. package/front_end/panels/elements/StylePropertyTreeElement.ts +211 -121
  154. package/front_end/panels/elements/StylesContainer.ts +2 -0
  155. package/front_end/panels/elements/StylesSidebarPane.ts +34 -16
  156. package/front_end/panels/elements/components/QueryContainer.ts +1 -1
  157. package/front_end/panels/elements/elementStatePaneWidget.css +1 -1
  158. package/front_end/panels/elements/stylePropertiesTreeOutline.css +1 -1
  159. package/front_end/panels/elements/stylesSidebarPane.css +4 -0
  160. package/front_end/panels/emulation/DeviceModeToolbar.ts +57 -25
  161. package/front_end/panels/emulation/DeviceModeView.ts +27 -1
  162. package/front_end/panels/emulation/InspectedPagePlaceholder.ts +6 -0
  163. package/front_end/panels/emulation/MediaQueryInspector.ts +14 -4
  164. package/front_end/panels/explain/components/ConsoleInsight.ts +2 -3
  165. package/front_end/panels/explain/explain-meta.ts +1 -1
  166. package/front_end/panels/issues/AffectedMetadataAllowedSitesView.ts +67 -34
  167. package/front_end/panels/issues/issues.ts +2 -0
  168. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +7 -3
  169. package/front_end/panels/lighthouse/LighthouseController.ts +1 -1
  170. package/front_end/panels/media/PlayerMessagesView.ts +1 -1
  171. package/front_end/panels/mobile_throttling/CPUThrottlingSelector.ts +1 -1
  172. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +45 -15
  173. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +3 -3
  174. package/front_end/panels/network/BinaryResourceView.ts +54 -50
  175. package/front_end/panels/network/RequestHeadersView.ts +6 -2
  176. package/front_end/panels/network/RequestPreviewView.ts +28 -5
  177. package/front_end/panels/network/ResourceWebSocketFrameView.ts +1 -0
  178. package/front_end/panels/network/components/EditableSpan.ts +11 -30
  179. package/front_end/panels/network/components/HeaderSectionRow.ts +2 -2
  180. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +10 -6
  181. package/front_end/panels/profiler/HeapDetachedElementsView.ts +112 -22
  182. package/front_end/panels/profiler/HeapProfileView.ts +3 -3
  183. package/front_end/panels/profiler/HeapSnapshotView.ts +12 -2
  184. package/front_end/panels/profiler/HeapTimelineOverview.ts +16 -2
  185. package/front_end/panels/profiler/profiler.ts +0 -2
  186. package/front_end/panels/protocol_monitor/JSONEditor.ts +1 -1
  187. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +1 -1
  188. package/front_end/panels/recorder/CreateRecordingView.ts +1 -1
  189. package/front_end/panels/recorder/RecordingView.ts +3 -3
  190. package/front_end/panels/recorder/ReplaySection.ts +1 -1
  191. package/front_end/panels/screencast/ScreencastApp.ts +83 -57
  192. package/front_end/panels/screencast/screencastView.css +1 -1
  193. package/front_end/panels/settings/AISettingsTab.ts +107 -4
  194. package/front_end/panels/settings/aiSettingsTab.css +53 -0
  195. package/front_end/panels/settings/settings-meta.ts +1 -1
  196. package/front_end/panels/settings/settingsScreen.css +0 -4
  197. package/front_end/panels/sources/BreakpointsView.ts +2 -2
  198. package/front_end/panels/sources/DebuggerPlugin.ts +7 -0
  199. package/front_end/panels/sources/NavigatorView.ts +61 -18
  200. package/front_end/panels/sources/SourcesNavigator.ts +22 -7
  201. package/front_end/panels/sources/SourcesPanel.ts +1 -0
  202. package/front_end/panels/timeline/README.md +12 -0
  203. package/front_end/panels/timeline/StatusDialog.ts +1 -1
  204. package/front_end/panels/timeline/ThirdPartyTreeView.ts +1 -3
  205. package/front_end/panels/timeline/TimelineCommentController.ts +346 -0
  206. package/front_end/panels/timeline/TimelineDetailsView.ts +24 -1
  207. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +34 -30
  208. package/front_end/panels/timeline/TimelineFlameChartView.ts +22 -1
  209. package/front_end/panels/timeline/TimelinePanel.ts +12 -5
  210. package/front_end/panels/timeline/TimelineTreeView.ts +28 -6
  211. package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -1
  212. package/front_end/panels/timeline/components/fieldSettingsDialog.css +2 -2
  213. package/front_end/panels/timeline/components/insights/baseInsightComponent.css +1 -1
  214. package/front_end/panels/timeline/overlays/components/entriesLinkOverlay.css +2 -2
  215. package/front_end/panels/timeline/overlays/components/entryLabelOverlay.css +9 -9
  216. package/front_end/panels/timeline/timeline-meta.ts +2 -2
  217. package/front_end/panels/timeline/timeline.ts +4 -0
  218. package/front_end/panels/timeline/timelineFlamechartPopover.css +2 -2
  219. package/front_end/panels/timeline/timelinePanel.css +2 -2
  220. package/front_end/panels/web_audio/WebAudioView.ts +7 -4
  221. package/front_end/third_party/chromium/README.chromium +1 -1
  222. package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
  223. package/front_end/third_party/codemirror.next/chunk/angular.js.map +1 -1
  224. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  225. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  226. package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
  227. package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
  228. package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
  229. package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
  230. package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
  231. package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
  232. package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
  233. package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
  234. package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
  235. package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
  236. package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
  237. package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
  238. package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
  239. package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
  240. package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
  241. package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
  242. package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
  243. package/front_end/third_party/codemirror.next/chunk/vue.js.map +1 -1
  244. package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
  245. package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
  246. package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
  247. package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
  248. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  249. package/front_end/third_party/codemirror.next/rollup.config.mjs +1 -1
  250. package/front_end/tsconfig.json +1 -1
  251. package/front_end/ui/comments/CommentAnchorResolver.ts +1 -1
  252. package/front_end/ui/components/buttons/Button.ts +29 -18
  253. package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +1 -1
  254. package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +94 -39
  255. package/front_end/ui/components/dialogs/dialog.css +1 -1
  256. package/front_end/ui/components/menus/menuItem.css +11 -0
  257. package/front_end/ui/components/text_editor/AccessiblePlaceholder.ts +1 -1
  258. package/front_end/ui/components/text_editor/AiCodeCompletionTeaser.ts +1 -1
  259. package/front_end/ui/components/text_editor/config.ts +2 -1
  260. package/front_end/ui/components/text_editor/javascript.ts +2 -1
  261. package/front_end/ui/legacy/InspectorView.ts +4 -2
  262. package/front_end/ui/legacy/SplitWidget.ts +14 -16
  263. package/front_end/ui/legacy/TabbedPane.ts +9 -1
  264. package/front_end/ui/legacy/UIUtils.ts +60 -40
  265. package/front_end/ui/legacy/components/color_picker/spectrum.css +2 -2
  266. package/front_end/ui/legacy/components/data_grid/dataGrid.css +9 -0
  267. package/front_end/ui/legacy/components/inline_editor/CSSAngle.ts +0 -1
  268. package/front_end/ui/legacy/components/inline_editor/cssShadowEditor.css +5 -7
  269. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +1 -1
  270. package/front_end/ui/legacy/components/perf_ui/PieChart.ts +11 -0
  271. package/front_end/ui/legacy/components/perf_ui/chartViewport.css +4 -4
  272. package/front_end/ui/legacy/components/quick_open/filteredListWidget.css +6 -0
  273. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +1 -1
  274. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +38 -13
  275. package/front_end/ui/legacy/dropTarget.css +1 -1
  276. package/front_end/ui/legacy/statusBar.css +7 -0
  277. package/front_end/ui/legacy/tabbedPane.css +0 -7
  278. package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
  279. package/inspector_overlay/main.ts +2 -15
  280. package/inspector_overlay/tool_persistent.ts +0 -14
  281. package/mcp/mcp.ts +3 -0
  282. package/package.json +1 -1
  283. package/front_end/panels/ai_assistance/components/StylingAgentMarkdownRenderer.ts +0 -178
  284. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +0 -147
  285. package/front_end/panels/profiler/heapDetachedElementsDataGrid.css +0 -14
  286. package/front_end/ui/components/legacy_wrapper/LegacyWrapper.ts +0 -62
  287. package/front_end/ui/components/legacy_wrapper/legacy_wrapper.ts +0 -8
  288. package/inspector_overlay/tool_green_dev_anchors.css +0 -54
  289. package/inspector_overlay/tool_green_dev_anchors.ts +0 -164
  290. /package/front_end/models/{ai_assistance → ai-utils}/AiSetting.ts +0 -0
  291. /package/front_end/models/{ai_assistance → ai-utils}/debug.ts +0 -0
@@ -27,6 +27,7 @@ import {
27
27
  EnvFunctionMatcher,
28
28
  FlexGridGridLanesMatcher,
29
29
  GridTemplateMatcher,
30
+ ImportantMatcher,
30
31
  LengthMatcher,
31
32
  LightDarkColorMatcher,
32
33
  LinearGradientMatcher,
@@ -140,6 +141,10 @@ function cleanUserAgentPayload(payload: Protocol.CSS.RuleMatch[]): Protocol.CSS.
140
141
  }
141
142
  }
142
143
 
144
+ function parseCustomHighlightName(selectorText: string): string|null {
145
+ return selectorText.match(/::highlight\(([^)]+)\)/)?.[1] ?? null;
146
+ }
147
+
143
148
  /**
144
149
  * Return a mapping of the highlight names in the specified RuleMatch to
145
150
  * the indices of selectors in that selector list with that highlight name.
@@ -164,15 +169,15 @@ function cleanUserAgentPayload(payload: Protocol.CSS.RuleMatch[]): Protocol.CSS.
164
169
  * list associated with ruleMatch. The indices correspond to the selectors in the rule
165
170
  * associated with the key's highlight name.
166
171
  */
167
- function customHighlightNamesToMatchingSelectorIndices(ruleMatch: Protocol.CSS.RuleMatch): Map<string, number[]> {
172
+ function customHighlightNamesToMatchingSelectorIndices(ruleMatch: Protocol.CSS.RuleMatch,
173
+ highlightNames: Set<string>): Map<string, number[]> {
168
174
  const highlightNamesToMatchingSelectors = new Map<string, number[]>();
169
175
 
170
176
  for (let i = 0; i < ruleMatch.matchingSelectors.length; i++) {
171
177
  const matchingSelectorIndex = ruleMatch.matchingSelectors[i];
172
178
  const selectorText = ruleMatch.rule.selectorList.selectors[matchingSelectorIndex].text;
173
- const highlightNameMatch = selectorText.match(/::highlight\((.*)\)/);
174
- if (highlightNameMatch) {
175
- const highlightName = highlightNameMatch[1];
179
+ const highlightName = parseCustomHighlightName(selectorText);
180
+ if (highlightName) {
176
181
  const selectorsForName = highlightNamesToMatchingSelectors.get(highlightName);
177
182
  if (selectorsForName) {
178
183
  selectorsForName.push(matchingSelectorIndex);
@@ -181,9 +186,36 @@ function customHighlightNamesToMatchingSelectorIndices(ruleMatch: Protocol.CSS.R
181
186
  }
182
187
  }
183
188
  }
189
+
190
+ const universalSelectors = highlightNamesToMatchingSelectors.get('*');
191
+ if (universalSelectors) {
192
+ for (const highlightName of highlightNames) {
193
+ const selectorsForName = highlightNamesToMatchingSelectors.get(highlightName) ?? [];
194
+ highlightNamesToMatchingSelectors.set(highlightName, [...selectorsForName, ...universalSelectors]);
195
+ }
196
+ }
184
197
  return highlightNamesToMatchingSelectors;
185
198
  }
186
199
 
200
+ function getCustomHighlightNames(pseudoPayload: Protocol.CSS.PseudoElementMatches[]): Set<string> {
201
+ const highlightNames = new Set<string>();
202
+ for (const entryPayload of pseudoPayload) {
203
+ if (entryPayload.pseudoType !== Protocol.DOM.PseudoType.Highlight || !entryPayload.matches) {
204
+ continue;
205
+ }
206
+ for (const ruleMatch of entryPayload.matches) {
207
+ for (const matchingSelectorIndex of ruleMatch.matchingSelectors) {
208
+ const selectorText = ruleMatch.rule.selectorList.selectors[matchingSelectorIndex].text;
209
+ const highlightName = parseCustomHighlightName(selectorText);
210
+ if (highlightName && highlightName !== '*') {
211
+ highlightNames.add(highlightName);
212
+ }
213
+ }
214
+ }
215
+ }
216
+ return highlightNames;
217
+ }
218
+
187
219
  function queryMatches(style: CSSStyleDeclaration): boolean {
188
220
  if (!style.parentRule) {
189
221
  return true;
@@ -564,13 +596,14 @@ export class CSSMatchedStyles {
564
596
  * This helper function takes a list of rule matches and generates separate NodeCascades
565
597
  * for each custom highlight name that was matched.
566
598
  */
567
- private buildSplitCustomHighlightCascades(
568
- rules: Protocol.CSS.RuleMatch[], node: DOMNode, isInherited: boolean,
569
- pseudoCascades: Map<string, NodeCascade[]>): void {
599
+ private buildSplitCustomHighlightCascades(rules: Protocol.CSS.RuleMatch[], node: DOMNode, isInherited: boolean,
600
+ highlightNames: Set<string>,
601
+ pseudoCascades: Map<string, NodeCascade[]>): void {
570
602
  const splitHighlightRules = new Map<string, CSSStyleDeclaration[]>();
571
603
 
572
604
  for (let j = rules.length - 1; j >= 0; --j) {
573
- const highlightNamesToMatchingSelectorIndices = customHighlightNamesToMatchingSelectorIndices(rules[j]);
605
+ const highlightNamesToMatchingSelectorIndices =
606
+ customHighlightNamesToMatchingSelectorIndices(rules[j], highlightNames);
574
607
 
575
608
  for (const [highlightName, matchingSelectors] of highlightNamesToMatchingSelectorIndices) {
576
609
  const pseudoRule = new CSSStyleRule(this.#cssModel, rules[j].rule);
@@ -613,6 +646,8 @@ export class CSSMatchedStyles {
613
646
 
614
647
  const pseudoCascades = new Map<Protocol.DOM.PseudoType, NodeCascade[]>();
615
648
  const customHighlightPseudoCascades = new Map<string, NodeCascade[]>();
649
+ const highlightNames = getCustomHighlightNames(
650
+ [...pseudoPayload, ...(inheritedPseudoPayload || []).flatMap(entry => entry.pseudoElements)]);
616
651
  for (let i = 0; i < pseudoPayload.length; ++i) {
617
652
  const entryPayload = pseudoPayload[i];
618
653
  // PseudoElement nodes are not created unless "content" css property is set.
@@ -621,8 +656,8 @@ export class CSSMatchedStyles {
621
656
  const rules = entryPayload.matches || [];
622
657
 
623
658
  if (entryPayload.pseudoType === Protocol.DOM.PseudoType.Highlight) {
624
- this.buildSplitCustomHighlightCascades(
625
- rules, this.#node, false /* #isInherited */, customHighlightPseudoCascades);
659
+ this.buildSplitCustomHighlightCascades(rules, this.#node, false /* #isInherited */, highlightNames,
660
+ customHighlightPseudoCascades);
626
661
  } else {
627
662
  for (let j = rules.length - 1; j >= 0; --j) {
628
663
  const pseudoRule = new CSSStyleRule(this.#cssModel, rules[j].rule);
@@ -651,8 +686,8 @@ export class CSSMatchedStyles {
651
686
  const rules = inheritedEntryPayload.matches || [];
652
687
 
653
688
  if (inheritedEntryPayload.pseudoType === Protocol.DOM.PseudoType.Highlight) {
654
- this.buildSplitCustomHighlightCascades(
655
- rules, parentNode, true /* #isInherited */, customHighlightPseudoCascades);
689
+ this.buildSplitCustomHighlightCascades(rules, parentNode, true /* #isInherited */, highlightNames,
690
+ customHighlightPseudoCascades);
656
691
  } else {
657
692
  const pseudoStyles = [];
658
693
  for (let k = rules.length - 1; k >= 0; --k) {
@@ -1490,19 +1525,23 @@ class DOMInheritanceCascade {
1490
1525
  return null;
1491
1526
  }
1492
1527
 
1493
- if (definedValue.declaration.declaration instanceof CSSProperty && definedValue.declaration.value &&
1494
- CSSMetadata.isCSSWideKeyword(definedValue.declaration.value)) {
1495
- const resolvedProperty =
1496
- this.resolveGlobalKeyword(definedValue.declaration.declaration, definedValue.declaration.value);
1528
+ while (definedValue.declaration.declaration instanceof CSSProperty && definedValue.declaration.value) {
1529
+ const value = PropertyParser
1530
+ .matchDeclaration(`--${variableName}`, definedValue.declaration.value, [new ImportantMatcher()])
1531
+ ?.getComputedPropertyValueText()
1532
+ .trim();
1533
+ if (!value || !CSSMetadata.isCSSWideKeyword(value)) {
1534
+ break;
1535
+ }
1536
+ const resolvedProperty = this.resolveGlobalKeyword(definedValue.declaration.declaration, value);
1497
1537
  if (!resolvedProperty) {
1498
1538
  return definedValue;
1499
1539
  }
1500
1540
  const declaration = new CSSValueSource(resolvedProperty);
1501
- const {value} = declaration;
1502
- if (!value) {
1541
+ if (!declaration.value) {
1503
1542
  return definedValue;
1504
1543
  }
1505
- definedValue = {declaration, value};
1544
+ definedValue = {declaration, value: declaration.value};
1506
1545
  }
1507
1546
 
1508
1547
  const ast = PropertyParser.tokenizeDeclaration(`--${variableName}`, definedValue.value);
@@ -1623,9 +1662,10 @@ class DOMInheritanceCascade {
1623
1662
  }
1624
1663
  return evaluateFallback(match.fallback, match.matching);
1625
1664
  }),
1665
+ ...(declaration ? [new ImportantMatcher()] : []),
1626
1666
  ]);
1627
1667
  const decl = PropertyParser.ASTUtils.siblings(PropertyParser.ASTUtils.declValue(matching.ast.tree));
1628
- const declText = decl.length > 0 ? matching.getComputedTextRange(decl[0], decl[decl.length - 1]) : '';
1668
+ const declText = decl.length > 0 ? matching.getComputedTextRange(decl[0], decl[decl.length - 1]).trim() : '';
1629
1669
  const hasUnresolvedSubstitutions =
1630
1670
  decl.length > 0 && matching.hasUnresolvedSubstitutionsRange(decl[0], decl[decl.length - 1]);
1631
1671
  const computedText = hasUnresolvedSubstitutions ? null : declText;
@@ -18,7 +18,7 @@ import {
18
18
  type Matcher,
19
19
  stripComments,
20
20
  } from './CSSPropertyParser.js';
21
- import {CSSWideKeywordMatcher} from './CSSPropertyParserMatchers.js';
21
+ import {CSSWideKeywordMatcher, ImportantMatcher} from './CSSPropertyParserMatchers.js';
22
22
  import type {CSSStyleDeclaration} from './CSSStyleDeclaration.js';
23
23
  import {textEditorIndentSettingDescriptor} from './SDKSettings.js';
24
24
 
@@ -114,7 +114,7 @@ export class CSSProperty extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
114
114
  #matchers(matchedStyles: CSSMatchedStyles, computedStyles: Map<string, string>|null): Array<Matcher<Match>> {
115
115
  const matchers = matchedStyles.propertyMatchers(this.ownerStyle, computedStyles);
116
116
 
117
- matchers.push(new CSSWideKeywordMatcher(this, matchedStyles));
117
+ matchers.push(new CSSWideKeywordMatcher(this, matchedStyles), new ImportantMatcher());
118
118
  return matchers;
119
119
  }
120
120
 
@@ -360,6 +360,19 @@ export class TextMatcher extends TextMatcherBase {
360
360
  }
361
361
  }
362
362
 
363
+ export class ImportantMatch extends TextMatch {
364
+ override computedText = (): string => '';
365
+ }
366
+
367
+ const ImportantMatcherBase: MatcherClass<ImportantMatch> = matcherBase(ImportantMatch);
368
+ // clang-format off
369
+ export class ImportantMatcher extends ImportantMatcherBase {
370
+ // clang-format on
371
+ override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): ImportantMatch|null {
372
+ return node.name === 'Important' ? new ImportantMatch(matching.ast.text(node), node) : null;
373
+ }
374
+ }
375
+
363
376
  export class AngleMatch implements Match {
364
377
  constructor(readonly text: string, readonly node: CodeMirror.SyntaxNode) {
365
378
  }
@@ -1167,14 +1180,15 @@ export class FlexGridGridLanesMatcher extends FlexGridGridLanesMatcherBase {
1167
1180
  .map(node => matching.getComputedText(node).trim())
1168
1181
  .filter(value => value);
1169
1182
  const text = values.join(' ');
1183
+ const valueText = matching.ast.textRange(valueNodes[0], valueNodes[valueNodes.length - 1]);
1170
1184
  if (FlexGridGridLanesMatcher.FLEX.includes(text)) {
1171
- return new FlexGridGridLanesMatch(matching.ast.text(node), node, LayoutType.FLEX);
1185
+ return new FlexGridGridLanesMatch(valueText, node, LayoutType.FLEX);
1172
1186
  }
1173
1187
  if (FlexGridGridLanesMatcher.GRID.includes(text)) {
1174
- return new FlexGridGridLanesMatch(matching.ast.text(node), node, LayoutType.GRID);
1188
+ return new FlexGridGridLanesMatch(valueText, node, LayoutType.GRID);
1175
1189
  }
1176
1190
  if (FlexGridGridLanesMatcher.GRID_LANES.includes(text)) {
1177
- return new FlexGridGridLanesMatch(matching.ast.text(node), node, LayoutType.GRID_LANES);
1191
+ return new FlexGridGridLanesMatch(valueText, node, LayoutType.GRID_LANES);
1178
1192
  }
1179
1193
  return null;
1180
1194
  }
@@ -1360,7 +1374,11 @@ export class CSSWideKeywordMatch implements Match {
1360
1374
  return this.matchedStyles.resolveGlobalKeyword(this.property, this.text);
1361
1375
  }
1362
1376
  computedText?(): string|null {
1363
- return this.resolveProperty()?.value ?? null;
1377
+ return this.resolveProperty()
1378
+ ?.declaration.parseValue(this.matchedStyles, null)
1379
+ ?.getComputedPropertyValueText()
1380
+ .trim() ??
1381
+ null;
1364
1382
  }
1365
1383
  }
1366
1384
 
@@ -1379,6 +1397,7 @@ export class CSSWideKeywordMatcher extends CSSWideKeywordMatcherBase {
1379
1397
  }
1380
1398
 
1381
1399
  if (Array.from(ASTUtils.stripComments(ASTUtils.siblings(ASTUtils.declValue(parentNode))))
1400
+ .filter(child => child.name !== 'Important')
1382
1401
  .some(child => !ASTUtils.equals(child, node))) {
1383
1402
  return null;
1384
1403
  }
@@ -1416,18 +1435,17 @@ export class PositionTryMatcher extends PositionTryMatcherBase {
1416
1435
  let preamble: CodeMirror.SyntaxNode[] = [];
1417
1436
  const valueNodes = ASTUtils.siblings(ASTUtils.declValue(node));
1418
1437
  const fallbacks = ASTUtils.split(valueNodes);
1419
- if (matching.ast.propertyName === LinkableNameProperties.POSITION_TRY) {
1420
1438
  for (const [i, n] of fallbacks[0].entries()) {
1421
1439
  const computedText = matching.getComputedText(n);
1422
1440
  if (CSSMetadata.isCSSWideKeyword(computedText)) {
1423
1441
  return null;
1424
1442
  }
1425
- if (CSSMetadata.isPositionTryOrderKeyword(computedText)) {
1443
+ if (matching.ast.propertyName === LinkableNameProperties.POSITION_TRY &&
1444
+ CSSMetadata.isPositionTryOrderKeyword(computedText)) {
1426
1445
  preamble = fallbacks[0].splice(0, i + 1);
1427
1446
  break;
1428
1447
  }
1429
1448
  }
1430
- }
1431
1449
 
1432
1450
  const valueText = matching.ast.textRange(valueNodes[0], valueNodes[valueNodes.length - 1]);
1433
1451
  return new PositionTryMatch(valueText, node, preamble, fallbacks);
@@ -1493,10 +1511,11 @@ export class PositionAreaMatcher extends PositionAreaMatcherBase {
1493
1511
  if (valueNodes.length === 0) {
1494
1512
  return null;
1495
1513
  }
1496
- const valueText = matching.getComputedTextRange(valueNodes[0], valueNodes[valueNodes.length - 1]);
1497
- if (CSSMetadata.isCSSWideKeyword(valueText)) {
1514
+ const computedText = matching.getComputedTextRange(valueNodes[0], valueNodes[valueNodes.length - 1]).trim();
1515
+ if (CSSMetadata.isCSSWideKeyword(computedText)) {
1498
1516
  return null;
1499
1517
  }
1518
+ const valueText = matching.ast.textRange(valueNodes[0], valueNodes[valueNodes.length - 1]);
1500
1519
  return new PositionAreaMatch(valueText, node);
1501
1520
  }
1502
1521
  }
@@ -763,6 +763,11 @@ export class FetchDispatcher implements ProtocolProxyApi.FetchDispatcher {
763
763
  }
764
764
  }
765
765
 
766
+ function multicastMembership(event: Pick<Protocol.Network.DirectUDPSocketJoinedMulticastGroupEvent, 'IPAddress'>&
767
+ {sourceAddress?: string}): string {
768
+ return event.sourceAddress ? `${event.IPAddress}@${event.sourceAddress}` : event.IPAddress;
769
+ }
770
+
766
771
  export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
767
772
  readonly #manager: NetworkManager;
768
773
  readonly #multitargetNetworkManager: MultitargetNetworkManager;
@@ -1743,8 +1748,9 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
1743
1748
  if (!networkRequest.directSocketInfo.joinedMulticastGroups) {
1744
1749
  networkRequest.directSocketInfo.joinedMulticastGroups = new Set();
1745
1750
  }
1746
- if (!networkRequest.directSocketInfo.joinedMulticastGroups.has(event.IPAddress)) {
1747
- networkRequest.directSocketInfo.joinedMulticastGroups.add(event.IPAddress);
1751
+ const membership = multicastMembership(event);
1752
+ if (!networkRequest.directSocketInfo.joinedMulticastGroups.has(membership)) {
1753
+ networkRequest.directSocketInfo.joinedMulticastGroups.add(membership);
1748
1754
  this.updateNetworkRequest(networkRequest);
1749
1755
  }
1750
1756
  }
@@ -1754,7 +1760,7 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
1754
1760
  if (!networkRequest?.directSocketInfo?.joinedMulticastGroups) {
1755
1761
  return;
1756
1762
  }
1757
- if (networkRequest.directSocketInfo.joinedMulticastGroups.delete(event.IPAddress)) {
1763
+ if (networkRequest.directSocketInfo.joinedMulticastGroups.delete(multicastMembership(event))) {
1758
1764
  this.updateNetworkRequest(networkRequest);
1759
1765
  }
1760
1766
  }
@@ -887,12 +887,10 @@ export class OverlayModel extends SDKModel<EventTypes> implements ProtocolProxyA
887
887
  return await this.#windowControls.initializeStyleSheetText(url);
888
888
  }
889
889
 
890
- inspectPanelShowRequested({backendNodeId}: Protocol.Overlay.InspectPanelShowRequestedEvent): void {
891
- this.dispatchEventToListeners(Events.INSPECT_PANEL_SHOW_REQUESTED, backendNodeId);
890
+ inspectPanelShowRequested(_event: Protocol.Overlay.InspectPanelShowRequestedEvent): void {
892
891
  }
893
892
 
894
- inspectedElementWindowRestored({backendNodeId}: Protocol.Overlay.InspectedElementWindowRestoredEvent): void {
895
- this.dispatchEventToListeners(Events.INSPECTED_ELEMENT_WINDOW_RESTORED, backendNodeId);
893
+ inspectedElementWindowRestored(_event: Protocol.Overlay.InspectedElementWindowRestoredEvent): void {
896
894
  }
897
895
  }
898
896
 
@@ -1028,8 +1026,6 @@ export const enum Events {
1028
1026
  PERSISTENT_FLEX_CONTAINER_OVERLAY_STATE_CHANGED = 'PersistentFlexContainerOverlayStateChanged',
1029
1027
  PERSISTENT_SCROLL_SNAP_OVERLAY_STATE_CHANGED = 'PersistentScrollSnapOverlayStateChanged',
1030
1028
  PERSISTENT_CONTAINER_QUERY_OVERLAY_STATE_CHANGED = 'PersistentContainerQueryOverlayStateChanged',
1031
- INSPECT_PANEL_SHOW_REQUESTED = 'InspectPanelShowRequested',
1032
- INSPECTED_ELEMENT_WINDOW_RESTORED = 'InspectedElementWindowRestored',
1033
1029
  }
1034
1030
 
1035
1031
  export interface ChangedNodeId {
@@ -1046,8 +1042,6 @@ export interface EventTypes {
1046
1042
  [Events.PERSISTENT_FLEX_CONTAINER_OVERLAY_STATE_CHANGED]: ChangedNodeId;
1047
1043
  [Events.PERSISTENT_SCROLL_SNAP_OVERLAY_STATE_CHANGED]: ChangedNodeId;
1048
1044
  [Events.PERSISTENT_CONTAINER_QUERY_OVERLAY_STATE_CHANGED]: ChangedNodeId;
1049
- [Events.INSPECT_PANEL_SHOW_REQUESTED]: number;
1050
- [Events.INSPECTED_ELEMENT_WINDOW_RESTORED]: number;
1051
1045
  }
1052
1046
 
1053
1047
  export interface Highlighter {
@@ -0,0 +1,79 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
6
+ import type * as Protocol from '../../generated/protocol.js';
7
+
8
+ import {SDKModel} from './SDKModel.js';
9
+ import {Capability, type Target} from './Target.js';
10
+
11
+ export class PrivateVerificationTokensModel extends SDKModel<EventTypes> implements ProtocolProxyApi.StorageDispatcher {
12
+ readonly #storageAgent: ProtocolProxyApi.StorageApi;
13
+
14
+ constructor(target: Target) {
15
+ super(target);
16
+ target.registerStorageDispatcher(this);
17
+ this.#storageAgent = target.storageAgent();
18
+ }
19
+
20
+ setTracking(enable: boolean): void {
21
+ void this.#storageAgent.invoke_setPrivateVerificationTokensTracking({enable});
22
+ }
23
+
24
+ async getTokens(): Promise<Protocol.Storage.PrivateVerificationToken[]> {
25
+ const response = await this.#storageAgent.invoke_getPrivateVerificationTokens();
26
+ if (response.getError()) {
27
+ return [];
28
+ }
29
+ return response.tokens ?? [];
30
+ }
31
+
32
+ async getIssuerConfigs(): Promise<Protocol.Storage.PrivateVerificationTokensIssuerConfig[]> {
33
+ const response = await this.#storageAgent.invoke_getPrivateVerificationTokensIssuerConfigs();
34
+ if (response.getError()) {
35
+ return [];
36
+ }
37
+ return response.configs ?? [];
38
+ }
39
+
40
+ async clearTokens(issuerOrigin: string): Promise<void> {
41
+ await this.#storageAgent.invoke_clearPrivateVerificationTokens({issuerOrigin});
42
+ }
43
+
44
+ async deleteToken(tokenId: string): Promise<void> {
45
+ await this.#storageAgent.invoke_deletePrivateVerificationToken({tokenId});
46
+ }
47
+
48
+ privateVerificationTokensUpdated(): void {
49
+ this.dispatchEventToListeners(Events.TOKENS_UPDATED);
50
+ }
51
+
52
+ cacheStorageContentUpdated(_event: Protocol.Storage.CacheStorageContentUpdatedEvent): void {
53
+ }
54
+
55
+ cacheStorageListUpdated(_event: Protocol.Storage.CacheStorageListUpdatedEvent): void {
56
+ }
57
+
58
+ indexedDBContentUpdated(_event: Protocol.Storage.IndexedDBContentUpdatedEvent): void {
59
+ }
60
+
61
+ indexedDBListUpdated(_event: Protocol.Storage.IndexedDBListUpdatedEvent): void {
62
+ }
63
+
64
+ storageBucketCreatedOrUpdated(_event: Protocol.Storage.StorageBucketCreatedOrUpdatedEvent): void {
65
+ }
66
+
67
+ storageBucketDeleted(_event: Protocol.Storage.StorageBucketDeletedEvent): void {
68
+ }
69
+ }
70
+
71
+ SDKModel.register(PrivateVerificationTokensModel, {capabilities: Capability.STORAGE, autostart: false});
72
+
73
+ export const enum Events {
74
+ TOKENS_UPDATED = 'TokensUpdated',
75
+ }
76
+
77
+ export interface EventTypes {
78
+ [Events.TOKENS_UPDATED]: void;
79
+ }
@@ -113,7 +113,7 @@ export class SecurityOrigin {
113
113
 
114
114
  if (rawUrl.toLowerCase().startsWith('file://')) {
115
115
  const parsed = Common.ParsedURL.ParsedURL.fromString(rawUrl as Platform.DevToolsPath.UrlString);
116
- if (!parsed) {
116
+ if (!parsed || parsed.path === '/') {
117
117
  return SecurityOrigin.createUniqueOpaque();
118
118
  }
119
119
  const authority = parsed.host + (parsed.port ? ':' + parsed.port : '');
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as Platform from '../platform/platform.js';
6
6
 
7
+ import type {SecurityOrigin} from './SecurityOrigin.js';
7
8
  import type {DebugId, SourceMapV3} from './SourceMap.js';
8
9
 
9
10
  /** A thin wrapper around the Cache API to store source map JSONs keyed on Debug IDs */
@@ -27,20 +28,22 @@ export class SourceMapCache {
27
28
  this.#name = name;
28
29
  }
29
30
 
30
- async set(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString, sourceMap: SourceMapV3): Promise<void> {
31
- if (!securityOrigin || securityOrigin === 'file://') {
31
+ async set(debugId: DebugId, scriptOrigin: SecurityOrigin, loaderOrigin: SecurityOrigin,
32
+ sourceMap: SourceMapV3): Promise<void> {
33
+ if (scriptOrigin.isOpaque() || loaderOrigin.isOpaque()) {
32
34
  return;
33
35
  }
34
36
  const cache = await this.#cache();
35
- await cache?.put(SourceMapCache.#urlForDebugId(debugId, securityOrigin), new Response(JSON.stringify(sourceMap)));
37
+ await cache?.put(SourceMapCache.#urlForDebugId(debugId, scriptOrigin, loaderOrigin),
38
+ new Response(JSON.stringify(sourceMap)));
36
39
  }
37
40
 
38
- async get(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString): Promise<SourceMapV3|null> {
39
- if (!securityOrigin || securityOrigin === 'file://') {
41
+ async get(debugId: DebugId, scriptOrigin: SecurityOrigin, loaderOrigin: SecurityOrigin): Promise<SourceMapV3|null> {
42
+ if (scriptOrigin.isOpaque() || loaderOrigin.isOpaque()) {
40
43
  return null;
41
44
  }
42
45
  const cache = await this.#cache();
43
- const response = await cache?.match(SourceMapCache.#urlForDebugId(debugId, securityOrigin));
46
+ const response = await cache?.match(SourceMapCache.#urlForDebugId(debugId, scriptOrigin, loaderOrigin));
44
47
  return (await response?.json() as SourceMapV3 | undefined) ?? null;
45
48
  }
46
49
 
@@ -58,8 +61,9 @@ export class SourceMapCache {
58
61
  }
59
62
 
60
63
  /** The Cache API only allows URL as keys, so we construct a simple one. Given that we have our own cache, we have no risk of conflicting URLs */
61
- static #urlForDebugId(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString): string {
62
- return `http://debug.id/${encodeURIComponent(debugId)}?origin=${encodeURIComponent(securityOrigin)}`;
64
+ static #urlForDebugId(debugId: DebugId, scriptOrigin: SecurityOrigin, loaderOrigin: SecurityOrigin): string {
65
+ return `http://debug.id/${encodeURIComponent(debugId)}?origin=${encodeURIComponent(scriptOrigin.siteId())}&loader=${
66
+ encodeURIComponent(loaderOrigin.siteId())}`;
63
67
  }
64
68
 
65
69
  async disposeForTest(): Promise<void> {
@@ -70,21 +74,22 @@ export class SourceMapCache {
70
74
  const IN_MEMORY_INSTANCE = new (class implements Pick<SourceMapCache, 'get'|'set'|'disposeForTest'> {
71
75
  readonly #cache = new Map<string, SourceMapV3>();
72
76
 
73
- async set(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString, sourceMap: SourceMapV3): Promise<void> {
74
- if (!securityOrigin || securityOrigin === 'file://') {
77
+ async set(debugId: DebugId, scriptOrigin: SecurityOrigin, loaderOrigin: SecurityOrigin,
78
+ sourceMap: SourceMapV3): Promise<void> {
79
+ if (scriptOrigin.isOpaque() || loaderOrigin.isOpaque()) {
75
80
  return;
76
81
  }
77
- this.#cache.set(`${debugId}|${securityOrigin}`, sourceMap);
82
+ this.#cache.set(`${debugId}|${scriptOrigin.siteId()}|${loaderOrigin.siteId()}`, sourceMap);
78
83
  }
79
84
 
80
- async get(debugId: DebugId, securityOrigin: Platform.DevToolsPath.UrlString): Promise<SourceMapV3|null> {
81
- if (!securityOrigin || securityOrigin === 'file://') {
85
+ async get(debugId: DebugId, scriptOrigin: SecurityOrigin, loaderOrigin: SecurityOrigin): Promise<SourceMapV3|null> {
86
+ if (scriptOrigin.isOpaque() || loaderOrigin.isOpaque()) {
82
87
  return null;
83
88
  }
84
- return this.#cache.get(`${debugId}|${securityOrigin}`) ?? null;
89
+ return this.#cache.get(`${debugId}|${scriptOrigin.siteId()}|${loaderOrigin.siteId()}`) ?? null;
85
90
  }
86
91
 
87
92
  async disposeForTest(): Promise<void> {
88
- // Do nothing.
93
+ this.#cache.clear();
89
94
  }
90
95
  })();
@@ -7,6 +7,7 @@ import * as Platform from '../platform/platform.js';
7
7
 
8
8
  import type {FrameAssociated} from './FrameAssociated.js';
9
9
  import {PageResourceLoader, type PageResourceLoadInitiator, type ResourceLoader} from './PageResourceLoader.js';
10
+ import {ResourceTreeModel} from './ResourceTreeModel.js';
10
11
  import {SecurityOrigin} from './SecurityOrigin.js';
11
12
  import {type DebugId, parseSourceMap, SourceMap, type SourceMapProvenance, type SourceMapV3} from './SourceMap.js';
12
13
  import {SourceMapCache} from './SourceMapCache.js';
@@ -216,24 +217,42 @@ export class SourceMapManager<T extends FrameAssociated> extends Common.ObjectWr
216
217
  }
217
218
  }
218
219
 
219
- function getCacheOrigin(initiator: PageResourceLoadInitiator): Platform.DevToolsPath.UrlString|null {
220
+ function getScriptOrigin(initiator: PageResourceLoadInitiator): SecurityOrigin|null {
220
221
  if (!initiator.initiatorUrl) {
221
222
  return null;
222
223
  }
223
- const securityOrigin = SecurityOrigin.create(initiator.initiatorUrl);
224
- if (securityOrigin.isOpaque() || (securityOrigin.isFile() && securityOrigin.siteId() === 'file:///')) {
224
+ const origin = SecurityOrigin.create(initiator.initiatorUrl);
225
+ return origin.isOpaque() ? null : origin;
226
+ }
227
+
228
+ function getLoaderOrigin(initiator: PageResourceLoadInitiator): SecurityOrigin|null {
229
+ if (!initiator.target) {
230
+ return null;
231
+ }
232
+ const resourceTreeModel = initiator.target.model(ResourceTreeModel);
233
+ if (resourceTreeModel) {
234
+ if (!initiator.frameId) {
235
+ return null;
236
+ }
237
+ const origin = resourceTreeModel.frameForId(initiator.frameId)?.securityOrigin() ?? null;
238
+ return origin && !origin.isOpaque() ? origin : null;
239
+ }
240
+ const targetUrl = initiator.target.inspectedURL() || initiator.target.targetInfo()?.url;
241
+ if (!targetUrl) {
225
242
  return null;
226
243
  }
227
- return securityOrigin.siteId() as Platform.DevToolsPath.UrlString;
244
+ const origin = SecurityOrigin.create(targetUrl);
245
+ return origin.isOpaque() ? null : origin;
228
246
  }
229
247
 
230
248
  async function loadSourceMap(resourceLoader: ResourceLoader, sourceMapCache: SourceMapCache,
231
249
  url: Platform.DevToolsPath.UrlString, debugId: DebugId|null,
232
250
  initiator: PageResourceLoadInitiator): Promise<SourceMapV3> {
233
251
  try {
234
- const cacheOrigin = debugId ? getCacheOrigin(initiator) : null;
235
- if (debugId && cacheOrigin) {
236
- const cachedSourceMap = await sourceMapCache.get(debugId, cacheOrigin);
252
+ const scriptOrigin = debugId ? getScriptOrigin(initiator) : null;
253
+ const loaderOrigin = debugId ? getLoaderOrigin(initiator) : null;
254
+ if (debugId && scriptOrigin && loaderOrigin) {
255
+ const cachedSourceMap = await sourceMapCache.get(debugId, scriptOrigin, loaderOrigin);
237
256
  if (cachedSourceMap) {
238
257
  return cachedSourceMap;
239
258
  }
@@ -241,9 +260,9 @@ async function loadSourceMap(resourceLoader: ResourceLoader, sourceMapCache: Sou
241
260
 
242
261
  const {content} = await resourceLoader.loadResource(url, initiator);
243
262
  const sourceMap = parseSourceMap(content);
244
- if (debugId && cacheOrigin && 'debugId' in sourceMap && sourceMap.debugId === debugId) {
263
+ if (debugId && scriptOrigin && loaderOrigin && 'debugId' in sourceMap && sourceMap.debugId === debugId) {
245
264
  // In case something goes wrong with updating the cache, we still want to use the source map.
246
- await sourceMapCache.set(sourceMap.debugId as DebugId, cacheOrigin, sourceMap).catch();
265
+ await sourceMapCache.set(sourceMap.debugId as DebugId, scriptOrigin, loaderOrigin, sourceMap).catch(() => {});
247
266
  }
248
267
  return sourceMap;
249
268
  } catch (cause) {
@@ -264,15 +264,18 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
264
264
  if (!this.#modelListeners.has(eventType)) {
265
265
  return;
266
266
  }
267
- let wrappedListener = null;
267
+ const wrappedListeners: Array<Common.EventTarget.EventListener<Events, T>> = [];
268
268
  for (const info of this.#modelListeners.get(eventType)) {
269
269
  if (info.modelClass === modelClass && info.listener === listener && info.thisObject === thisObject) {
270
- wrappedListener = info.wrappedListener;
270
+ wrappedListeners.push(info.wrappedListener);
271
271
  this.#modelListeners.delete(eventType, info);
272
272
  }
273
273
  }
274
- if (wrappedListener) {
275
- for (const model of this.models(modelClass)) {
274
+ if (wrappedListeners.length === 0) {
275
+ return;
276
+ }
277
+ for (const model of this.models(modelClass)) {
278
+ for (const wrappedListener of wrappedListeners) {
276
279
  model.removeEventListener(eventType, wrappedListener);
277
280
  }
278
281
  }
@@ -30,9 +30,9 @@ export class WebAuthnModel extends SDKModel<EventTypes> {
30
30
  target.registerWebAuthnDispatcher(new WebAuthnDispatcher(this));
31
31
  }
32
32
 
33
- setVirtualAuthEnvEnabled(enable: boolean): Promise<Object> {
33
+ setVirtualAuthEnvEnabled(enable: boolean, enableUI = true): Promise<Object> {
34
34
  if (enable) {
35
- return this.#agent.invoke_enable({enableUI: true});
35
+ return this.#agent.invoke_enable({enableUI});
36
36
  }
37
37
  return this.#agent.invoke_disable();
38
38
  }
@@ -52,6 +52,15 @@ export class WebAuthnModel extends SDKModel<EventTypes> {
52
52
  await this.#agent.invoke_setAutomaticPresenceSimulation({authenticatorId, enabled});
53
53
  }
54
54
 
55
+ async setUserVerified(authenticatorId: Protocol.WebAuthn.AuthenticatorId, isUserVerified: boolean): Promise<void> {
56
+ await this.#agent.invoke_setUserVerified({authenticatorId, isUserVerified});
57
+ }
58
+
59
+ async addCredential(authenticatorId: Protocol.WebAuthn.AuthenticatorId,
60
+ credential: Protocol.WebAuthn.Credential): Promise<void> {
61
+ await this.#agent.invoke_addCredential({authenticatorId, credential});
62
+ }
63
+
55
64
  async getCredentials(authenticatorId: Protocol.WebAuthn.AuthenticatorId): Promise<Protocol.WebAuthn.Credential[]> {
56
65
  const response = await this.#agent.invoke_getCredentials({authenticatorId});
57
66
  return response.credentials;
@@ -68,6 +68,7 @@ import * as PageResourceLoader from './PageResourceLoader.js';
68
68
  import * as PaintProfiler from './PaintProfiler.js';
69
69
  import * as PerformanceMetricsModel from './PerformanceMetricsModel.js';
70
70
  import * as PreloadingModel from './PreloadingModel.js';
71
+ import * as PrivateVerificationTokensModel from './PrivateVerificationTokensModel.js';
71
72
  import * as RehydratingConnection from './RehydratingConnection.js';
72
73
  import * as RehydratingObject from './RehydratingObject.js';
73
74
  import * as RemoteObject from './RemoteObject.js';
@@ -159,6 +160,7 @@ export {
159
160
  PaintProfiler,
160
161
  PerformanceMetricsModel,
161
162
  PreloadingModel,
163
+ PrivateVerificationTokensModel,
162
164
  RehydratingConnection, // TODO(crbug.com/444191656): Exported for tests.
163
165
  RehydratingObject,
164
166
  RemoteObject,