chrome-devtools-frontend 1.0.1652307 → 1.0.1656291
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/fixing-skipped-tests/SKILL.md +32 -0
- package/.agents/skills/migrate-chromium-test/SKILL.md +144 -0
- package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +116 -0
- package/.agents/skills/ui-eng-vision-logic-consolidator/SKILL.md +82 -0
- package/.agents/skills/ui-eng-vision-orchestrator/SKILL.md +123 -0
- package/.agents/skills/ui-eng-vision-test-scaffolder/SKILL.md +125 -0
- package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +75 -0
- package/AUTHORS +1 -0
- package/config/owner/COMMON_OWNERS +0 -4
- package/docs/get_the_code.md +1 -2
- package/docs/playbook.md +1 -1
- package/docs/ui_engineering.md +3 -1
- package/eslint.config.mjs +0 -5
- package/front_end/Tests.js +1 -0
- package/front_end/core/common/Settings.ts +47 -30
- package/front_end/core/sdk/CPUThrottlingManager.ts +23 -167
- package/front_end/core/sdk/CSSMetadata.ts +23 -0
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +8 -4
- package/front_end/core/sdk/ConsoleModel.ts +13 -11
- package/front_end/core/sdk/DOMDebuggerModel.ts +11 -5
- package/front_end/core/sdk/DOMModel.ts +4 -0
- package/front_end/core/sdk/EmulationModel.ts +4 -0
- package/front_end/core/sdk/EventBreakpointsModel.ts +9 -5
- package/front_end/core/sdk/IsolateManager.ts +6 -6
- package/front_end/core/sdk/ResourceTreeModel.ts +8 -5
- package/front_end/core/sdk/TargetManager.ts +17 -0
- package/front_end/entrypoints/devtools_app/devtools_app.ts +0 -1
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +459 -74
- package/front_end/entrypoints/main/MainImpl.ts +12 -42
- package/front_end/foundation/Universe.ts +116 -3
- package/front_end/generated/InspectorBackendCommands.ts +11 -6
- package/front_end/generated/SupportedCSSProperties.js +124 -34
- package/front_end/generated/protocol-mapping.d.ts +8 -0
- package/front_end/generated/protocol-proxy-api.d.ts +15 -0
- package/front_end/generated/protocol.ts +94 -1
- package/front_end/models/ai_assistance/AiConversation.ts +2 -7
- package/front_end/models/ai_assistance/README.md +4 -3
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +13 -320
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -24
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +2 -358
- package/front_end/models/ai_assistance/ai_assistance.ts +6 -8
- package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +295 -0
- package/front_end/models/ai_assistance/contexts/RequestContext.snapshot.txt +0 -1
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +0 -2
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +10 -10
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +12 -11
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +6 -6
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -14
- package/front_end/models/ai_assistance/skills/accessibility.md +4 -2
- package/front_end/models/ai_assistance/tools/GetElementAccessibilityDetails.ts +142 -0
- package/front_end/models/ai_assistance/tools/GetStyles.ts +1 -1
- package/front_end/models/ai_assistance/tools/README.md +21 -1
- package/front_end/models/ai_assistance/tools/{ResolveLighthousePath.ts → ResolveDevtoolsNodePath.ts} +18 -17
- package/front_end/models/ai_assistance/tools/Tool.ts +6 -1
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +4 -2
- package/front_end/models/autofill_manager/AutofillManager.ts +6 -15
- package/front_end/models/bindings/NetworkProject.ts +4 -8
- package/front_end/models/breakpoints/BreakpointManager.ts +9 -9
- package/front_end/models/emulation/DeviceModeModel.ts +24 -0
- package/front_end/models/emulation/EmulatedDevices.ts +108 -0
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +36 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +8 -0
- package/front_end/models/issues_manager/IssuesManager.ts +10 -6
- package/front_end/models/javascript_metadata/JavaScriptMetadata.ts +4 -5
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
- package/front_end/models/live-metrics/LiveMetrics.ts +6 -6
- package/front_end/models/live-metrics/web-vitals-injected/spec/spec.ts +5 -5
- package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +3 -3
- package/front_end/models/logs/LogManager.ts +25 -10
- package/front_end/models/logs/NetworkLog.ts +24 -19
- package/front_end/models/persistence/AutomaticFileSystemManager.ts +14 -13
- package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +26 -14
- package/front_end/models/persistence/IsolatedFileSystem.ts +9 -11
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +22 -11
- package/front_end/models/persistence/NetworkPersistenceManager.ts +73 -44
- package/front_end/models/persistence/PersistenceImpl.ts +4 -5
- package/front_end/models/project_settings/ProjectSettingsModel.ts +12 -11
- package/front_end/models/trace/EntityMapper.ts +1 -1
- package/front_end/models/trace/handlers/ScreenshotsHandler.ts +14 -59
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +12 -38
- package/front_end/panels/ai_assistance/ExportConversation.ts +4 -1
- package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
- package/front_end/panels/application/DeviceBoundSessionsView.ts +15 -3
- package/front_end/panels/application/FrameDetailsView.ts +2 -1
- package/front_end/panels/application/IndexedDBViews.ts +38 -36
- package/front_end/panels/application/ServiceWorkersView.ts +23 -16
- package/front_end/panels/application/components/AdsView.ts +4 -0
- package/front_end/panels/autofill/AutofillView.ts +1 -1
- package/front_end/panels/autofill/autofill-meta.ts +3 -2
- package/front_end/panels/common/CPUThrottlingOption.ts +142 -0
- package/front_end/panels/common/ThrottlingUtils.ts +9 -4
- package/front_end/panels/common/common.ts +1 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +45 -0
- package/front_end/panels/elements/AccessibilityTreeUtils.ts +26 -15
- package/front_end/panels/elements/AccessibilityTreeView.ts +12 -9
- package/front_end/panels/elements/ElementsPanel.ts +0 -74
- package/front_end/panels/elements/ElementsTreeOutline.ts +5 -4
- package/front_end/panels/emulation/DeviceModeToolbar.ts +46 -45
- package/front_end/panels/layer_viewer/LayerTreeOutline.ts +118 -68
- package/front_end/panels/layer_viewer/Layers3DView.ts +1 -1
- package/front_end/panels/layer_viewer/layerTreeOutline.css +20 -13
- package/front_end/panels/layers/LayersPanel.ts +1 -1
- package/front_end/panels/mobile_throttling/CalibrationController.ts +6 -5
- package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +1 -1
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +40 -13
- package/front_end/panels/mobile_throttling/ThrottlingPresets.ts +13 -17
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +79 -30
- package/front_end/panels/mobile_throttling/throttlingSettingsTab.css +5 -0
- package/front_end/panels/network/LinkPreloadGenerator.ts +101 -0
- package/front_end/panels/network/NetworkLogView.ts +28 -9
- package/front_end/panels/network/NetworkPanel.ts +1 -63
- package/front_end/panels/network/RequestInitiatorView.ts +29 -4
- package/front_end/panels/network/components/HeaderSectionRow.css +9 -7
- package/front_end/panels/network/components/HeaderSectionRow.ts +20 -1
- package/front_end/panels/network/components/RequestHeaderSection.css +5 -3
- package/front_end/panels/network/components/RequestHeaderSection.ts +1 -2
- package/front_end/panels/network/components/RequestHeadersView.css +1 -1
- package/front_end/panels/network/network.ts +2 -0
- package/front_end/panels/profiler/HeapSnapshotView.ts +121 -33
- package/front_end/panels/profiler/ModuleUIStrings.ts +4 -0
- package/front_end/panels/security/SecurityPanel.ts +36 -23
- package/front_end/panels/settings/SettingsScreen.ts +18 -103
- package/front_end/panels/settings/settings-meta.ts +0 -24
- package/front_end/panels/timeline/TimelineController.ts +3 -2
- package/front_end/panels/timeline/TimelineHistoryManager.ts +38 -37
- package/front_end/panels/timeline/TimelinePanel.ts +52 -11
- package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +20 -18
- package/front_end/panels/timeline/components/LiveMetricsView.ts +38 -38
- package/front_end/panels/timeline/components/MetricCard.ts +18 -18
- package/front_end/panels/timeline/components/liveMetricsView.css +6 -6
- package/front_end/panels/timeline/components/metricCard.css +4 -4
- package/front_end/panels/timeline/timelineFlamechartPopover.css +2 -0
- package/front_end/panels/utils/utils.ts +25 -24
- package/front_end/panels/whats_new/ReleaseNoteText.ts +3 -3
- package/front_end/panels/whats_new/resources/WNDT.md +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/lib/es5-iife/puppeteer-core-browser.d.ts +34 -55
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +96 -83
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +10 -1
- 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.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +1 -1
- 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/CDPSession.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/CDPSession.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts +3 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Target.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Target.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts.map +1 -1
- 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/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Realm.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +2 -2
- 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 +5 -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/Frame.js +1 -1
- 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 +23 -13
- 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/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPResponse.js +4 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Input.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/LifecycleWatcher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/LifecycleWatcher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts.map +1 -1
- 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/WebMCP.d.ts +3 -41
- 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.map +1 -1
- 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/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +4 -2
- 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/LaunchOptions.d.ts +5 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/LaunchOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.js +5 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.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 +34 -55
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +13 -1
- package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +2 -3
- package/front_end/third_party/puppeteer/package/src/api/CDPSession.ts +3 -1
- package/front_end/third_party/puppeteer/package/src/api/HTTPResponse.ts +3 -2
- package/front_end/third_party/puppeteer/package/src/api/Realm.ts +1 -2
- package/front_end/third_party/puppeteer/package/src/api/Target.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +1 -2
- package/front_end/third_party/puppeteer/package/src/bidi/HTTPResponse.ts +3 -1
- package/front_end/third_party/puppeteer/package/src/bidi/core/Realm.ts +1 -3
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +13 -3
- package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/FrameManager.ts +24 -13
- package/front_end/third_party/puppeteer/package/src/cdp/HTTPResponse.ts +4 -1
- package/front_end/third_party/puppeteer/package/src/cdp/Input.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/LifecycleWatcher.ts +1 -4
- package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +2 -4
- package/front_end/third_party/puppeteer/package/src/cdp/WebMCP.ts +7 -76
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +1 -4
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +4 -1
- package/front_end/third_party/puppeteer/package/src/node/LaunchOptions.ts +5 -0
- package/front_end/third_party/puppeteer/package/src/revisions.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/util/httpUtils.ts +5 -5
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/third_party/puppeteer/third_party/parsel/README.chromium +1 -1
- package/front_end/ui/components/dialogs/Dialog.ts +3 -0
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +0 -7
- package/front_end/ui/helpers/OpenInNewTab.ts +15 -7
- package/front_end/ui/legacy/InspectorDrawerView.ts +7 -5
- package/front_end/ui/legacy/ListWidget.ts +12 -0
- package/front_end/ui/legacy/SplitWidget.ts +12 -11
- package/front_end/ui/legacy/TabbedPane.ts +1 -108
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +9 -0
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +192 -139
- package/front_end/ui/legacy/components/data_grid/DataGridExporter.ts +89 -0
- package/front_end/ui/legacy/components/data_grid/dataGrid.css +10 -0
- package/front_end/ui/legacy/components/data_grid/data_grid.ts +3 -1
- package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +8 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +110 -17
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +89 -40
- package/front_end/ui/legacy/treeoutline.css +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/package.json +4 -3
- package/front_end/Images/navigationControls.png +0 -0
- package/front_end/Images/navigationControls_2x.png +0 -0
- package/front_end/Images/popoverArrows.png +0 -0
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -746
- package/front_end/entrypoints/greendev_floaty/floaty.css +0 -301
- package/front_end/entrypoints/greendev_floaty/floaty.html +0 -38
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -415
- package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +0 -834
- package/front_end/models/ai_assistance/agents/GreenDevAgentAntigravityCliSocketClient.ts +0 -53
- package/front_end/models/ai_assistance/agents/GreenDevAgentGeminiCliSocketClient.ts +0 -117
- package/front_end/models/annotations/AnnotationRepository.ts +0 -238
- package/front_end/models/annotations/AnnotationType.ts +0 -10
- package/front_end/models/annotations/README.md +0 -7
- package/front_end/models/annotations/annotations.ts +0 -6
- package/front_end/models/greendev/Prototypes.ts +0 -68
- package/front_end/models/greendev/README.md +0 -5
- package/front_end/models/greendev/greendev.ts +0 -5
- package/front_end/panels/common/Annotation.ts +0 -184
- package/front_end/panels/common/AnnotationManager.ts +0 -208
- package/front_end/panels/common/annotation.css +0 -40
- package/front_end/panels/greendev/GreenDevPanel.css +0 -282
- package/front_end/panels/greendev/GreenDevPanel.ts +0 -364
- package/front_end/panels/greendev/GreenDevShared.ts +0 -13
- package/front_end/panels/greendev/greendev-meta.ts +0 -52
- package/front_end/panels/greendev/greendev.ts +0 -9
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
/* eslint-disable color-named, no-duplicate-selectors */
|
|
2
|
-
/* stylelint-disable plugin/use_theme_colors */
|
|
3
|
-
/*
|
|
4
|
-
* Copyright 2026 The Chromium Authors
|
|
5
|
-
* Use of this source code is governed by a BSD-style license that can be
|
|
6
|
-
* found in the LICENSE file.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
:root {
|
|
10
|
-
--gemini-logo: url("data:image/svg+xml,%0A%3Csvg%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2065%2065%22%3E%3Cmask%20id%3D%22maskme%22%20style%3D%22mask-type%3Aalpha%22%20maskUnits%3D%22userSpaceOnUse%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2265%22%20height%3D%2265%22%3E%3Cpath%20d%3D%22M32.447%200c.68%200%201.273.465%201.439%201.125a38.904%2038.904%200%20001.999%205.905c2.152%205%205.105%209.376%208.854%2013.125%203.751%203.75%208.126%206.703%2013.125%208.855a38.98%2038.98%200%20005.906%201.999c.66.166%201.124.758%201.124%201.438%200%20.68-.464%201.273-1.125%201.439a38.902%2038.902%200%2000-5.905%201.999c-5%202.152-9.375%205.105-13.125%208.854-3.749%203.751-6.702%208.126-8.854%2013.125a38.973%2038.973%200%2000-2%205.906%201.485%201.485%200%2001-1.438%201.124c-.68%200-1.272-.464-1.438-1.125a38.913%2038.913%200%2000-2-5.905c-2.151-5-5.103-9.375-8.854-13.125-3.75-3.749-8.125-6.702-13.125-8.854a38.973%2038.973%200%2000-5.905-2A1.485%201.485%200%20010%2032.448c0-.68.465-1.272%201.125-1.438a38.903%2038.903%200%20005.905-2c5-2.151%209.376-5.104%2013.125-8.854%203.75-3.749%206.703-8.125%208.855-13.125a38.972%2038.972%200%20001.999-5.905A1.485%201.485%200%200132.447%200z%22%20fill%3D%22%23000%22/%3E%3Cpath%20d%3D%22M32.447%200c.68%200%201.273.465%201.439%201.125a38.904%2038.904%200%20001.999%205.905c2.152%205%205.105%209.376%208.854%2013.125%203.751%203.75%208.126%206.703%2013.125%208.855a38.98%2038.98%200%20005.906%201.999c.66.166%201.124.758%201.124%201.438%200%20.68-.464%201.273-1.125%201.439a38.902%2038.902%200%2000-5.905%201.999c-5%202.152-9.375%205.105-13.125%208.854-3.749%203.751-6.702%208.126-8.854%2013.125a38.973%2038.973%200%2000-2%205.906%201.485%201.485%200%2001-1.438%201.124c-.68%200-1.272-.464-1.438-1.125a38.913%2038.913%200%2000-2-5.905c-2.151-5-5.103-9.375-8.854-13.125-3.75-3.749-8.125-6.702-13.125-8.854a38.973%2038.973%200%2000-5.905-2A1.485%201.485%200%20010%2032.448c0-.68.465-1.272%201.125-1.438a38.903%2038.903%200%20005.905-2c5-2.151%209.376-5.104%2013.125-8.854%203.75-3.749%206.703-8.125%208.855-13.125a38.972%2038.972%200%20001.999-5.905A1.485%201.485%200%200132.447%200z%22%20fill%3D%22%23000%22/%3E%3Cpath%20d%3D%22M32.447%200c.68%200%201.273.465%201.439%201.125a38.904%2038.904%200%20001.999%205.905c2.152%205%205.105%209.376%208.854%2013.125%203.751%203.75%208.126%206.703%2013.125%208.855a38.98%2038.98%200%20005.906%201.999c.66.166%201.124.758%201.124%201.438%200%20.68-.464%201.273-1.125%201.439a38.902%2038.902%200%2000-5.905%201.999c-5%202.152-9.375%205.105-13.125%208.854-3.749%203.751-6.702%208.126-8.854%2013.125a38.973%2038.973%200%2000-2%205.906%201.485%201.485%200%2001-1.438%201.124c-.68%200-1.272-.464-1.438-1.125a38.913%2038.913%200%2000-2-5.905c-2.151-5-5.103-9.375-8.854-13.125-3.75-3.749-8.125-6.702-13.125-8.854a38.973%2038.973%200%2000-5.905-2A1.485%201.485%200%20010%2032.448c0-.68.465-1.272%201.125-1.438a38.903%2038.903%200%20005.905-2c5-2.151%209.376-5.104%2013.125-8.854%203.75-3.749%206.703-8.125%208.855-13.125a38.972%2038.972%200%20001.999-5.905A1.485%201.485%200%200132.447%200z%22%20fill%3D%22%23000%22/%3E%3Cpath%20d%3D%22M32.447%200c.68%200%201.273.465%201.439%201.125a38.904%2038.904%200%20001.999%205.905c2.152%205%205.105%209.376%208.854%2013.125%203.751%203.75%208.126%206.703%2013.125%208.855a38.98%2038.98%200%20005.906%201.999c.66.166%201.124.758%201.124%201.438%200%20.68-.464%201.273-1.125%201.439a38.902%2038.902%200%2000-5.905%201.999c-5%202.152-9.375%205.105-13.125%208.854-3.749%203.751-6.702%208.126-8.854%2013.125a38.973%2038.973%200%2000-2%205.906%201.485%201.485%200%2001-1.438%201.124c-.68%200-1.272-.464-1.438-1.125a38.913%2038.913%200%2000-2-5.905c-2.151-5-5.103-9.375-8.854-13.125-3.75-3.749-8.125-6.702-13.125-8.854a38.973%2038.973%200%2000-5.905-2A1.485%201.485%200%20010%2032.448c0-.68.465-1.272%201.125-1.438a38.903%2038.903%200%20005.905-2c5-2.151%209.376-5.104%2013.125-8.854%203.75-3.749%206.703-8.125%208.855-13.125a38.972%2038.972%200%20001.999-5.905A1.485%201.485%200%200132.447%200z%22%20fill%3D%22%23000%22/%3E%3C/mask%3E%3Cg%20mask%3D%22url%28%23maskme%29%22%3E%3Cpath%20d%3D%22M32.447%200c25.437%200%2046.062%2020.625%2046.062%2046.062%200%2025.438-20.625%2046.063-46.062%2046.063-25.438%200-46.062-20.625-46.062-46.063C-13.615%2020.625%207.01%200%2032.447%200z%22%20fill%3D%22%231967D2%22/%3E%3Cpath%20d%3D%22M65%200v65H0V0h65z%22%20fill%3D%22%231967D2%22/%3E%3Cpath%20d%3D%22M63.79%2033.567L33.567%2063.79%201.21%2031.433%2031.433%201.21%2063.79%2033.567z%22%20fill%3D%22%23fff%22%20style%3D%22mix-blend-mode%3Asoft-light%22/%3E%3C/g%3E%3C/svg%3E");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.green-dev-floaty-dialog {
|
|
14
|
-
width: 100%;
|
|
15
|
-
height: 100%;
|
|
16
|
-
background-color: #fff;
|
|
17
|
-
display: flex;
|
|
18
|
-
flex-direction: column;
|
|
19
|
-
font-family: sans-serif;
|
|
20
|
-
color: #333;
|
|
21
|
-
font-size: 16px;
|
|
22
|
-
box-sizing: border-box;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/* Header extending upwards */
|
|
26
|
-
.green-dev-floaty-dialog-header {
|
|
27
|
-
position: relative;
|
|
28
|
-
height: 70px;
|
|
29
|
-
margin-top: -20px;
|
|
30
|
-
background-color: #d3e3fd;
|
|
31
|
-
border-top-left-radius: 12px;
|
|
32
|
-
border-top-right-radius: 12px;
|
|
33
|
-
display: flex;
|
|
34
|
-
justify-content: space-between;
|
|
35
|
-
align-items: center;
|
|
36
|
-
padding: 34px 10px 11px;
|
|
37
|
-
box-sizing: border-box;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.green-dev-floaty-dialog-header-text {
|
|
41
|
-
font-weight: bold;
|
|
42
|
-
font-size: 18px;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.green-dev-floaty-dialog-close-button {
|
|
46
|
-
width: 20px;
|
|
47
|
-
height: 20px;
|
|
48
|
-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23333' d='M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z'/%3E%3C/svg%3E");
|
|
49
|
-
background-size: cover;
|
|
50
|
-
cursor: pointer;
|
|
51
|
-
border: none;
|
|
52
|
-
background-color: transparent;
|
|
53
|
-
padding: 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* Main content area of the white card */
|
|
57
|
-
.green-dev-floaty-dialog-content {
|
|
58
|
-
flex-grow: 1;
|
|
59
|
-
padding: 20px;
|
|
60
|
-
display: flex;
|
|
61
|
-
flex-direction: column;
|
|
62
|
-
min-height: 0; /* Important for flex-grow with overflow */
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.green-dev-floaty-dialog-chat-container {
|
|
66
|
-
flex-grow: 1;
|
|
67
|
-
margin-bottom: 10px;
|
|
68
|
-
overflow-y: auto;
|
|
69
|
-
display: flex;
|
|
70
|
-
flex-direction: column;
|
|
71
|
-
gap: 10px;
|
|
72
|
-
padding: 10px;
|
|
73
|
-
border: 1px solid #e0e0e0;
|
|
74
|
-
border-radius: 8px;
|
|
75
|
-
background-color: #f9f9f9;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.message {
|
|
79
|
-
padding: 8px 12px;
|
|
80
|
-
border-radius: 12px;
|
|
81
|
-
max-width: 85%;
|
|
82
|
-
overflow-wrap: break-word;
|
|
83
|
-
line-height: 1.4;
|
|
84
|
-
white-space: pre-wrap; /* Preserve newlines */
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
.user-message {
|
|
88
|
-
align-self: flex-end;
|
|
89
|
-
background-color: #d3e3fd;
|
|
90
|
-
color: #0b57d0;
|
|
91
|
-
border-bottom-right-radius: 2px;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.ai-message {
|
|
95
|
-
align-self: flex-start;
|
|
96
|
-
background-color: #fff;
|
|
97
|
-
color: #333;
|
|
98
|
-
border: 1px solid #e0e0e0;
|
|
99
|
-
border-bottom-left-radius: 2px;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.message-details-toggle {
|
|
103
|
-
font-size: 11px;
|
|
104
|
-
color: #0b57d0;
|
|
105
|
-
cursor: pointer;
|
|
106
|
-
margin-top: 4px;
|
|
107
|
-
text-decoration: underline;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.message-details-toggle:hover {
|
|
111
|
-
color: #0842a0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.message-details {
|
|
115
|
-
font-size: 11px;
|
|
116
|
-
color: #666;
|
|
117
|
-
margin-top: 8px;
|
|
118
|
-
padding-top: 8px;
|
|
119
|
-
border-top: 1px solid #eee;
|
|
120
|
-
font-family: var(--monospace-font-family);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.thought, .action {
|
|
124
|
-
margin-bottom: 6px;
|
|
125
|
-
white-space: pre-wrap;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.thought {
|
|
129
|
-
font-style: italic;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.green-dev-floaty-dialog-top-row {
|
|
133
|
-
display: flex;
|
|
134
|
-
align-items: center;
|
|
135
|
-
margin-bottom: 15px; /* Space between top row and blue card */
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.green-dev-floaty-dialog-gemini-icon {
|
|
139
|
-
width: 24px;
|
|
140
|
-
height: 24px;
|
|
141
|
-
background-image: var(--gemini-logo);
|
|
142
|
-
background-size: cover;
|
|
143
|
-
margin-right: 10px;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.green-dev-floaty-dialog-checkmark-icon {
|
|
147
|
-
width: 20px;
|
|
148
|
-
height: 20px;
|
|
149
|
-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234CAF50' d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
|
|
150
|
-
background-size: cover;
|
|
151
|
-
margin-right: 5px;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.green-dev-floaty-dialog-context-text {
|
|
155
|
-
font-weight: bold;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/* Blue card at the bottom */
|
|
159
|
-
.green-dev-floaty-dialog-blue-card {
|
|
160
|
-
position: relative;
|
|
161
|
-
background-color: #edf2fa; /* Light blue */
|
|
162
|
-
border-radius: 12px;
|
|
163
|
-
padding: 12px;
|
|
164
|
-
display: flex;
|
|
165
|
-
flex-direction: column;
|
|
166
|
-
gap: 8px;
|
|
167
|
-
border: 1px solid #d3e3fd;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.green-dev-floaty-dialog-node-description {
|
|
171
|
-
font-size: 11px;
|
|
172
|
-
font-family: var(--monospace-font-family);
|
|
173
|
-
color: #0b57d0;
|
|
174
|
-
background-color: #d3e3fd;
|
|
175
|
-
padding: 2px 8px;
|
|
176
|
-
margin-bottom: 10px;
|
|
177
|
-
border-radius: 4px;
|
|
178
|
-
align-self: flex-start;
|
|
179
|
-
max-width: 100%;
|
|
180
|
-
overflow: hidden;
|
|
181
|
-
text-overflow: ellipsis;
|
|
182
|
-
white-space: nowrap;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.input-row {
|
|
186
|
-
display: flex;
|
|
187
|
-
align-items: center;
|
|
188
|
-
width: 100%;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.green-dev-floaty-dialog-text-field {
|
|
192
|
-
flex-grow: 1;
|
|
193
|
-
background-color: #fff;
|
|
194
|
-
border: 1px solid #a7d9f0;
|
|
195
|
-
border-radius: 20px; /* Pill shape */
|
|
196
|
-
padding: 8px 16px;
|
|
197
|
-
font-size: 14px;
|
|
198
|
-
color: #333;
|
|
199
|
-
margin-right: 8px;
|
|
200
|
-
outline: none;
|
|
201
|
-
transition: border-color 0.2s;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
.green-dev-floaty-dialog-text-field:focus {
|
|
205
|
-
border-color: #0b57d0;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.green-dev-floaty-dialog-play-button {
|
|
209
|
-
width: 30px;
|
|
210
|
-
height: 30px;
|
|
211
|
-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%231976D2' d='M8 5v14l11-7z'/%3E%3C/svg%3E");
|
|
212
|
-
background-size: cover;
|
|
213
|
-
cursor: pointer;
|
|
214
|
-
border: none;
|
|
215
|
-
background-color: transparent;
|
|
216
|
-
padding: 0;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.green-dev-floaty-minimal {
|
|
220
|
-
position: absolute;
|
|
221
|
-
width: 40px;
|
|
222
|
-
height: 40px;
|
|
223
|
-
background-color: #fff;
|
|
224
|
-
background-image: var(--gemini-logo);
|
|
225
|
-
background-repeat: no-repeat;
|
|
226
|
-
background-position: center;
|
|
227
|
-
background-size: 32px;
|
|
228
|
-
cursor: pointer;
|
|
229
|
-
pointer-events: all;
|
|
230
|
-
z-index: 1001;
|
|
231
|
-
border-radius: 12px;
|
|
232
|
-
box-shadow: 0 4px 8px rgb(0 0 0 / 20%);
|
|
233
|
-
padding: 5px;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.green-dev-floaty-disclaimer {
|
|
237
|
-
font-size: 15px;
|
|
238
|
-
color: #666;
|
|
239
|
-
text-align: center;
|
|
240
|
-
margin-top: 8px;
|
|
241
|
-
position: relative; /* For tooltip positioning */
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
.disclaimer-link {
|
|
245
|
-
color: #666; /* Match text color */
|
|
246
|
-
text-decoration: underline;
|
|
247
|
-
cursor: pointer;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.disclaimer-tooltip {
|
|
251
|
-
display: none;
|
|
252
|
-
position: absolute;
|
|
253
|
-
bottom: 100%; /* Position above */
|
|
254
|
-
left: 50%;
|
|
255
|
-
transform: translateX(-50%);
|
|
256
|
-
width: 300px;
|
|
257
|
-
padding: 12px;
|
|
258
|
-
background-color: #fff;
|
|
259
|
-
border: 1px solid #ccc;
|
|
260
|
-
border-radius: 8px;
|
|
261
|
-
box-shadow: 0 2px 10px rgb(0 0 0 / 20%);
|
|
262
|
-
z-index: 1000;
|
|
263
|
-
text-align: left;
|
|
264
|
-
font-size: 16px;
|
|
265
|
-
line-height: 1.4;
|
|
266
|
-
color: #333;
|
|
267
|
-
white-space: normal; /* Ensure text wraps */
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
.disclaimer-link:hover + .disclaimer-tooltip,
|
|
271
|
-
.disclaimer-tooltip:hover {
|
|
272
|
-
display: block;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
.learn-more-link {
|
|
276
|
-
color: #0b57d0;
|
|
277
|
-
text-decoration: none;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
.learn-more-link:hover {
|
|
281
|
-
text-decoration: underline;
|
|
282
|
-
}
|
|
@@ -1,364 +0,0 @@
|
|
|
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
|
-
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
|
-
|
|
6
|
-
import type * as Common from '../../core/common/common.js';
|
|
7
|
-
import * as Host from '../../core/host/host.js';
|
|
8
|
-
import type * as Platform from '../../core/platform/platform.js';
|
|
9
|
-
import * as SDK from '../../core/sdk/sdk.js';
|
|
10
|
-
import type * as Protocol from '../../generated/protocol.js';
|
|
11
|
-
import * as Marked from '../../third_party/marked/marked.js';
|
|
12
|
-
import * as MarkdownView from '../../ui/components/markdown_view/markdown_view.js';
|
|
13
|
-
import * as UI from '../../ui/legacy/legacy.js';
|
|
14
|
-
|
|
15
|
-
import greenDevPanelStyles from './GreenDevPanel.css.js';
|
|
16
|
-
import type {SyncMessage} from './GreenDevShared.js';
|
|
17
|
-
|
|
18
|
-
let greenDevPanelInstance: GreenDevPanel;
|
|
19
|
-
|
|
20
|
-
export class GreenDevPanel extends UI.Panel.Panel {
|
|
21
|
-
#tabbedPane: UI.TabbedPane.TabbedPane;
|
|
22
|
-
#sessions = new Map<
|
|
23
|
-
string,
|
|
24
|
-
{view: UI.Widget.Widget, container: HTMLDivElement, description: HTMLDivElement, node?: SDK.DOMModel.DOMNode}>();
|
|
25
|
-
#syncChannel: BroadcastChannel;
|
|
26
|
-
|
|
27
|
-
private constructor() {
|
|
28
|
-
super('greendev');
|
|
29
|
-
this.contentElement.style.display = 'flex';
|
|
30
|
-
this.contentElement.style.flexDirection = 'column';
|
|
31
|
-
this.contentElement.style.height = '100%';
|
|
32
|
-
this.contentElement.style.overflow = 'hidden';
|
|
33
|
-
|
|
34
|
-
this.#tabbedPane = new UI.TabbedPane.TabbedPane();
|
|
35
|
-
this.#tabbedPane.element.style.flex = '1';
|
|
36
|
-
this.#tabbedPane.show(this.contentElement);
|
|
37
|
-
|
|
38
|
-
// Welcome Tab
|
|
39
|
-
this.#createWelcomeTab();
|
|
40
|
-
|
|
41
|
-
this.#tabbedPane.addEventListener(UI.TabbedPane.Events.TabClosed, this.#onTabClosed, this);
|
|
42
|
-
|
|
43
|
-
this.#syncChannel = new BroadcastChannel('green-dev-sync');
|
|
44
|
-
this.#syncChannel.onmessage = event => {
|
|
45
|
-
void this.#handlePanelMessage(event.data as SyncMessage);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Request state from active floaties
|
|
49
|
-
this.#syncChannel.postMessage({type: 'request-session-state'});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
override wasShown(): void {
|
|
53
|
-
super.wasShown();
|
|
54
|
-
this.registerRequiredCSS(greenDevPanelStyles);
|
|
55
|
-
SDK.OverlayModel.OverlayModel.setInspectNodeHandler(this.#handleInspectNode.bind(this));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
override willHide(): void {
|
|
59
|
-
super.willHide();
|
|
60
|
-
SDK.OverlayModel.OverlayModel.setInspectNodeHandler(async () => {});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async #handleInspectNode(_node: SDK.DOMModel.DOMNode): Promise<void> {
|
|
64
|
-
// Suppress reveal in Elements panel by doing nothing here.
|
|
65
|
-
// The Floaty will handle its own opening and broadcasting.
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
#onTabClosed(event: Common.EventTarget.EventTargetEvent<UI.TabbedPane.EventData>): void {
|
|
69
|
-
const tabId = event.data.tabId;
|
|
70
|
-
if (tabId === 'welcome') {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
this.#sessions.delete(tabId);
|
|
74
|
-
if (this.#sessions.size === 0) {
|
|
75
|
-
if (!this.#tabbedPane.hasTab('welcome')) {
|
|
76
|
-
this.#createWelcomeTab();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
#createWelcomeTab(): void {
|
|
82
|
-
const welcomeWidget = new UI.Widget.Widget();
|
|
83
|
-
welcomeWidget.element.style.display = 'flex';
|
|
84
|
-
welcomeWidget.element.style.alignItems = 'center';
|
|
85
|
-
welcomeWidget.element.style.justifyContent = 'center';
|
|
86
|
-
welcomeWidget.element.style.height = '100%';
|
|
87
|
-
const welcomeContent = document.createElement('div');
|
|
88
|
-
welcomeContent.textContent = 'Interact with GreenDev Floaty dialogs to see conversations here.';
|
|
89
|
-
welcomeContent.style.padding = '20px';
|
|
90
|
-
welcomeContent.style.fontSize = '14px';
|
|
91
|
-
welcomeContent.style.color = 'var(--sys-color-on-surface-subtle)';
|
|
92
|
-
welcomeWidget.contentElement.appendChild(welcomeContent);
|
|
93
|
-
this.#tabbedPane.appendTab('welcome', 'Welcome', welcomeWidget);
|
|
94
|
-
this.#tabbedPane.selectTab('welcome');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
closeSession(sessionId: string): void {
|
|
98
|
-
this.#tabbedPane.closeTab(sessionId);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
async #handlePanelMessage(data: SyncMessage): Promise<void> {
|
|
102
|
-
const sessionId = String(data.sessionId);
|
|
103
|
-
if (!sessionId || sessionId === '0' || sessionId === 'undefined') {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
let session = this.#sessions.get(sessionId);
|
|
108
|
-
if (!session) {
|
|
109
|
-
// If we are adding a new tab, check if we need to remove the welcome tab
|
|
110
|
-
if (this.#tabbedPane.hasTab('welcome')) {
|
|
111
|
-
this.#tabbedPane.closeTab('welcome');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const widget = new UI.Widget.Widget();
|
|
115
|
-
widget.contentElement.className = 'green-dev-floaty-dialog';
|
|
116
|
-
widget.contentElement.style.display = 'flex';
|
|
117
|
-
widget.contentElement.style.flexDirection = 'column';
|
|
118
|
-
widget.contentElement.style.height = '100%';
|
|
119
|
-
widget.contentElement.style.padding = '0';
|
|
120
|
-
|
|
121
|
-
const content = document.createElement('div');
|
|
122
|
-
content.className = 'green-dev-floaty-dialog-content';
|
|
123
|
-
content.style.flexGrow = '1';
|
|
124
|
-
content.style.display = 'flex';
|
|
125
|
-
content.style.flexDirection = 'column';
|
|
126
|
-
content.style.overflow = 'hidden';
|
|
127
|
-
|
|
128
|
-
// Top row: Context added
|
|
129
|
-
const topRow = document.createElement('div');
|
|
130
|
-
topRow.className = 'green-dev-floaty-dialog-top-row';
|
|
131
|
-
topRow.style.flexShrink = '0';
|
|
132
|
-
const geminiIcon = document.createElement('div');
|
|
133
|
-
geminiIcon.className = 'green-dev-floaty-dialog-gemini-icon';
|
|
134
|
-
const checkmarkIcon = document.createElement('div');
|
|
135
|
-
checkmarkIcon.className = 'green-dev-floaty-dialog-checkmark-icon';
|
|
136
|
-
const contextText = document.createElement('span');
|
|
137
|
-
contextText.className = 'green-dev-floaty-dialog-context-text';
|
|
138
|
-
contextText.textContent = 'Context added';
|
|
139
|
-
topRow.appendChild(geminiIcon);
|
|
140
|
-
topRow.appendChild(checkmarkIcon);
|
|
141
|
-
topRow.appendChild(contextText);
|
|
142
|
-
content.appendChild(topRow);
|
|
143
|
-
|
|
144
|
-
const chatContainer = document.createElement('div');
|
|
145
|
-
chatContainer.className = 'green-dev-floaty-dialog-chat-container';
|
|
146
|
-
chatContainer.style.flexGrow = '1';
|
|
147
|
-
chatContainer.style.overflowY = 'auto';
|
|
148
|
-
content.appendChild(chatContainer);
|
|
149
|
-
|
|
150
|
-
const blueCard = document.createElement('div');
|
|
151
|
-
blueCard.className = 'green-dev-floaty-dialog-blue-card';
|
|
152
|
-
blueCard.style.flexShrink = '0';
|
|
153
|
-
|
|
154
|
-
const desc = document.createElement('div');
|
|
155
|
-
desc.className = 'green-dev-floaty-dialog-node-description';
|
|
156
|
-
desc.style.whiteSpace = 'normal';
|
|
157
|
-
desc.style.overflow = 'auto';
|
|
158
|
-
blueCard.appendChild(desc);
|
|
159
|
-
|
|
160
|
-
const inputRow = document.createElement('div');
|
|
161
|
-
inputRow.className = 'input-row';
|
|
162
|
-
|
|
163
|
-
const input = document.createElement('input');
|
|
164
|
-
input.type = 'text';
|
|
165
|
-
input.className = 'green-dev-floaty-dialog-text-field';
|
|
166
|
-
input.placeholder = 'Ask a question...';
|
|
167
|
-
|
|
168
|
-
const button = document.createElement('button');
|
|
169
|
-
button.className = 'green-dev-floaty-dialog-play-button';
|
|
170
|
-
|
|
171
|
-
const sendAction = (): void => {
|
|
172
|
-
const text = input.value;
|
|
173
|
-
if (text) {
|
|
174
|
-
input.value = '';
|
|
175
|
-
// Do not append locally; wait for broadcast from floaty
|
|
176
|
-
this.#syncChannel.postMessage({type: 'user-input', sessionId: parseInt(sessionId, 10), text});
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
button.addEventListener('click', sendAction);
|
|
181
|
-
input.addEventListener('keydown', e => {
|
|
182
|
-
if (e.key === 'Enter') {
|
|
183
|
-
sendAction();
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
inputRow.appendChild(input);
|
|
188
|
-
inputRow.appendChild(button);
|
|
189
|
-
blueCard.appendChild(inputRow);
|
|
190
|
-
|
|
191
|
-
const disclaimer = document.createElement('div');
|
|
192
|
-
disclaimer.className = 'green-dev-floaty-disclaimer';
|
|
193
|
-
|
|
194
|
-
const link = document.createElement('span');
|
|
195
|
-
link.className = 'disclaimer-link';
|
|
196
|
-
link.textContent = 'Relevant data';
|
|
197
|
-
disclaimer.appendChild(link);
|
|
198
|
-
|
|
199
|
-
disclaimer.appendChild(document.createTextNode(' is sent to Google'));
|
|
200
|
-
|
|
201
|
-
const tooltip = document.createElement('div');
|
|
202
|
-
tooltip.className = 'disclaimer-tooltip';
|
|
203
|
-
|
|
204
|
-
tooltip.appendChild(document.createTextNode(
|
|
205
|
-
'Chat messages and any data the inspected page can access via Web APIs are sent to Google and may be seen by human reviewers to improve this feature. This is an experimental AI feature and won\'t always get it right.'));
|
|
206
|
-
tooltip.appendChild(document.createElement('br'));
|
|
207
|
-
tooltip.appendChild(document.createElement('br'));
|
|
208
|
-
|
|
209
|
-
const learnMore = document.createElement('a');
|
|
210
|
-
const href = 'https://developer.chrome.com/docs/devtools/ai-assistance' as Platform.DevToolsPath.UrlString;
|
|
211
|
-
learnMore.href = href;
|
|
212
|
-
learnMore.className = 'learn-more-link';
|
|
213
|
-
learnMore.textContent = 'Learn about AI in DevTools';
|
|
214
|
-
learnMore.addEventListener('click', event => {
|
|
215
|
-
event.preventDefault();
|
|
216
|
-
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(href);
|
|
217
|
-
});
|
|
218
|
-
tooltip.appendChild(learnMore);
|
|
219
|
-
|
|
220
|
-
disclaimer.appendChild(tooltip);
|
|
221
|
-
blueCard.appendChild(disclaimer);
|
|
222
|
-
|
|
223
|
-
content.appendChild(blueCard);
|
|
224
|
-
widget.contentElement.appendChild(content);
|
|
225
|
-
|
|
226
|
-
this.#sessions.set(sessionId, {view: widget, container: chatContainer, description: desc});
|
|
227
|
-
session = {view: widget, container: chatContainer, description: desc};
|
|
228
|
-
|
|
229
|
-
const title = data.nodeDescription || `Node ${sessionId}`;
|
|
230
|
-
this.#tabbedPane.appendTab(sessionId, title, widget, undefined, undefined, true);
|
|
231
|
-
this.#tabbedPane.selectTab(sessionId);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (!session.node && (data.type === 'full-state' || data.type === 'node-changed' || !session)) {
|
|
235
|
-
const backendNodeId = parseInt(sessionId, 10);
|
|
236
|
-
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
237
|
-
let mainTarget = targetManager.primaryPageTarget();
|
|
238
|
-
|
|
239
|
-
const fetchNode = async(target: SDK.Target.Target): Promise<void> => {
|
|
240
|
-
const domModel = target.model(SDK.DOMModel.DOMModel);
|
|
241
|
-
if (domModel) {
|
|
242
|
-
const nodesMap = await domModel.pushNodesByBackendIdsToFrontend(
|
|
243
|
-
new Set([backendNodeId]) as Set<Protocol.DOM.BackendNodeId>);
|
|
244
|
-
const node = nodesMap?.get(backendNodeId as Protocol.DOM.BackendNodeId) || null;
|
|
245
|
-
if (node && session) {
|
|
246
|
-
session.node = node;
|
|
247
|
-
this.#addHighlightListeners(session.description, node);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
if (mainTarget) {
|
|
253
|
-
await fetchNode(mainTarget);
|
|
254
|
-
} else {
|
|
255
|
-
targetManager.observeTargets({
|
|
256
|
-
targetAdded: async(target: SDK.Target.Target): Promise<void> => {
|
|
257
|
-
if (target === targetManager.primaryPageTarget()) {
|
|
258
|
-
mainTarget = target;
|
|
259
|
-
await fetchNode(mainTarget);
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
|
-
targetRemoved: (_: SDK.Target.Target): void => {},
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (data.type === 'new-message' && data.text) {
|
|
268
|
-
this.#appendMessageToContainer(session.container, data.text, data.isUser ?? false);
|
|
269
|
-
} else if (data.type === 'update-last-message') {
|
|
270
|
-
const lastMsg = session.container.lastElementChild?.querySelector('.message-content devtools-markdown-view');
|
|
271
|
-
if (lastMsg) {
|
|
272
|
-
(lastMsg as MarkdownView.MarkdownView.MarkdownView).data = {
|
|
273
|
-
tokens: Marked.Marked.lexer(data.text ?? ''),
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
} else if (data.type === 'full-state') {
|
|
277
|
-
session.container.innerHTML = '';
|
|
278
|
-
if (data.messages) {
|
|
279
|
-
for (const msg of data.messages) {
|
|
280
|
-
this.#appendMessageToContainer(session.container, msg.text, msg.isUser);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
} else if (data.type === 'select-tab') {
|
|
284
|
-
this.#tabbedPane.selectTab(sessionId);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (data.nodeDescription) {
|
|
288
|
-
session.description.textContent = data.nodeDescription;
|
|
289
|
-
if (data.type === 'node-changed') {
|
|
290
|
-
this.#tabbedPane.changeTabTitle(sessionId, data.nodeDescription);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
#addHighlightListeners(element: HTMLElement, node: SDK.DOMModel.DOMNode): void {
|
|
296
|
-
element.addEventListener('mousemove', () => {
|
|
297
|
-
node.highlight();
|
|
298
|
-
});
|
|
299
|
-
element.addEventListener('mouseleave', () => {
|
|
300
|
-
void node.domModel().overlayModel().clearHighlight();
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
#appendMessageToContainer(container: HTMLDivElement, text: string, isUser: boolean): void {
|
|
305
|
-
const messageElement = document.createElement('div');
|
|
306
|
-
messageElement.className = `message ${isUser ? 'user-message' : 'ai-message'}`;
|
|
307
|
-
messageElement.style.display = 'flex';
|
|
308
|
-
messageElement.style.flexDirection = 'column';
|
|
309
|
-
messageElement.style.flexShrink = '0';
|
|
310
|
-
|
|
311
|
-
const content = document.createElement('div');
|
|
312
|
-
content.className = 'message-content';
|
|
313
|
-
if (isUser) {
|
|
314
|
-
content.textContent = text;
|
|
315
|
-
} else {
|
|
316
|
-
const markdown = new MarkdownView.MarkdownView.MarkdownView();
|
|
317
|
-
markdown.data = {
|
|
318
|
-
tokens: Marked.Marked.lexer(text),
|
|
319
|
-
};
|
|
320
|
-
content.append(markdown);
|
|
321
|
-
const style = document.createElement('style');
|
|
322
|
-
style.textContent = `
|
|
323
|
-
.message { font-size: 1.0rem; }
|
|
324
|
-
.message code { font-size: 1.0rem; font-family: 'Roboto Mono', monospace; color: green; }
|
|
325
|
-
devtools-code-block {
|
|
326
|
-
white-space: pre-wrap;
|
|
327
|
-
}
|
|
328
|
-
`;
|
|
329
|
-
markdown.shadowRoot?.appendChild(style);
|
|
330
|
-
|
|
331
|
-
const codeBlocks = markdown.shadowRoot?.querySelectorAll('devtools-code-block');
|
|
332
|
-
for (const block of codeBlocks ?? []) {
|
|
333
|
-
// We need to rerender the component for the styles to be applied.
|
|
334
|
-
block.connectedCallback();
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
content.style.flexGrow = '1';
|
|
338
|
-
messageElement.appendChild(content);
|
|
339
|
-
|
|
340
|
-
container.appendChild(messageElement);
|
|
341
|
-
container.scrollTop = container.scrollHeight;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
static instance(opts: {
|
|
345
|
-
forceNew: boolean|null,
|
|
346
|
-
} = {forceNew: null}): GreenDevPanel {
|
|
347
|
-
const {forceNew} = opts;
|
|
348
|
-
if (!greenDevPanelInstance || forceNew) {
|
|
349
|
-
greenDevPanelInstance = new GreenDevPanel();
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return greenDevPanelInstance;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Expose global method for browser process to call
|
|
357
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
358
|
-
(window as any).GreenDevPanel = {
|
|
359
|
-
closeSession: (sessionId: number): void => {
|
|
360
|
-
if (greenDevPanelInstance) {
|
|
361
|
-
greenDevPanelInstance.closeSession(String(sessionId));
|
|
362
|
-
}
|
|
363
|
-
},
|
|
364
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
export interface SyncMessage {
|
|
6
|
-
type: 'main-window-alive'|'request-session-state'|'user-input'|'restore-floaty'|'full-state'|'activate-panel'|
|
|
7
|
-
'select-tab'|'node-changed'|'new-message'|'update-last-message';
|
|
8
|
-
sessionId?: number;
|
|
9
|
-
text?: string;
|
|
10
|
-
isUser?: boolean;
|
|
11
|
-
nodeDescription?: string|null;
|
|
12
|
-
messages?: Array<{text: string, isUser: boolean}>;
|
|
13
|
-
}
|