chrome-devtools-frontend 1.0.1535712 → 1.0.1537268
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/docs/contributing/images/issues-nearestslo.png +0 -0
- package/docs/contributing/issues.md +17 -21
- package/front_end/core/common/Console.ts +1 -8
- package/front_end/core/common/ParsedURL.ts +10 -20
- package/front_end/core/common/SegmentedRange.ts +1 -2
- package/front_end/core/common/StringOutputStream.ts +1 -4
- package/front_end/core/host/AidaClient.ts +64 -5
- package/front_end/core/host/DispatchHttpRequestClient.ts +62 -0
- package/front_end/core/host/GdpClient.ts +8 -57
- package/front_end/core/host/host.ts +2 -0
- package/front_end/core/i18n/i18nImpl.ts +0 -24
- package/front_end/core/protocol_client/CDPConnection.ts +10 -8
- package/front_end/core/protocol_client/InspectorBackend.ts +36 -42
- package/front_end/core/sdk/AnimationModel.ts +1 -2
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -2
- package/front_end/core/sdk/CSSModel.ts +1 -1
- package/front_end/core/sdk/CSSProperty.ts +3 -6
- package/front_end/core/sdk/CSSStyleDeclaration.ts +4 -4
- package/front_end/core/sdk/DebuggerModel.ts +1 -2
- package/front_end/core/sdk/EnhancedTracesParser.ts +24 -5
- package/front_end/core/sdk/RehydratingConnection.ts +112 -4
- package/front_end/core/sdk/RehydratingObject.ts +8 -0
- package/front_end/core/sdk/SourceMap.ts +2 -3
- package/front_end/core/sdk/TraceObject.ts +5 -1
- package/front_end/entrypoints/node_app/NodeConnectionsPanel.ts +2 -1
- package/front_end/generated/InspectorBackendCommands.js +1 -2
- package/front_end/generated/SupportedCSSProperties.js +19 -0
- package/front_end/generated/protocol.ts +0 -27
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
- package/front_end/models/trace/types/File.ts +9 -0
- package/front_end/panels/accessibility/AccessibilityNodeView.ts +18 -17
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +9 -12
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -9
- package/front_end/panels/ai_assistance/components/ChatView.ts +63 -74
- package/front_end/panels/application/AppManifestView.ts +7 -6
- package/front_end/panels/application/ApplicationPanelSidebar.ts +4 -4
- package/front_end/panels/application/BackForwardCacheTreeElement.ts +2 -6
- package/front_end/panels/application/OpenedWindowDetailsView.ts +6 -6
- package/front_end/panels/application/StorageView.ts +9 -8
- package/front_end/panels/application/components/BackForwardCacheView.ts +366 -342
- package/front_end/panels/application/components/FrameDetailsView.ts +8 -11
- package/front_end/panels/application/components/OriginTrialTreeView.ts +65 -69
- package/front_end/panels/application/components/ProtocolHandlersView.ts +3 -2
- package/front_end/panels/application/components/backForwardCacheView.css +4 -0
- package/front_end/panels/application/components/badge.css +1 -1
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -1
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +44 -53
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +8 -8
- package/front_end/panels/common/BadgeNotification.ts +2 -1
- package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +8 -2
- package/front_end/panels/console/ConsolePinPane.ts +12 -7
- package/front_end/panels/developer_resources/DeveloperResourcesView.ts +9 -9
- package/front_end/panels/elements/ComputedStyleWidget.ts +7 -7
- package/front_end/panels/elements/EventListenersWidget.ts +9 -9
- package/front_end/panels/elements/NodeStackTraceWidget.ts +6 -6
- package/front_end/panels/elements/PlatformFontsWidget.ts +5 -5
- package/front_end/panels/elements/PropertiesWidget.ts +8 -8
- package/front_end/panels/layer_viewer/Layers3DView.ts +2 -1
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +3 -3
- package/front_end/panels/network/RequestCookiesView.ts +2 -1
- package/front_end/panels/network/RequestTimingView.ts +2 -1
- package/front_end/panels/recorder/RecorderController.ts +33 -23
- package/front_end/panels/recorder/components/CreateRecordingView.ts +259 -226
- package/front_end/panels/security/CookieControlsView.ts +2 -1
- package/front_end/panels/security/CookieReportView.ts +3 -2
- package/front_end/panels/settings/AISettingsTab.ts +164 -172
- package/front_end/panels/settings/KeybindsSettingsTab.ts +6 -0
- package/front_end/panels/settings/SettingsScreen.ts +3 -7
- package/front_end/panels/settings/aiSettingsTab.css +151 -148
- package/front_end/panels/settings/components/SyncSection.ts +2 -1
- package/front_end/panels/settings/settings-meta.ts +1 -2
- package/front_end/panels/sources/AddSourceMapURLDialog.ts +23 -26
- package/front_end/panels/sources/DebuggerPausedMessage.ts +4 -3
- package/front_end/panels/sources/ResourceOriginPlugin.ts +3 -2
- package/front_end/panels/sources/SourcesNavigator.ts +2 -1
- package/front_end/panels/sources/TabbedEditorContainer.ts +3 -2
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +9 -9
- package/front_end/panels/timeline/TimelinePanel.ts +60 -11
- package/front_end/panels/timeline/TimelineUIUtils.ts +3 -2
- package/front_end/panels/timeline/components/DetailsView.ts +5 -4
- package/front_end/panels/timeline/components/ExportTraceOptions.ts +33 -34
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +2 -1
- package/front_end/panels/timeline/components/LiveMetricsView.ts +5 -4
- package/front_end/panels/timeline/components/MetricCompareStrings.ts +25 -24
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +2 -1
- package/front_end/third_party/chromium/README.chromium +2 -2
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +9 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +13 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js +5 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +1 -12
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +6 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +28 -3
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21 -10
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +9 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +13 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js +5 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts +1 -12
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +6 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +28 -3
- package/front_end/third_party/puppeteer/package/package.json +2 -2
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +13 -1
- package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +7 -2
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +14 -1
- package/front_end/third_party/puppeteer/package/src/bidi/BrowserContext.ts +8 -5
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +5 -2
- package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +8 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +11 -2
- package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +3 -2
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +5 -5
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/disposable.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/util.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/docs/tooltip/basic.ts +1 -1
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +280 -0
- package/front_end/ui/components/text_editor/text_editor.ts +1 -0
- package/front_end/ui/components/tooltips/Tooltip.ts +33 -18
- package/front_end/ui/i18n/i18n.ts +31 -0
- package/front_end/ui/legacy/Dialog.ts +0 -1
- package/front_end/ui/legacy/SettingsUI.ts +0 -14
- package/front_end/ui/legacy/SoftDropDown.ts +1 -12
- package/front_end/ui/legacy/ViewManager.ts +2 -4
- package/front_end/ui/legacy/Widget.ts +33 -17
- package/front_end/ui/legacy/XLink.ts +0 -3
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +9 -0
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -1
- package/front_end/ui/legacy/components/utils/Linkifier.ts +9 -3
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +4 -1
- package/mcp/mcp.ts +6 -0
- package/package.json +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +0 -4
- package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.html +0 -20
- package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.ts +0 -25
- package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.html +0 -20
- package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.ts +0 -36
- package/front_end/ui/components/docs/recorder_create_recording_view/basic.html +0 -20
- package/front_end/ui/components/docs/recorder_create_recording_view/basic.ts +0 -27
- package/front_end/ui/legacy/ThrottledWidget.ts +0 -48
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type {CreatePageOptions} from '../api/Browser.js';
|
|
7
8
|
import {
|
|
8
9
|
WEB_PERMISSION_TO_PROTOCOL_PERMISSION,
|
|
9
10
|
type Permission,
|
|
@@ -88,9 +89,9 @@ export class CdpBrowserContext extends BrowserContext {
|
|
|
88
89
|
});
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
override async newPage(): Promise<Page> {
|
|
92
|
+
override async newPage(options?: CreatePageOptions): Promise<Page> {
|
|
92
93
|
using _guard = await this.waitForScreenshotOperations();
|
|
93
|
-
return await this.#browser._createPageInContext(this.#id);
|
|
94
|
+
return await this.#browser._createPageInContext(this.#id, options);
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
override browser(): CdpBrowser {
|
|
@@ -14,7 +14,7 @@ import type {ElementHandle} from '../api/ElementHandle.js';
|
|
|
14
14
|
import type {Frame, WaitForOptions} from '../api/Frame.js';
|
|
15
15
|
import type {HTTPResponse} from '../api/HTTPResponse.js';
|
|
16
16
|
import type {JSHandle} from '../api/JSHandle.js';
|
|
17
|
-
import type {Credentials} from '../api/Page.js';
|
|
17
|
+
import type {Credentials, ReloadOptions} from '../api/Page.js';
|
|
18
18
|
import {
|
|
19
19
|
Page,
|
|
20
20
|
PageEvent,
|
|
@@ -898,15 +898,15 @@ export class CdpPage extends Page {
|
|
|
898
898
|
this.emit(PageEvent.Dialog, dialog);
|
|
899
899
|
}
|
|
900
900
|
|
|
901
|
-
override async reload(
|
|
902
|
-
options?: WaitForOptions,
|
|
903
|
-
): Promise<HTTPResponse | null> {
|
|
901
|
+
override async reload(options?: ReloadOptions): Promise<HTTPResponse | null> {
|
|
904
902
|
const [result] = await Promise.all([
|
|
905
903
|
this.waitForNavigation({
|
|
906
904
|
...options,
|
|
907
905
|
ignoreSameDocumentNavigation: true,
|
|
908
906
|
}),
|
|
909
|
-
this.#primaryTargetClient.send('Page.reload'
|
|
907
|
+
this.#primaryTargetClient.send('Page.reload', {
|
|
908
|
+
ignoreCache: options?.ignoreCache ?? false,
|
|
909
|
+
}),
|
|
910
910
|
]);
|
|
911
911
|
|
|
912
912
|
return result;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
10
|
export const PUPPETEER_REVISIONS = Object.freeze({
|
|
11
|
-
chrome: '
|
|
12
|
-
'chrome-headless-shell': '
|
|
13
|
-
firefox: 'stable_144.0',
|
|
11
|
+
chrome: '142.0.7444.59',
|
|
12
|
+
'chrome-headless-shell': '142.0.7444.59',
|
|
13
|
+
firefox: 'stable_144.0.2',
|
|
14
14
|
});
|
|
@@ -45,7 +45,7 @@ export const asyncDisposeSymbol: typeof Symbol.asyncDispose =
|
|
|
45
45
|
/**
|
|
46
46
|
* @internal
|
|
47
47
|
*/
|
|
48
|
-
class DisposableStackPolyfill {
|
|
48
|
+
export class DisposableStackPolyfill {
|
|
49
49
|
#disposed = false;
|
|
50
50
|
#stack: Disposable[] = [];
|
|
51
51
|
|
|
@@ -194,7 +194,7 @@ export const DisposableStack: typeof DisposableStackPolyfill =
|
|
|
194
194
|
/**
|
|
195
195
|
* @internal
|
|
196
196
|
*/
|
|
197
|
-
class AsyncDisposableStackPolyfill {
|
|
197
|
+
export class AsyncDisposableStackPolyfill {
|
|
198
198
|
#disposed = false;
|
|
199
199
|
#stack: AsyncDisposable[] = [];
|
|
200
200
|
|
|
@@ -31,7 +31,7 @@ Lit.render(
|
|
|
31
31
|
>
|
|
32
32
|
Non-button click trigger
|
|
33
33
|
</span>
|
|
34
|
-
<devtools-tooltip id="rich-tooltip" variant="rich"
|
|
34
|
+
<devtools-tooltip id="rich-tooltip" variant="rich" trigger="click">
|
|
35
35
|
<p>Rich tooltip</p>
|
|
36
36
|
<button>Action</button>
|
|
37
37
|
</devtools-tooltip>
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// Copyright 2025 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 Common from '../../../core/common/common.js';
|
|
6
|
+
import * as Host from '../../../core/host/host.js';
|
|
7
|
+
import * as i18n from '../../../core/i18n/i18n.js';
|
|
8
|
+
import * as Root from '../../../core/root/root.js';
|
|
9
|
+
import * as PanelCommon from '../../../panels/common/common.js';
|
|
10
|
+
import * as CodeMirror from '../../../third_party/codemirror.next/codemirror.next.js';
|
|
11
|
+
import * as UI from '../../legacy/legacy.js';
|
|
12
|
+
import * as VisualLogging from '../../visual_logging/visual_logging.js';
|
|
13
|
+
|
|
14
|
+
import {AiCodeCompletionTeaserPlaceholder} from './AiCodeCompletionTeaserPlaceholder.js';
|
|
15
|
+
import {
|
|
16
|
+
aiAutoCompleteSuggestion,
|
|
17
|
+
aiAutoCompleteSuggestionState,
|
|
18
|
+
setAiAutoCompleteSuggestion,
|
|
19
|
+
} from './config.js';
|
|
20
|
+
import type {TextEditor} from './TextEditor.js';
|
|
21
|
+
|
|
22
|
+
export enum AiCodeCompletionTeaserMode {
|
|
23
|
+
OFF = 'off',
|
|
24
|
+
ON = 'on',
|
|
25
|
+
ONLY_SHOW_ON_EMPTY = 'onlyShowOnEmpty',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const setAiCodeCompletionTeaserMode = CodeMirror.StateEffect.define<AiCodeCompletionTeaserMode>();
|
|
29
|
+
|
|
30
|
+
export const aiCodeCompletionTeaserModeState = CodeMirror.StateField.define<AiCodeCompletionTeaserMode>({
|
|
31
|
+
create: () => AiCodeCompletionTeaserMode.OFF,
|
|
32
|
+
update(value, tr) {
|
|
33
|
+
return tr.effects.find(effect => effect.is(setAiCodeCompletionTeaserMode))?.value ?? value;
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export interface AiCodeCompletionConfig {
|
|
38
|
+
completionContext: {
|
|
39
|
+
additionalFiles?: Host.AidaClient.AdditionalFile[],
|
|
40
|
+
inferenceLanguage?: Host.AidaClient.AidaInferenceLanguage,
|
|
41
|
+
getPrefix?: () => string,
|
|
42
|
+
stopSequences?: string[],
|
|
43
|
+
};
|
|
44
|
+
onFeatureEnabled: () => void;
|
|
45
|
+
onFeatureDisabled: () => void;
|
|
46
|
+
onSuggestionAccepted: () => void;
|
|
47
|
+
onRequestTriggered: () => void;
|
|
48
|
+
onResponseReceived: (citations: Host.AidaClient.Citation[]) => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const DELAY_BEFORE_SHOWING_RESPONSE_MS = 500;
|
|
52
|
+
export const AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS = 200;
|
|
53
|
+
|
|
54
|
+
// TODO(samiyac): Add code relevant to AiCodeCompletion and for triggering requests
|
|
55
|
+
export class AiCodeCompletionProvider {
|
|
56
|
+
#aidaClient?: Host.AidaClient.AidaClient;
|
|
57
|
+
#aiCodeCompletionSetting = Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
|
|
58
|
+
#aiCodeCompletionTeaserDismissedSetting =
|
|
59
|
+
Common.Settings.Settings.instance().createSetting('ai-code-completion-teaser-dismissed', false);
|
|
60
|
+
#teaserCompartment = new CodeMirror.Compartment();
|
|
61
|
+
#teaser?: PanelCommon.AiCodeCompletionTeaser;
|
|
62
|
+
#suggestionRenderingTimeout?: number;
|
|
63
|
+
#editor?: TextEditor;
|
|
64
|
+
#aiCodeCompletionConfig?: AiCodeCompletionConfig;
|
|
65
|
+
|
|
66
|
+
#boundOnUpdateAiCodeCompletionState = this.#updateAiCodeCompletionState.bind(this);
|
|
67
|
+
|
|
68
|
+
constructor(aiCodeCompletionConfig: AiCodeCompletionConfig) {
|
|
69
|
+
if (!this.#isAiCodeCompletionEnabled()) {
|
|
70
|
+
throw new Error('AI code completion feature is not enabled.');
|
|
71
|
+
}
|
|
72
|
+
this.#aiCodeCompletionConfig = aiCodeCompletionConfig;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
extension(): CodeMirror.Extension[] {
|
|
76
|
+
return [
|
|
77
|
+
this.#teaserCompartment.of([]),
|
|
78
|
+
aiAutoCompleteSuggestion,
|
|
79
|
+
aiCodeCompletionTeaserModeState,
|
|
80
|
+
aiAutoCompleteSuggestionState,
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
dispose(): void {
|
|
85
|
+
this.#detachTeaser();
|
|
86
|
+
this.#teaser = undefined;
|
|
87
|
+
this.#aiCodeCompletionSetting.removeChangeListener(this.#boundOnUpdateAiCodeCompletionState);
|
|
88
|
+
Host.AidaClient.HostConfigTracker.instance().removeEventListener(
|
|
89
|
+
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnUpdateAiCodeCompletionState);
|
|
90
|
+
this.#cleanupAiCodeCompletion();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
editorInitialized(editor: TextEditor): void {
|
|
94
|
+
this.#editor = editor;
|
|
95
|
+
if (!this.#aiCodeCompletionSetting.get() && !this.#aiCodeCompletionTeaserDismissedSetting.get()) {
|
|
96
|
+
this.#teaser = new PanelCommon.AiCodeCompletionTeaser({
|
|
97
|
+
onDetach: () => this.#detachTeaser.bind(this),
|
|
98
|
+
});
|
|
99
|
+
this.#editor.editor.dispatch(
|
|
100
|
+
{effects: this.#teaserCompartment.reconfigure([aiCodeCompletionTeaserExtension(this.#teaser)])});
|
|
101
|
+
}
|
|
102
|
+
Host.AidaClient.HostConfigTracker.instance().addEventListener(
|
|
103
|
+
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnUpdateAiCodeCompletionState);
|
|
104
|
+
this.#aiCodeCompletionSetting.addChangeListener(this.#boundOnUpdateAiCodeCompletionState);
|
|
105
|
+
void this.#updateAiCodeCompletionState();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#setupAiCodeCompletion(): void {
|
|
109
|
+
if (!this.#editor || !this.#aiCodeCompletionConfig) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!this.#aidaClient) {
|
|
113
|
+
this.#aidaClient = new Host.AidaClient.AidaClient();
|
|
114
|
+
}
|
|
115
|
+
this.#aiCodeCompletionConfig.onFeatureEnabled();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
#cleanupAiCodeCompletion(): void {
|
|
119
|
+
if (this.#suggestionRenderingTimeout) {
|
|
120
|
+
clearTimeout(this.#suggestionRenderingTimeout);
|
|
121
|
+
this.#suggestionRenderingTimeout = undefined;
|
|
122
|
+
}
|
|
123
|
+
this.#editor?.dispatch({
|
|
124
|
+
effects: setAiAutoCompleteSuggestion.of(null),
|
|
125
|
+
});
|
|
126
|
+
this.#aiCodeCompletionConfig?.onFeatureDisabled();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async #updateAiCodeCompletionState(): Promise<void> {
|
|
130
|
+
const aidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
|
|
131
|
+
const isAvailable = aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE;
|
|
132
|
+
const isEnabled = this.#aiCodeCompletionSetting.get();
|
|
133
|
+
if (isAvailable && isEnabled) {
|
|
134
|
+
this.#detachTeaser();
|
|
135
|
+
this.#setupAiCodeCompletion();
|
|
136
|
+
} else if (isAvailable && !isEnabled) {
|
|
137
|
+
if (this.#teaser && !this.#aiCodeCompletionTeaserDismissedSetting.get()) {
|
|
138
|
+
this.#editor?.editor.dispatch(
|
|
139
|
+
{effects: this.#teaserCompartment.reconfigure([aiCodeCompletionTeaserExtension(this.#teaser)])});
|
|
140
|
+
}
|
|
141
|
+
this.#cleanupAiCodeCompletion();
|
|
142
|
+
} else if (!isAvailable) {
|
|
143
|
+
this.#detachTeaser();
|
|
144
|
+
this.#cleanupAiCodeCompletion();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
#detachTeaser(): void {
|
|
149
|
+
if (!this.#teaser) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
this.#editor?.editor.dispatch({effects: this.#teaserCompartment.reconfigure([])});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// TODO(samiyac): Define static method in AiCodeCompletion and use that instead
|
|
156
|
+
#isAiCodeCompletionEnabled(): boolean {
|
|
157
|
+
const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
|
|
158
|
+
const aidaAvailability = Root.Runtime.hostConfig.aidaAvailability;
|
|
159
|
+
if (!devtoolsLocale.locale.startsWith('en-')) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
if (!aidaAvailability || aidaAvailability.blockedByGeo || aidaAvailability.blockedByAge ||
|
|
163
|
+
aidaAvailability.blockedByEnterprisePolicy) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return Boolean(aidaAvailability.enabled && Root.Runtime.hostConfig.devToolsAiCodeCompletion?.enabled);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function aiCodeCompletionTeaserExtension(teaser: PanelCommon.AiCodeCompletionTeaser): CodeMirror.Extension {
|
|
171
|
+
return CodeMirror.ViewPlugin.fromClass(class {
|
|
172
|
+
teaser: PanelCommon.AiCodeCompletionTeaser;
|
|
173
|
+
#teaserDecoration: CodeMirror.DecorationSet = CodeMirror.Decoration.none;
|
|
174
|
+
#teaserMode: AiCodeCompletionTeaserMode;
|
|
175
|
+
#teaserDisplayTimeout?: number;
|
|
176
|
+
|
|
177
|
+
constructor(readonly view: CodeMirror.EditorView) {
|
|
178
|
+
this.teaser = teaser;
|
|
179
|
+
this.#teaserMode = view.state.field(aiCodeCompletionTeaserModeState);
|
|
180
|
+
this.#setupDecoration();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
destroy(): void {
|
|
184
|
+
window.clearTimeout(this.#teaserDisplayTimeout);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
update(update: CodeMirror.ViewUpdate): void {
|
|
188
|
+
const currentTeaserMode = update.state.field(aiCodeCompletionTeaserModeState);
|
|
189
|
+
if (currentTeaserMode !== this.#teaserMode) {
|
|
190
|
+
this.#teaserMode = currentTeaserMode;
|
|
191
|
+
this.#setupDecoration();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (this.#teaserMode === AiCodeCompletionTeaserMode.ONLY_SHOW_ON_EMPTY && update.docChanged) {
|
|
195
|
+
this.#updateTeaserDecorationForOnlyShowOnEmptyMode();
|
|
196
|
+
} else if (this.#teaserMode === AiCodeCompletionTeaserMode.ON) {
|
|
197
|
+
if (update.docChanged) {
|
|
198
|
+
this.#teaserDecoration = CodeMirror.Decoration.none;
|
|
199
|
+
window.clearTimeout(this.#teaserDisplayTimeout);
|
|
200
|
+
this.#updateTeaserDecorationForOnMode();
|
|
201
|
+
} else if (update.selectionSet && update.state.doc.length > 0) {
|
|
202
|
+
this.#teaserDecoration = CodeMirror.Decoration.none;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
get decorations(): CodeMirror.DecorationSet {
|
|
208
|
+
return this.#teaserDecoration;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#setupDecoration(): void {
|
|
212
|
+
switch (this.#teaserMode) {
|
|
213
|
+
case AiCodeCompletionTeaserMode.ON:
|
|
214
|
+
this.#updateTeaserDecorationForOnModeImmediately();
|
|
215
|
+
return;
|
|
216
|
+
case AiCodeCompletionTeaserMode.ONLY_SHOW_ON_EMPTY:
|
|
217
|
+
this.#updateTeaserDecorationForOnlyShowOnEmptyMode();
|
|
218
|
+
return;
|
|
219
|
+
case AiCodeCompletionTeaserMode.OFF:
|
|
220
|
+
this.#teaserDecoration = CodeMirror.Decoration.none;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#updateTeaserDecorationForOnlyShowOnEmptyMode(): void {
|
|
226
|
+
if (this.view.state.doc.length === 0) {
|
|
227
|
+
this.#addTeaserWidget(0);
|
|
228
|
+
} else {
|
|
229
|
+
this.#teaserDecoration = CodeMirror.Decoration.none;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#updateTeaserDecorationForOnMode = Common.Debouncer.debounce(() => {
|
|
234
|
+
this.#teaserDisplayTimeout = window.setTimeout(() => {
|
|
235
|
+
this.#updateTeaserDecorationForOnModeImmediately();
|
|
236
|
+
this.view.dispatch({});
|
|
237
|
+
}, DELAY_BEFORE_SHOWING_RESPONSE_MS);
|
|
238
|
+
}, AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS);
|
|
239
|
+
|
|
240
|
+
#updateTeaserDecorationForOnModeImmediately(): void {
|
|
241
|
+
const cursorPosition = this.view.state.selection.main.head;
|
|
242
|
+
const line = this.view.state.doc.lineAt(cursorPosition);
|
|
243
|
+
if (cursorPosition >= line.to) {
|
|
244
|
+
this.#addTeaserWidget(cursorPosition);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
#addTeaserWidget(pos: number): void {
|
|
249
|
+
this.#teaserDecoration = CodeMirror.Decoration.set([
|
|
250
|
+
CodeMirror.Decoration.widget({widget: new AiCodeCompletionTeaserPlaceholder(this.teaser), side: 1}).range(pos),
|
|
251
|
+
]);
|
|
252
|
+
}
|
|
253
|
+
}, {
|
|
254
|
+
decorations: v => v.decorations,
|
|
255
|
+
eventHandlers: {
|
|
256
|
+
mousedown(event: MouseEvent): boolean {
|
|
257
|
+
// Required for mouse click to propagate to the "Don't show again" span in teaser.
|
|
258
|
+
return (event.target instanceof Node && teaser.contentElement.contains(event.target));
|
|
259
|
+
},
|
|
260
|
+
keydown(event: KeyboardEvent): boolean {
|
|
261
|
+
if (!UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event) || !teaser.isShowing()) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
if (event.key === 'i') {
|
|
265
|
+
event.consume(true);
|
|
266
|
+
void VisualLogging.logKeyDown(event.currentTarget, event, 'ai-code-completion-teaser.fre');
|
|
267
|
+
void this.teaser.onAction(event);
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
if (event.key === 'x') {
|
|
271
|
+
event.consume(true);
|
|
272
|
+
void VisualLogging.logKeyDown(event.currentTarget, event, 'ai-code-completion-teaser.dismiss');
|
|
273
|
+
this.teaser.onDismiss(event);
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
+
export * as AiCodeCompletionProvider from './AiCodeCompletionProvider.js';
|
|
5
6
|
export * as AiCodeCompletionTeaserPlaceholder from './AiCodeCompletionTeaserPlaceholder.js';
|
|
6
7
|
export * as AutocompleteHistory from './AutocompleteHistory.js';
|
|
7
8
|
export * as Config from './config.js';
|
|
@@ -167,6 +167,7 @@ const proposedRectForSimpleTooltip =
|
|
|
167
167
|
|
|
168
168
|
export type TooltipVariant = 'simple'|'rich';
|
|
169
169
|
export type PaddingMode = 'small'|'large';
|
|
170
|
+
export type TooltipTrigger = 'hover'|'click'|'both';
|
|
170
171
|
|
|
171
172
|
export interface TooltipProperties {
|
|
172
173
|
id: string;
|
|
@@ -174,6 +175,7 @@ export interface TooltipProperties {
|
|
|
174
175
|
padding?: PaddingMode;
|
|
175
176
|
anchor?: HTMLElement;
|
|
176
177
|
jslogContext?: string;
|
|
178
|
+
trigger?: TooltipTrigger;
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
/**
|
|
@@ -182,7 +184,7 @@ export interface TooltipProperties {
|
|
|
182
184
|
* @property hoverDelay - reflects the `"hover-delay"` attribute.
|
|
183
185
|
* @property variant - reflects the `"variant"` attribute.
|
|
184
186
|
* @property padding - reflects the `"padding"` attribute.
|
|
185
|
-
* @property
|
|
187
|
+
* @property trigger - reflects the `"trigger"` attribute.
|
|
186
188
|
* @property verticalDistanceIncrease - reflects the `"vertical-distance-increase"` attribute.
|
|
187
189
|
* @property preferSpanLeft - reflects the `"prefer-span-left"` attribute.
|
|
188
190
|
* @attribute id - Id of the tooltip. Used for searching an anchor element with aria-describedby.
|
|
@@ -190,17 +192,19 @@ export interface TooltipProperties {
|
|
|
190
192
|
* @attribute variant - Variant of the tooltip, `"simple"` for strings only, inverted background,
|
|
191
193
|
* `"rich"` for interactive content, background according to theme's surface.
|
|
192
194
|
* @attribute padding - Which padding to use, defaults to `"small"`. Use `"large"` for richer content.
|
|
193
|
-
* @attribute
|
|
195
|
+
* @attribute trigger - Specifies which action triggers the tooltip. `"hover"` is the default. `"click"` means the
|
|
196
|
+
* tooltip will be shown on click instead of hover. `"both"` means both hover and click trigger the
|
|
197
|
+
* tooltip.
|
|
194
198
|
* @attribute vertical-distance-increase - The tooltip is moved vertically this many pixels further away from its anchor.
|
|
195
199
|
* @attribute prefer-span-left - If present, the tooltip's preferred position is `"span-left"` (The right
|
|
196
200
|
* side of the tooltip and its anchor are aligned. The tooltip expands to the left from
|
|
197
201
|
* there.). Applies to rich tooltips only.
|
|
198
202
|
* @attribute use-hotkey - If present, the tooltip will be shown on hover but not when receiving focus.
|
|
199
|
-
*
|
|
200
|
-
*
|
|
203
|
+
* Requires a hotkey to open when fosed (Alt-down). When `"trigger"` is present
|
|
204
|
+
* as well, `"trigger"` takes precedence.
|
|
201
205
|
*/
|
|
202
206
|
export class Tooltip extends HTMLElement {
|
|
203
|
-
static readonly observedAttributes = ['id', 'variant', 'jslogcontext'];
|
|
207
|
+
static readonly observedAttributes = ['id', 'variant', 'jslogcontext', 'trigger'];
|
|
204
208
|
static lastOpenedTooltipId: string|null = null;
|
|
205
209
|
|
|
206
210
|
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
@@ -231,16 +235,20 @@ export class Tooltip extends HTMLElement {
|
|
|
231
235
|
}
|
|
232
236
|
}
|
|
233
237
|
|
|
234
|
-
get
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
get trigger(): TooltipTrigger {
|
|
239
|
+
switch (this.getAttribute('trigger')) {
|
|
240
|
+
case 'click':
|
|
241
|
+
return 'click';
|
|
242
|
+
case 'both':
|
|
243
|
+
return 'both';
|
|
244
|
+
case 'hover':
|
|
245
|
+
default:
|
|
246
|
+
return 'hover';
|
|
242
247
|
}
|
|
243
248
|
}
|
|
249
|
+
set trigger(trigger: TooltipTrigger) {
|
|
250
|
+
this.setAttribute('trigger', trigger);
|
|
251
|
+
}
|
|
244
252
|
|
|
245
253
|
get hoverDelay(): number {
|
|
246
254
|
return this.hasAttribute('hover-delay') ? Number(this.getAttribute('hover-delay')) : 300;
|
|
@@ -297,7 +305,7 @@ export class Tooltip extends HTMLElement {
|
|
|
297
305
|
|
|
298
306
|
constructor(properties?: TooltipProperties) {
|
|
299
307
|
super();
|
|
300
|
-
const {id, variant, padding, jslogContext, anchor} = properties ?? {};
|
|
308
|
+
const {id, variant, padding, jslogContext, anchor, trigger} = properties ?? {};
|
|
301
309
|
if (id) {
|
|
302
310
|
this.id = id;
|
|
303
311
|
}
|
|
@@ -317,6 +325,9 @@ export class Tooltip extends HTMLElement {
|
|
|
317
325
|
}
|
|
318
326
|
this.#anchor = anchor;
|
|
319
327
|
}
|
|
328
|
+
if (trigger) {
|
|
329
|
+
this.trigger = trigger;
|
|
330
|
+
}
|
|
320
331
|
}
|
|
321
332
|
|
|
322
333
|
attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
|
|
@@ -432,7 +443,7 @@ export class Tooltip extends HTMLElement {
|
|
|
432
443
|
this.#previousAnchorRect = anchorRect;
|
|
433
444
|
this.#previousPopoverRect = currentPopoverRect;
|
|
434
445
|
|
|
435
|
-
const inspectorViewRect = UI.
|
|
446
|
+
const inspectorViewRect = UI.UIUtils.getDevToolsBoundingElement().getBoundingClientRect();
|
|
436
447
|
const preferredPositions =
|
|
437
448
|
this.preferSpanLeft ? [PositionOption.BOTTOM_SPAN_LEFT, PositionOption.TOP_SPAN_LEFT] : [];
|
|
438
449
|
const proposedPopoverRect = this.variant === 'rich' ?
|
|
@@ -463,7 +474,7 @@ export class Tooltip extends HTMLElement {
|
|
|
463
474
|
if (!this.hasAttribute('role')) {
|
|
464
475
|
this.setAttribute('role', 'tooltip');
|
|
465
476
|
}
|
|
466
|
-
this.setAttribute('popover', this.
|
|
477
|
+
this.setAttribute('popover', this.trigger === 'hover' ? 'manual' : 'auto');
|
|
467
478
|
this.#updateJslog();
|
|
468
479
|
}
|
|
469
480
|
|
|
@@ -474,6 +485,9 @@ export class Tooltip extends HTMLElement {
|
|
|
474
485
|
#setClosing = (event: Event): void => {
|
|
475
486
|
if ((event as ToggleEvent).newState === 'closed') {
|
|
476
487
|
this.#closing = true;
|
|
488
|
+
if (this.#timeout) {
|
|
489
|
+
window.clearTimeout(this.#timeout);
|
|
490
|
+
}
|
|
477
491
|
}
|
|
478
492
|
};
|
|
479
493
|
|
|
@@ -521,9 +535,10 @@ export class Tooltip extends HTMLElement {
|
|
|
521
535
|
// as we always want to support ESC to close.
|
|
522
536
|
this.#anchor.addEventListener('keydown', this.#keyDown);
|
|
523
537
|
|
|
524
|
-
if (this.
|
|
538
|
+
if (this.trigger === 'click' || this.trigger === 'both') {
|
|
525
539
|
this.#anchor.addEventListener('click', this.toggle);
|
|
526
|
-
}
|
|
540
|
+
}
|
|
541
|
+
if (this.trigger === 'hover' || this.trigger === 'both') {
|
|
527
542
|
this.#anchor.addEventListener('mouseenter', this.showTooltip);
|
|
528
543
|
if (!this.useHotkey) {
|
|
529
544
|
this.#anchor.addEventListener('focus', this.showTooltip);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright 2025 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
|
+
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
6
|
+
|
|
7
|
+
import * as I18n from '../../core/i18n/i18n.js';
|
|
8
|
+
import type * as ThirdPartyI18n from '../../third_party/i18n/i18n.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns a span element that may contains other DOM element as placeholders
|
|
12
|
+
*/
|
|
13
|
+
export function getFormatLocalizedString(
|
|
14
|
+
registeredStrings: ThirdPartyI18n.LocalizedStringSet.RegisteredFileStrings, stringId: string,
|
|
15
|
+
placeholders: Record<string, Object>): HTMLSpanElement {
|
|
16
|
+
const formatter = registeredStrings.getLocalizedStringSetFor(I18n.DevToolsLocale.DevToolsLocale.instance().locale)
|
|
17
|
+
.getMessageFormatterFor(stringId);
|
|
18
|
+
|
|
19
|
+
const element = document.createElement('span');
|
|
20
|
+
for (const icuElement of formatter.getAst()) {
|
|
21
|
+
if (icuElement.type === /* argumentElement */ 1) {
|
|
22
|
+
const placeholderValue = placeholders[icuElement.value];
|
|
23
|
+
if (placeholderValue) {
|
|
24
|
+
element.append(placeholderValue as Node | string);
|
|
25
|
+
}
|
|
26
|
+
} else if ('value' in icuElement) {
|
|
27
|
+
element.append(String(icuElement.value));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return element;
|
|
31
|
+
}
|
|
@@ -33,7 +33,6 @@ export class Dialog extends Common.ObjectWrapper.eventMixin<EventTypes, typeof G
|
|
|
33
33
|
this.contentElement.setAttribute(
|
|
34
34
|
'jslog', `${VisualLogging.dialog(jslogContext).track({resize: true, keydown: 'Escape'})}`);
|
|
35
35
|
}
|
|
36
|
-
this.widget().setDefaultFocusedElement(this.contentElement);
|
|
37
36
|
this.setPointerEventsBehavior(PointerEventsBehavior.BLOCKED_BY_GLASS_PANE);
|
|
38
37
|
this.setOutsideClickCallback(event => {
|
|
39
38
|
// If there are stacked dialogs, we only want to
|
|
@@ -205,16 +205,6 @@ const bindCheckboxImpl = function(
|
|
|
205
205
|
};
|
|
206
206
|
};
|
|
207
207
|
|
|
208
|
-
export const createCustomSetting = function(name: string, element: Element): Element {
|
|
209
|
-
const p = document.createElement('p');
|
|
210
|
-
p.classList.add('settings-select');
|
|
211
|
-
const label = p.createChild('label');
|
|
212
|
-
label.textContent = name;
|
|
213
|
-
ARIAUtils.bindLabelToControl(label, element);
|
|
214
|
-
p.appendChild(element);
|
|
215
|
-
return p;
|
|
216
|
-
};
|
|
217
|
-
|
|
218
208
|
export const createControlForSetting = function(
|
|
219
209
|
setting: Common.Settings.Setting<unknown>, subtitle?: string): HTMLElement|null {
|
|
220
210
|
const uiTitle = setting.title();
|
|
@@ -239,10 +229,6 @@ export const createControlForSetting = function(
|
|
|
239
229
|
}
|
|
240
230
|
};
|
|
241
231
|
|
|
242
|
-
export interface SettingUI {
|
|
243
|
-
settingElement(): Element|null;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
232
|
/**
|
|
247
233
|
* Track toggle action as a whole or
|
|
248
234
|
* track on and off action separately.
|
|
@@ -38,7 +38,6 @@ export class SoftDropDown<T> implements ListDelegate<T> {
|
|
|
38
38
|
private list: ListControl<T>;
|
|
39
39
|
private rowHeight: number;
|
|
40
40
|
private width: number;
|
|
41
|
-
private listWasShowing200msAgo: boolean;
|
|
42
41
|
|
|
43
42
|
constructor(model: ListModel<T>, delegate: Delegate<T>, jslogContext?: string) {
|
|
44
43
|
this.delegate = delegate;
|
|
@@ -79,9 +78,8 @@ export class SoftDropDown<T> implements ListDelegate<T> {
|
|
|
79
78
|
'jslog',
|
|
80
79
|
`${VisualLogging.menu().parent('mapped').track({resize: true, keydown: 'ArrowUp|ArrowDown|PageUp|PageDown'})}`);
|
|
81
80
|
|
|
82
|
-
this.listWasShowing200msAgo = false;
|
|
83
81
|
this.element.addEventListener('mousedown', event => {
|
|
84
|
-
if (this.
|
|
82
|
+
if (this.glassPane.isShowing()) {
|
|
85
83
|
this.hide(event);
|
|
86
84
|
} else if (!this.element.disabled) {
|
|
87
85
|
this.show(event);
|
|
@@ -96,9 +94,6 @@ export class SoftDropDown<T> implements ListDelegate<T> {
|
|
|
96
94
|
return;
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
if (!this.listWasShowing200msAgo) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
97
|
this.selectHighlightedItem();
|
|
103
98
|
if (event.target instanceof Element && event.target?.parentElement) {
|
|
104
99
|
// hide() will consume the mouseup event and click won't be triggered
|
|
@@ -122,9 +117,6 @@ export class SoftDropDown<T> implements ListDelegate<T> {
|
|
|
122
117
|
this.list.selectItem(this.selectedItem);
|
|
123
118
|
}
|
|
124
119
|
event.consume(true);
|
|
125
|
-
window.setTimeout(() => {
|
|
126
|
-
this.listWasShowing200msAgo = true;
|
|
127
|
-
}, 200);
|
|
128
120
|
}
|
|
129
121
|
|
|
130
122
|
private updateGlasspaneSize(): void {
|
|
@@ -134,9 +126,6 @@ export class SoftDropDown<T> implements ListDelegate<T> {
|
|
|
134
126
|
}
|
|
135
127
|
|
|
136
128
|
private hide(event: Event): void {
|
|
137
|
-
window.setTimeout(() => {
|
|
138
|
-
this.listWasShowing200msAgo = false;
|
|
139
|
-
}, 200);
|
|
140
129
|
this.glassPane.hide();
|
|
141
130
|
this.list.selectItem(null);
|
|
142
131
|
ARIAUtils.setExpanded(this.element, false);
|
|
@@ -164,14 +164,12 @@ export interface EventTypes {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
export class ViewManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
167
|
-
readonly views
|
|
168
|
-
private readonly locationNameByViewId
|
|
167
|
+
readonly views = new Map<string, View>();
|
|
168
|
+
private readonly locationNameByViewId = new Map<string, string>();
|
|
169
169
|
private readonly locationOverrideSetting: Common.Settings.Setting<Record<string, string>>;
|
|
170
170
|
|
|
171
171
|
private constructor() {
|
|
172
172
|
super();
|
|
173
|
-
this.views = new Map();
|
|
174
|
-
this.locationNameByViewId = new Map();
|
|
175
173
|
|
|
176
174
|
// Read override setting for location
|
|
177
175
|
this.locationOverrideSetting = Common.Settings.Settings.instance().createSetting('views-location-override', {});
|