chrome-devtools-frontend 1.0.1650232 → 1.0.1651641
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.
- package/.agents/skills/version-control/SKILL.md +5 -1
- package/config/typescript/tsconfig.base.json +1 -0
- package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -1
- package/front_end/core/host/UserMetrics.ts +0 -11
- package/front_end/core/sdk/CSSMatchedStyles.ts +20 -4
- package/front_end/devtools_compatibility.js +1 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +94 -0
- package/front_end/foundation/Universe.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +4 -1
- package/front_end/generated/SupportedCSSProperties.js +284 -0
- package/front_end/generated/protocol-mapping.d.ts +7 -0
- package/front_end/generated/protocol-proxy-api.d.ts +5 -0
- package/front_end/generated/protocol.ts +60 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +11 -1
- package/front_end/models/ai_assistance/README.md +4 -0
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +2 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +3 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +2 -0
- package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
- package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
- package/front_end/models/ai_assistance/skills/SkillRegistry.ts +2 -0
- package/front_end/models/ai_assistance/skills/accessibility.md +13 -0
- package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +54 -0
- package/front_end/models/ai_assistance/tools/ResolveLighthousePath.ts +124 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +12 -2
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +4 -0
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +14 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +4 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
- package/front_end/models/persistence/NetworkPersistenceManager.ts +9 -1
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -11
- package/front_end/panels/common/ExtensionServer.ts +70 -50
- package/front_end/panels/elements/CSSSpecificityBreakdown.ts +106 -0
- package/front_end/panels/elements/ElementsPanel.ts +1 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +40 -13
- package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -5
- package/front_end/panels/elements/components/CSSQuery.ts +119 -4
- package/front_end/panels/elements/elements.ts +3 -0
- package/front_end/panels/elements/stylesSidebarPane.css +34 -0
- package/front_end/panels/js_timeline/js_timeline-meta.ts +1 -2
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +0 -3
- package/front_end/panels/network/RequestHeadersView.ts +2 -2
- package/front_end/panels/network/components/RequestHeadersView.css +1 -0
- package/front_end/panels/network/components/ResponseHeaderSection.css +5 -1
- package/front_end/panels/recorder/testing/RecorderHelpers.ts +2 -0
- package/front_end/panels/timeline/timeline-meta.ts +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/README.md +14 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +60 -24
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +271 -164
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +2 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +11 -7
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.js +3 -10
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +9 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/WebWorker.d.ts +13 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/WebWorker.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/WebWorker.js +14 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/WebWorker.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js +5 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserConnector.js +5 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserContext.js +6 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Deserializer.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Deserializer.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/ExposedFunction.js +6 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/ExposedFunction.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Frame.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/BrowsingContext.js +11 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Binding.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Binding.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +13 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/BrowserConnector.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Coverage.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Coverage.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ElementHandle.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +25 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ExecutionContext.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ExecutionContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Extension.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Extension.js +9 -11
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Extension.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/FrameManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/FrameManager.js +7 -7
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/FrameManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/JSHandle.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/JSHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +18 -10
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +17 -11
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js +28 -10
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.js +10 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.d.ts +3 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.js +20 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +11 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/CallbackRegistry.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/CallbackRegistry.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Configuration.d.ts +4 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Configuration.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +26 -13
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts +1 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js +24 -33
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +8 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +8 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/environment.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/environment.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/environment.js +4 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/environment.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/TextContent.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/TextContent.js +15 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/TextContent.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +17 -16
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js +14 -9
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/FirefoxLauncher.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/FirefoxLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/PipeTransport.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/PipeTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts +20 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js +38 -9
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node-env-setup.d.ts +7 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node-env-setup.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node-env-setup.js +16 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node-env-setup.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/puppeteer-core.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/puppeteer-core.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/puppeteer-core.js +3 -8
- package/front_end/third_party/puppeteer/package/lib/puppeteer/puppeteer-core.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +60 -24
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +4 -8
- package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +10 -10
- package/front_end/third_party/puppeteer/package/src/api/JSHandle.ts +3 -10
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +14 -8
- package/front_end/third_party/puppeteer/package/src/api/WebWorker.ts +30 -0
- package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +5 -5
- package/front_end/third_party/puppeteer/package/src/bidi/BidiOverCdp.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/bidi/BrowserConnector.ts +5 -3
- package/front_end/third_party/puppeteer/package/src/bidi/BrowserContext.ts +6 -6
- package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +4 -4
- package/front_end/third_party/puppeteer/package/src/bidi/Deserializer.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/bidi/ExposedFunction.ts +6 -6
- package/front_end/third_party/puppeteer/package/src/bidi/Frame.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +4 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Realm.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +11 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +6 -4
- package/front_end/third_party/puppeteer/package/src/cdp/Binding.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +14 -2
- package/front_end/third_party/puppeteer/package/src/cdp/BrowserConnector.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/cdp/Connection.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/cdp/Coverage.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/cdp/ElementHandle.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +36 -4
- package/front_end/third_party/puppeteer/package/src/cdp/ExecutionContext.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/cdp/Extension.ts +16 -17
- package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/cdp/FrameManager.ts +12 -7
- package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/JSHandle.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +22 -11
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +18 -10
- package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +37 -12
- package/front_end/third_party/puppeteer/package/src/cdp/WebMCP.ts +11 -9
- package/front_end/third_party/puppeteer/package/src/cdp/WebWorker.ts +33 -5
- package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +11 -0
- package/front_end/third_party/puppeteer/package/src/common/BrowserWebSocketTransport.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/common/CallbackRegistry.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/common/Configuration.ts +4 -2
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +26 -13
- package/front_end/third_party/puppeteer/package/src/common/Debug.ts +30 -40
- package/front_end/third_party/puppeteer/package/src/common/EventEmitter.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/common/util.ts +9 -1
- package/front_end/third_party/puppeteer/package/src/environment.ts +7 -3
- package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/injected/TextContent.ts +15 -5
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +23 -23
- package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +19 -13
- package/front_end/third_party/puppeteer/package/src/node/FirefoxLauncher.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/node/PipeTransport.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/node/ScreenRecorder.ts +44 -9
- package/front_end/third_party/puppeteer/package/src/node-env-setup.ts +18 -0
- package/front_end/third_party/puppeteer/package/src/puppeteer-core.ts +5 -9
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/third_party/puppeteer/puppeteer-tsconfig.json +1 -0
- package/front_end/tsconfig.json +1 -2
- package/inspector_overlay/tsconfig.json +3 -10
- package/mcp/tsconfig.json +1 -5
- package/package.json +1 -2
|
@@ -85,7 +85,8 @@ export class HostsPolicy {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
class RegisteredExtension {
|
|
88
|
-
constructor(readonly
|
|
88
|
+
constructor(readonly origin: string, readonly name: string, readonly hostsPolicy: HostsPolicy,
|
|
89
|
+
readonly allowFileAccess: boolean) {
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
isAllowedOnTarget(inspectedURL?: Platform.DevToolsPath.UrlString): boolean {
|
|
@@ -104,6 +105,14 @@ class RegisteredExtension {
|
|
|
104
105
|
return false;
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
if (parsedURL.protocol === 'chrome-extension:') {
|
|
109
|
+
if (parsedURL.origin !== this.origin) {
|
|
110
|
+
if (!Root.Runtime.hostConfig.extensionsOnChromeUrls?.enabled) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
107
116
|
if (!ExtensionServer.canInspectURL(inspectedURL)) {
|
|
108
117
|
return false;
|
|
109
118
|
}
|
|
@@ -953,27 +962,45 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
953
962
|
*/
|
|
954
963
|
private extensionAllowedOnContentProvider(
|
|
955
964
|
contentProvider: TextUtils.ContentProvider.ContentProvider, port: MessagePort): boolean {
|
|
956
|
-
|
|
957
|
-
|
|
965
|
+
// 1. Exception for Scripts with sourceURL
|
|
966
|
+
if (contentProvider instanceof Workspace.UISourceCode.UISourceCode &&
|
|
967
|
+
contentProvider.contentType() === Common.ResourceType.resourceTypes.Script) {
|
|
968
|
+
const scripts =
|
|
969
|
+
Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().scriptsForUISourceCode(contentProvider);
|
|
970
|
+
if (scripts.length > 0) {
|
|
971
|
+
const uiSourceCodeTarget =
|
|
972
|
+
Bindings.NetworkProject.NetworkProject.targetForUISourceCode(contentProvider) ?? undefined;
|
|
973
|
+
if (uiSourceCodeTarget && !this.extensionAllowedOnTarget(uiSourceCodeTarget, port)) {
|
|
974
|
+
return false;
|
|
975
|
+
}
|
|
976
|
+
return scripts.every(script => {
|
|
977
|
+
if (script.hasSourceURL) {
|
|
978
|
+
return this.extensionAllowedOnTarget(script.target(), port);
|
|
979
|
+
}
|
|
980
|
+
return this.extensionAllowedOnURL(script.contentURL(), port) &&
|
|
981
|
+
this.extensionAllowedOnTarget(script.target(), port);
|
|
982
|
+
});
|
|
983
|
+
}
|
|
958
984
|
}
|
|
959
985
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
986
|
+
// 2. Standard Policy: Both URL and Target must be allowed
|
|
987
|
+
|
|
988
|
+
// 2a. Check URL
|
|
989
|
+
if (!this.extensionAllowedOnURL(contentProvider.contentURL(), port)) {
|
|
990
|
+
return false;
|
|
963
991
|
}
|
|
964
992
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
if (
|
|
968
|
-
|
|
993
|
+
// 2b. Check Target (if one can be identified)
|
|
994
|
+
let target: SDK.Target.Target|undefined;
|
|
995
|
+
if (contentProvider instanceof SDK.NetworkRequest.NetworkRequest) {
|
|
996
|
+
target = SDK.NetworkManager.NetworkManager.forRequest(contentProvider)?.target();
|
|
997
|
+
} else if (contentProvider instanceof SDK.Resource.Resource) {
|
|
998
|
+
target = contentProvider.frame()?.resourceTreeModel().target();
|
|
999
|
+
} else if (contentProvider instanceof Workspace.UISourceCode.UISourceCode) {
|
|
1000
|
+
target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(contentProvider) ?? undefined;
|
|
969
1001
|
}
|
|
970
1002
|
|
|
971
|
-
return
|
|
972
|
-
if (script.hasSourceURL) {
|
|
973
|
-
return this.extensionAllowedOnTarget(script.target(), port);
|
|
974
|
-
}
|
|
975
|
-
return this.extensionAllowedOnURL(script.contentURL(), port);
|
|
976
|
-
});
|
|
1003
|
+
return !target || this.extensionAllowedOnTarget(target, port);
|
|
977
1004
|
}
|
|
978
1005
|
|
|
979
1006
|
/**
|
|
@@ -998,7 +1025,10 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
998
1025
|
return {uiSourceCode};
|
|
999
1026
|
}
|
|
1000
1027
|
|
|
1001
|
-
private extensionAllowedOnTarget(target: SDK.Target.Target, port: MessagePort): boolean {
|
|
1028
|
+
private extensionAllowedOnTarget(target: SDK.Target.Target|undefined, port: MessagePort): boolean {
|
|
1029
|
+
if (!target) {
|
|
1030
|
+
return false;
|
|
1031
|
+
}
|
|
1002
1032
|
return this.extensionAllowedOnURL(target.inspectedURL(), port);
|
|
1003
1033
|
}
|
|
1004
1034
|
|
|
@@ -1061,7 +1091,7 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
1061
1091
|
return this.status.E_BADARG('command', `expected ${Extensions.ExtensionAPI.PrivateAPI.Commands.GetHAR}`);
|
|
1062
1092
|
}
|
|
1063
1093
|
const requests =
|
|
1064
|
-
Logs.NetworkLog.NetworkLog.instance().requests().filter(r => this.
|
|
1094
|
+
Logs.NetworkLog.NetworkLog.instance().requests().filter(r => this.extensionAllowedOnContentProvider(r, port));
|
|
1065
1095
|
const harLog = await HAR.Log.Log.build(requests, {sanitize: false});
|
|
1066
1096
|
for (let i = 0; i < harLog.entries.length; ++i) {
|
|
1067
1097
|
// @ts-expect-error
|
|
@@ -1310,26 +1340,34 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
1310
1340
|
|
|
1311
1341
|
private notifyResourceAdded(event: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void {
|
|
1312
1342
|
const uiSourceCode = event.data;
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1343
|
+
const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(uiSourceCode);
|
|
1344
|
+
const targetUrl = target?.inspectedURL();
|
|
1345
|
+
this.postNotification(Extensions.ExtensionAPI.PrivateAPI.Events.ResourceAdded, [this.makeResource(uiSourceCode)],
|
|
1346
|
+
extension => extension.isAllowedOnTarget(uiSourceCode.url()) &&
|
|
1347
|
+
(!targetUrl || extension.isAllowedOnTarget(targetUrl)));
|
|
1316
1348
|
}
|
|
1317
1349
|
|
|
1318
1350
|
private notifyUISourceCodeContentCommitted(
|
|
1319
1351
|
event: Common.EventTarget.EventTargetEvent<Workspace.Workspace.WorkingCopyCommittedEvent>): void {
|
|
1320
1352
|
const {uiSourceCode, content} = event.data;
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1353
|
+
const target = Bindings.NetworkProject.NetworkProject.targetForUISourceCode(uiSourceCode);
|
|
1354
|
+
const targetUrl = target?.inspectedURL();
|
|
1355
|
+
this.postNotification(Extensions.ExtensionAPI.PrivateAPI.Events.ResourceContentCommitted,
|
|
1356
|
+
[this.makeResource(uiSourceCode), content],
|
|
1357
|
+
extension => extension.isAllowedOnTarget(uiSourceCode.url()) &&
|
|
1358
|
+
(!targetUrl || extension.isAllowedOnTarget(targetUrl)));
|
|
1324
1359
|
}
|
|
1325
1360
|
|
|
1326
1361
|
private async notifyRequestFinished(event: Common.EventTarget.EventTargetEvent<SDK.NetworkRequest.NetworkRequest>):
|
|
1327
1362
|
Promise<void> {
|
|
1328
1363
|
const request = event.data;
|
|
1329
1364
|
const entry = await HAR.Log.Entry.build(request, {sanitize: false});
|
|
1365
|
+
const networkManager = SDK.NetworkManager.NetworkManager.forRequest(request);
|
|
1366
|
+
const targetUrl = networkManager?.target()?.inspectedURL();
|
|
1330
1367
|
this.postNotification(
|
|
1331
1368
|
Extensions.ExtensionAPI.PrivateAPI.Events.NetworkRequestFinished, [this.requestId(request), entry],
|
|
1332
|
-
extension => extension.isAllowedOnTarget(entry.request.url)
|
|
1369
|
+
extension => extension.isAllowedOnTarget(entry.request.url as Platform.DevToolsPath.UrlString) &&
|
|
1370
|
+
(!targetUrl || extension.isAllowedOnTarget(targetUrl)));
|
|
1333
1371
|
}
|
|
1334
1372
|
|
|
1335
1373
|
private notifyElementsSelectionChanged(): void {
|
|
@@ -1388,7 +1426,8 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
1388
1426
|
const startPageURL = new URL((startPage));
|
|
1389
1427
|
const extensionOrigin = startPageURL.origin;
|
|
1390
1428
|
const name = extensionInfo.name || `Extension ${extensionOrigin}`;
|
|
1391
|
-
const extensionRegistration =
|
|
1429
|
+
const extensionRegistration =
|
|
1430
|
+
new RegisteredExtension(extensionOrigin, name, hostsPolicy, Boolean(extensionInfo.allowFileAccess));
|
|
1392
1431
|
if (!extensionRegistration.isAllowedOnTarget(inspectedURL)) {
|
|
1393
1432
|
this.#pendingExtensions.push(extensionInfo);
|
|
1394
1433
|
return;
|
|
@@ -1494,11 +1533,11 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
1494
1533
|
private registerAutosubscriptionTargetManagerHandler<Events, T extends keyof Events>(
|
|
1495
1534
|
eventTopic: string, modelClass: new(arg1: SDK.Target.Target) => SDK.SDKModel.SDKModel<Events>,
|
|
1496
1535
|
frontendEventType: T, handler: Common.EventTarget.EventListener<Events, T>): void {
|
|
1497
|
-
this.registerSubscriptionHandler(
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1536
|
+
this.registerSubscriptionHandler(eventTopic,
|
|
1537
|
+
() => SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
1538
|
+
modelClass, frontendEventType, handler, this, {scoped: true}),
|
|
1539
|
+
() => SDK.TargetManager.TargetManager.instance().removeModelListener(
|
|
1540
|
+
modelClass, frontendEventType, handler, this));
|
|
1502
1541
|
}
|
|
1503
1542
|
|
|
1504
1543
|
private registerResourceContentCommittedHandler(
|
|
@@ -1609,25 +1648,6 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
1609
1648
|
return this.status.E_FAILED('Permission denied');
|
|
1610
1649
|
}
|
|
1611
1650
|
|
|
1612
|
-
try {
|
|
1613
|
-
const parsedUrl = new URL(frame.url);
|
|
1614
|
-
let targetType = Host.UserMetrics.ExtensionEvalTarget.WEB_PAGE;
|
|
1615
|
-
if (parsedUrl.protocol === 'chrome-extension:') {
|
|
1616
|
-
if (parsedUrl.origin === securityOrigin) {
|
|
1617
|
-
targetType = Host.UserMetrics.ExtensionEvalTarget.SAME_EXTENSION;
|
|
1618
|
-
} else {
|
|
1619
|
-
targetType = Host.UserMetrics.ExtensionEvalTarget.OTHER_EXTENSION;
|
|
1620
|
-
if (!Root.Runtime.hostConfig.extensionsOnChromeUrls?.enabled) {
|
|
1621
|
-
return this.status.E_FAILED(
|
|
1622
|
-
'Access to extension URLs is restricted; use --extensions-on-chrome-urls to enable.');
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
Host.userMetrics.extensionEvalTarget(targetType);
|
|
1627
|
-
} catch {
|
|
1628
|
-
// Ignore invalid URLs.
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
1651
|
void context
|
|
1632
1652
|
.evaluate(
|
|
1633
1653
|
{
|
|
@@ -0,0 +1,106 @@
|
|
|
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 * as i18n from '../../core/i18n/i18n.js';
|
|
6
|
+
import type * as Protocol from '../../generated/protocol.js';
|
|
7
|
+
|
|
8
|
+
const UIStrings = {
|
|
9
|
+
/**
|
|
10
|
+
* @description Summary line in a tooltip explaining a CSS selector specificity.
|
|
11
|
+
* @example {1} PH1
|
|
12
|
+
* @example {2} PH2
|
|
13
|
+
* @example {3} PH3
|
|
14
|
+
*/
|
|
15
|
+
specificity: 'Specificity: ({PH1},{PH2},{PH3})',
|
|
16
|
+
/**
|
|
17
|
+
* @description Tooltip line listing the selector parts contributing to the ID-like specificity bucket.
|
|
18
|
+
* @example {#main} PH1
|
|
19
|
+
*/
|
|
20
|
+
idLikeSpecificity: '(a) ID-like: {PH1}',
|
|
21
|
+
/**
|
|
22
|
+
* @description Tooltip line listing the selector parts contributing to the class-like specificity bucket.
|
|
23
|
+
* @example {.active, :hover} PH1
|
|
24
|
+
*/
|
|
25
|
+
classLikeSpecificity: '(b) Class-like: {PH1}',
|
|
26
|
+
/**
|
|
27
|
+
* @description Tooltip line listing the selector parts contributing to the type-like specificity bucket.
|
|
28
|
+
* @example {div} PH1
|
|
29
|
+
*/
|
|
30
|
+
typeLikeSpecificity: '(c) Type-like: {PH1}',
|
|
31
|
+
} as const;
|
|
32
|
+
const str_ = i18n.i18n.registerUIStrings('panels/elements/CSSSpecificityBreakdown.ts', UIStrings);
|
|
33
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
34
|
+
|
|
35
|
+
export interface SpecificityBreakdown {
|
|
36
|
+
ids: string[];
|
|
37
|
+
classes: string[];
|
|
38
|
+
types: string[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function formatContribution(text: string, contribution: number): string {
|
|
42
|
+
return contribution > 1 ? `${text} x${contribution}` : text;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function formatComponentList(components: string[]): string {
|
|
46
|
+
const formatter = new Intl.ListFormat(i18n.DevToolsLocale.DevToolsLocale.instance().locale, {
|
|
47
|
+
style: 'long',
|
|
48
|
+
type: 'conjunction',
|
|
49
|
+
});
|
|
50
|
+
return formatter.format(components);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function getSpecificityBreakdown(specificity: Protocol.CSS.Specificity): SpecificityBreakdown {
|
|
54
|
+
const ids: string[] = [];
|
|
55
|
+
const classes: string[] = [];
|
|
56
|
+
const types: string[] = [];
|
|
57
|
+
|
|
58
|
+
for (const component of specificity.components ?? []) {
|
|
59
|
+
if (component.a > 0) {
|
|
60
|
+
ids.push(formatContribution(component.text, component.a));
|
|
61
|
+
}
|
|
62
|
+
if (component.b > 0) {
|
|
63
|
+
classes.push(formatContribution(component.text, component.b));
|
|
64
|
+
}
|
|
65
|
+
if (component.c > 0) {
|
|
66
|
+
types.push(formatContribution(component.text, component.c));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {ids, classes, types};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Formats the specificity breakdown into a human-readable multi-line string
|
|
75
|
+
* suitable for displaying in a tooltip.
|
|
76
|
+
*
|
|
77
|
+
* Example output for selector "div#main .active:hover":
|
|
78
|
+
* Specificity: (1,2,1)
|
|
79
|
+
* (a) ID-like: #main
|
|
80
|
+
* (b) Class-like: .active, :hover
|
|
81
|
+
* (c) Type-like: div
|
|
82
|
+
*/
|
|
83
|
+
export function formatSpecificitySummary(specificity: Protocol.CSS.Specificity): string {
|
|
84
|
+
return i18nString(UIStrings.specificity, {PH1: specificity.a, PH2: specificity.b, PH3: specificity.c});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function getSpecificityBreakdownLines(specificity: Protocol.CSS.Specificity): string[] {
|
|
88
|
+
const breakdown = getSpecificityBreakdown(specificity);
|
|
89
|
+
const lines: string[] = [];
|
|
90
|
+
|
|
91
|
+
if (breakdown.ids.length > 0) {
|
|
92
|
+
lines.push(i18nString(UIStrings.idLikeSpecificity, {PH1: formatComponentList(breakdown.ids)}));
|
|
93
|
+
}
|
|
94
|
+
if (breakdown.classes.length > 0) {
|
|
95
|
+
lines.push(i18nString(UIStrings.classLikeSpecificity, {PH1: formatComponentList(breakdown.classes)}));
|
|
96
|
+
}
|
|
97
|
+
if (breakdown.types.length > 0) {
|
|
98
|
+
lines.push(i18nString(UIStrings.typeLikeSpecificity, {PH1: formatComponentList(breakdown.types)}));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return lines;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function formatSpecificityTooltip(specificity: Protocol.CSS.Specificity): string {
|
|
105
|
+
return [formatSpecificitySummary(specificity), ...getSpecificityBreakdownLines(specificity)].join('\n');
|
|
106
|
+
}
|
|
@@ -1627,7 +1627,7 @@ export class PseudoStateMarkerDecorator implements MarkerDecorator {
|
|
|
1627
1627
|
return null;
|
|
1628
1628
|
}
|
|
1629
1629
|
return {
|
|
1630
|
-
color: '--sys-color-orange-bright',
|
|
1630
|
+
color: 'var(--sys-color-orange-bright)',
|
|
1631
1631
|
title: i18nString(UIStrings.elementStateS, {PH1: ':' + pseudoState.join(', :')}),
|
|
1632
1632
|
};
|
|
1633
1633
|
}
|
|
@@ -54,9 +54,15 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
|
54
54
|
import * as PanelsCommon from '../common/common.js';
|
|
55
55
|
|
|
56
56
|
import * as ElementsComponents from './components/components.js';
|
|
57
|
+
import {formatSpecificitySummary, getSpecificityBreakdownLines} from './CSSSpecificityBreakdown.js';
|
|
57
58
|
import {ElementsPanel} from './ElementsPanel.js';
|
|
58
59
|
import stylePropertiesTreeOutlineStyles from './stylePropertiesTreeOutline.css.js';
|
|
59
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
type Context,
|
|
62
|
+
GhostStylePropertyTreeElement,
|
|
63
|
+
handleVarDefinitionActivate,
|
|
64
|
+
StylePropertyTreeElement,
|
|
65
|
+
} from './StylePropertyTreeElement.js';
|
|
60
66
|
import type {StylesContainer} from './StylesContainer.js';
|
|
61
67
|
|
|
62
68
|
const UIStrings = {
|
|
@@ -110,11 +116,6 @@ const UIStrings = {
|
|
|
110
116
|
* @description Text that is announced by the screen reader when the user focuses on an input field for editing the name of a CSS selector in the Styles panel
|
|
111
117
|
*/
|
|
112
118
|
cssSelector: '`CSS` selector',
|
|
113
|
-
/**
|
|
114
|
-
* @description Text displayed in tooltip that shows specificity information.
|
|
115
|
-
* @example {(0,0,1)} PH1
|
|
116
|
-
*/
|
|
117
|
-
specificity: 'Specificity: {PH1}',
|
|
118
119
|
/**
|
|
119
120
|
* @description Accessibility label for the button that expands a collapsed CSS rule in the Styles pane.
|
|
120
121
|
*/
|
|
@@ -898,7 +899,7 @@ export class StylePropertiesSection {
|
|
|
898
899
|
ancestorRuleElement = this.createMediaElement(rule.media[mediaIndex++]);
|
|
899
900
|
break;
|
|
900
901
|
case Protocol.CSS.CSSRuleType.ContainerRule:
|
|
901
|
-
ancestorRuleElement = this.createContainerQueryElement(rule.containerQueries[containerIndex++]);
|
|
902
|
+
ancestorRuleElement = this.createContainerQueryElement(rule.containerQueries[containerIndex++], rule.style);
|
|
902
903
|
break;
|
|
903
904
|
case Protocol.CSS.CSSRuleType.ScopeRule:
|
|
904
905
|
ancestorRuleElement = this.createScopeElement(rule.scopes[scopeIndex++]);
|
|
@@ -1019,7 +1020,8 @@ export class StylePropertiesSection {
|
|
|
1019
1020
|
return mediaQueryElement;
|
|
1020
1021
|
}
|
|
1021
1022
|
|
|
1022
|
-
protected createContainerQueryElement(containerQuery: SDK.CSSContainerQuery.CSSContainerQuery
|
|
1023
|
+
protected createContainerQueryElement(containerQuery: SDK.CSSContainerQuery.CSSContainerQuery,
|
|
1024
|
+
style?: SDK.CSSStyleDeclaration.CSSStyleDeclaration):
|
|
1023
1025
|
ElementsComponents.CSSQuery.CSSQuery|undefined {
|
|
1024
1026
|
let onQueryTextClick;
|
|
1025
1027
|
if (containerQuery.styleSheetId) {
|
|
@@ -1032,10 +1034,22 @@ export class StylePropertiesSection {
|
|
|
1032
1034
|
queryName: containerQuery.textIsConditionText ? undefined : containerQuery.name,
|
|
1033
1035
|
queryText: containerQuery.text,
|
|
1034
1036
|
onQueryTextClick,
|
|
1037
|
+
onLinkActivate: async(resolvedVariable: string|SDK.CSSMatchedStyles.CSSValueSource): Promise<void> => {
|
|
1038
|
+
handleVarDefinitionActivate(resolvedVariable, this.stylesContainer);
|
|
1039
|
+
},
|
|
1040
|
+
getPopoverContents: (variableName: string, variableValue: string|null):
|
|
1041
|
+
ElementsComponents.CSSVariableValueView.CSSVariableValueView => {
|
|
1042
|
+
return this.stylesContainer.getVariablePopoverContents(this.matchedStyles, variableName, variableValue);
|
|
1043
|
+
},
|
|
1035
1044
|
jslogContext: 'container-query',
|
|
1036
1045
|
};
|
|
1037
|
-
if (
|
|
1038
|
-
|
|
1046
|
+
if (style) {
|
|
1047
|
+
const tooltipPrefix = `container-${this.sectionTooltipIdPrefix}-${this.nestingLevel}`;
|
|
1048
|
+
void containerQuery.getContainerForNode(this.matchedStyles.node().id).then(container => {
|
|
1049
|
+
if (container) {
|
|
1050
|
+
containerQueryElement.parseStyleQueries(this.matchedStyles, style, container.containerNode, tooltipPrefix);
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
1039
1053
|
void this.addContainerForContainerQuery(containerQuery);
|
|
1040
1054
|
}
|
|
1041
1055
|
return containerQueryElement;
|
|
@@ -1434,14 +1448,27 @@ export class StylePropertiesSection {
|
|
|
1434
1448
|
elementToSelectorIndex.set(span, i);
|
|
1435
1449
|
span.textContent = selectors[i].text;
|
|
1436
1450
|
if (specificityTooltipId && selector.specificity) {
|
|
1437
|
-
span.setAttribute('aria-
|
|
1438
|
-
const PH1 = `(${selector.specificity.a},${selector.specificity.b},${selector.specificity.c})`;
|
|
1451
|
+
span.setAttribute('aria-details', specificityTooltipId);
|
|
1439
1452
|
const tooltip = this.#specificityTooltips.appendChild(new Tooltips.Tooltip.Tooltip({
|
|
1440
1453
|
id: specificityTooltipId,
|
|
1441
1454
|
anchor: span,
|
|
1455
|
+
variant: 'rich',
|
|
1442
1456
|
jslogContext: 'elements.css-selector-specificity',
|
|
1443
1457
|
}));
|
|
1444
|
-
tooltip.
|
|
1458
|
+
tooltip.hoverDelay = 500;
|
|
1459
|
+
|
|
1460
|
+
const specificitySummary = formatSpecificitySummary(selector.specificity);
|
|
1461
|
+
const breakdownLines = getSpecificityBreakdownLines(selector.specificity);
|
|
1462
|
+
const tooltipContent = breakdownLines.length > 0 ? html`
|
|
1463
|
+
<details class="selector-specificity-tooltip-disclosure">
|
|
1464
|
+
<summary>${specificitySummary}</summary>
|
|
1465
|
+
<ul class="selector-specificity-tooltip-list">
|
|
1466
|
+
${breakdownLines.map(line => html`<li>${line}</li>`)}
|
|
1467
|
+
</ul>
|
|
1468
|
+
</details>` :
|
|
1469
|
+
html`
|
|
1470
|
+
<div class="selector-specificity-tooltip-summary">${specificitySummary}</div>`;
|
|
1471
|
+
render(tooltipContent, tooltip, {host: this});
|
|
1445
1472
|
}
|
|
1446
1473
|
}
|
|
1447
1474
|
}
|
|
@@ -316,8 +316,8 @@ export class CSSWideKeywordRenderer extends rendererBase(SDK.CSSPropertyParserMa
|
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
-
function handleVarDefinitionActivate(variable: string|SDK.CSSMatchedStyles.CSSValueSource,
|
|
320
|
-
|
|
319
|
+
export function handleVarDefinitionActivate(variable: string|SDK.CSSMatchedStyles.CSSValueSource,
|
|
320
|
+
stylesContainer: StylesContainer): void {
|
|
321
321
|
Host.userMetrics.actionTaken(Host.UserMetrics.Action.CustomPropertyLinkClicked);
|
|
322
322
|
Host.userMetrics.swatchActivated(Host.UserMetrics.SwatchType.VAR_LINK);
|
|
323
323
|
|
|
@@ -448,16 +448,17 @@ export class VariableNameRenderer extends rendererBase(SDK.CSSPropertyParserMatc
|
|
|
448
448
|
this.#matchedStyles = matchedStyles;
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
override render(match: SDK.CSSPropertyParserMatchers.VariableNameMatch,
|
|
451
|
+
override render(match: SDK.CSSPropertyParserMatchers.VariableNameMatch, _context: RenderingContext): Node[] {
|
|
452
|
+
const varSwatch = document.createElement('span');
|
|
452
453
|
if (this.#treeElement?.property.ownerStyle.parentRule instanceof SDK.CSSRule.CSSFunctionRule) {
|
|
453
|
-
|
|
454
|
+
render(html`${match.text}`, varSwatch);
|
|
455
|
+
return [varSwatch];
|
|
454
456
|
}
|
|
455
457
|
|
|
456
458
|
const {declaration, value: variableValue} = match.resolveVariable() ?? {};
|
|
457
459
|
const isDefined = variableValue !== undefined;
|
|
458
460
|
const onLinkActivate = (name: string): void =>
|
|
459
461
|
handleVarDefinitionActivate(declaration ?? name, this.#stylesContainer);
|
|
460
|
-
const varSwatch = document.createElement('span');
|
|
461
462
|
|
|
462
463
|
const tooltipContents =
|
|
463
464
|
this.#stylesContainer.getVariablePopoverContents(this.#matchedStyles, match.text, variableValue ?? null);
|
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
5
5
|
|
|
6
|
+
import '../../../ui/components/tooltips/tooltips.js';
|
|
7
|
+
import '../../../ui/legacy/components/inline_editor/inline_editor.js';
|
|
8
|
+
|
|
9
|
+
import * as SDK from '../../../core/sdk/sdk.js';
|
|
10
|
+
import type * as InlineEditor from '../../../ui/legacy/components/inline_editor/inline_editor.js';
|
|
6
11
|
import * as UI from '../../../ui/legacy/legacy.js';
|
|
7
12
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
8
13
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
9
14
|
|
|
10
15
|
import cssQueryStyles from './cssQuery.css.js';
|
|
16
|
+
import type {CSSVariableValueView} from './CSSVariableValueView.js';
|
|
11
17
|
|
|
12
18
|
const {render, html} = Lit;
|
|
13
19
|
|
|
@@ -16,36 +22,145 @@ export interface CSSQueryData {
|
|
|
16
22
|
queryName?: string;
|
|
17
23
|
queryText: string;
|
|
18
24
|
onQueryTextClick?: (event: Event) => void;
|
|
25
|
+
onLinkActivate?: (resolvedVariable: string|SDK.CSSMatchedStyles.CSSValueSource) => void;
|
|
26
|
+
getPopoverContents?: (variableName: string, variableValue: string|null) => CSSVariableValueView;
|
|
19
27
|
jslogContext: string;
|
|
20
28
|
}
|
|
21
29
|
|
|
30
|
+
interface TextSection {
|
|
31
|
+
text: string;
|
|
32
|
+
isVariable: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
export class CSSQuery extends HTMLElement {
|
|
23
36
|
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
24
37
|
#queryPrefix = '';
|
|
25
38
|
#queryName?: string;
|
|
26
|
-
#queryText =
|
|
39
|
+
#queryText: TextSection[] = [];
|
|
27
40
|
#onQueryTextClick?: (event: Event) => void;
|
|
41
|
+
#onLinkActivate?: (resolvedVariable: string|SDK.CSSMatchedStyles.CSSValueSource) => void;
|
|
42
|
+
#getPopoverContents?: (variableName: string, variableValue: string|null) => CSSVariableValueView;
|
|
28
43
|
#jslogContext?: string;
|
|
44
|
+
#matchedStyles?: SDK.CSSMatchedStyles.CSSMatchedStyles;
|
|
45
|
+
#style?: SDK.CSSStyleDeclaration.CSSStyleDeclaration;
|
|
46
|
+
#containerNode?: SDK.DOMModel.DOMNode;
|
|
47
|
+
#tooltipPrefix = '';
|
|
29
48
|
|
|
30
49
|
set data(data: CSSQueryData) {
|
|
31
50
|
this.#queryPrefix = data.queryPrefix;
|
|
32
51
|
this.#queryName = data.queryName;
|
|
33
|
-
this.#queryText = data.queryText;
|
|
52
|
+
this.#queryText = [{text: data.queryText, isVariable: false}];
|
|
34
53
|
this.#onQueryTextClick = data.onQueryTextClick;
|
|
54
|
+
this.#onLinkActivate = data.onLinkActivate;
|
|
55
|
+
this.#getPopoverContents = data.getPopoverContents;
|
|
35
56
|
this.#jslogContext = data.jslogContext;
|
|
36
57
|
this.#render();
|
|
37
58
|
}
|
|
38
59
|
|
|
60
|
+
parseStyleQueries(
|
|
61
|
+
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
|
|
62
|
+
style: SDK.CSSStyleDeclaration.CSSStyleDeclaration,
|
|
63
|
+
containerNode: SDK.DOMModel.DOMNode,
|
|
64
|
+
tooltipPrefix: string,
|
|
65
|
+
): void {
|
|
66
|
+
this.#matchedStyles = matchedStyles;
|
|
67
|
+
this.#style = style;
|
|
68
|
+
this.#containerNode = containerNode;
|
|
69
|
+
this.#tooltipPrefix = tooltipPrefix;
|
|
70
|
+
|
|
71
|
+
const queryText = this.#queryText[0]?.text;
|
|
72
|
+
if (!queryText) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const prefix = 'if(';
|
|
77
|
+
const suffix = ': 1)';
|
|
78
|
+
const ast = SDK.CSSPropertyParser.tokenizeDeclaration('--query', prefix + queryText + suffix);
|
|
79
|
+
if (!ast) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const matcher = new SDK.CSSPropertyParserMatchers.VariableNameMatcher(matchedStyles, style);
|
|
84
|
+
const matchedResult = SDK.CSSPropertyParser.BottomUpTreeMatching.walk(ast, [matcher]);
|
|
85
|
+
const matchedNodes = SDK.CSSPropertyParser.TreeSearch.findAll(ast, node => {
|
|
86
|
+
return matchedResult.getMatch(node) instanceof SDK.CSSPropertyParserMatchers.VariableNameMatch;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
matchedNodes.sort((a, b) => a.from - b.from);
|
|
90
|
+
|
|
91
|
+
const sections: TextSection[] = [];
|
|
92
|
+
const valueOffset = ast.rule.indexOf(ast.propertyValue) + prefix.length;
|
|
93
|
+
let lastOffset = 0;
|
|
94
|
+
|
|
95
|
+
for (const node of matchedNodes) {
|
|
96
|
+
const start = node.from - valueOffset;
|
|
97
|
+
const end = node.to - valueOffset;
|
|
98
|
+
if (start > lastOffset) {
|
|
99
|
+
sections.push({
|
|
100
|
+
text: queryText.substring(lastOffset, start),
|
|
101
|
+
isVariable: false,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
sections.push({
|
|
105
|
+
text: queryText.substring(start, end),
|
|
106
|
+
isVariable: true,
|
|
107
|
+
});
|
|
108
|
+
lastOffset = end;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (lastOffset < queryText.length) {
|
|
112
|
+
sections.push({
|
|
113
|
+
text: queryText.substring(lastOffset),
|
|
114
|
+
isVariable: false,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.#queryText = sections;
|
|
119
|
+
this.#render();
|
|
120
|
+
}
|
|
121
|
+
|
|
39
122
|
#render(): void {
|
|
40
123
|
const queryClasses = Lit.Directives.classMap({
|
|
41
124
|
query: true,
|
|
42
125
|
editable: Boolean(this.#onQueryTextClick),
|
|
43
126
|
});
|
|
44
127
|
|
|
45
|
-
// Disabled until https://crbug.com/1079231 is fixed.
|
|
46
128
|
// clang-format off
|
|
47
129
|
const queryText = html`
|
|
48
|
-
<span class="query-text" @click=${this.#onQueryTextClick}>${
|
|
130
|
+
<span class="query-text" @click=${this.#onQueryTextClick}>${
|
|
131
|
+
this.#queryText.map((section, index) => {
|
|
132
|
+
if (section.isVariable && this.#matchedStyles && this.#style && this.#onLinkActivate) {
|
|
133
|
+
const variableName = section.text;
|
|
134
|
+
const variable = this.#matchedStyles.computeCSSVariable(this.#style, variableName, this.#containerNode);
|
|
135
|
+
const isDefined = variable !== null && variable.value !== undefined;
|
|
136
|
+
const onLinkActivate = (): void => {
|
|
137
|
+
if (this.#onLinkActivate) {
|
|
138
|
+
this.#onLinkActivate(variable ? variable.declaration : variableName);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const tooltipContents = this.#getPopoverContents?.(variableName, variable?.value ?? null) ?? null;
|
|
142
|
+
const tooltipId = `${this.#tooltipPrefix}-${index}-${variableName}`;
|
|
143
|
+
const tooltip = {tooltipId};
|
|
144
|
+
return html`
|
|
145
|
+
<devtools-link-swatch class="css-var-link" .data=${{
|
|
146
|
+
tooltip,
|
|
147
|
+
text: variableName,
|
|
148
|
+
isDefined,
|
|
149
|
+
onLinkActivate,
|
|
150
|
+
} as InlineEditor.LinkSwatch.LinkSwatchRenderData}>
|
|
151
|
+
</devtools-link-swatch>
|
|
152
|
+
<devtools-tooltip
|
|
153
|
+
id=${tooltipId}
|
|
154
|
+
variant="rich"
|
|
155
|
+
jslogContext="elements.css-var"
|
|
156
|
+
>
|
|
157
|
+
${tooltipContents}
|
|
158
|
+
</devtools-tooltip>
|
|
159
|
+
`;
|
|
160
|
+
}
|
|
161
|
+
return html`${section.text}`;
|
|
162
|
+
})
|
|
163
|
+
}</span>
|
|
49
164
|
`;
|
|
50
165
|
|
|
51
166
|
render(html`
|
|
@@ -23,6 +23,7 @@ import './StylesAiCodeCompletionProvider.js';
|
|
|
23
23
|
import './StylePropertyTreeElement.js';
|
|
24
24
|
import './ComputedStyleWidget.js';
|
|
25
25
|
import './CSSRuleValidator.js';
|
|
26
|
+
import './CSSSpecificityBreakdown.js';
|
|
26
27
|
import './ElementsPanel.js';
|
|
27
28
|
import './ClassesPaneWidget.js';
|
|
28
29
|
import './ElementStatePaneWidget.js';
|
|
@@ -36,6 +37,7 @@ import * as ClassesPaneWidget from './ClassesPaneWidget.js';
|
|
|
36
37
|
import * as ColorSwatchPopoverIcon from './ColorSwatchPopoverIcon.js';
|
|
37
38
|
import * as ComputedStyleWidget from './ComputedStyleWidget.js';
|
|
38
39
|
import * as CSSRuleValidator from './CSSRuleValidator.js';
|
|
40
|
+
import * as CSSSpecificityBreakdown from './CSSSpecificityBreakdown.js';
|
|
39
41
|
import * as CSSValueTraceView from './CSSValueTraceView.js';
|
|
40
42
|
import * as DOMPath from './DOMPath.js';
|
|
41
43
|
import * as ElementsPanel from './ElementsPanel.js';
|
|
@@ -73,6 +75,7 @@ export {
|
|
|
73
75
|
ColorSwatchPopoverIcon,
|
|
74
76
|
ComputedStyleWidget,
|
|
75
77
|
CSSRuleValidator,
|
|
78
|
+
CSSSpecificityBreakdown,
|
|
76
79
|
CSSValueTraceView,
|
|
77
80
|
DOMPath,
|
|
78
81
|
ElementsPanel,
|