chrome-devtools-frontend 1.0.1536371 → 1.0.1537860
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/.env.template +9 -0
- package/docs/get_the_code.md +27 -0
- package/front_end/core/common/SettingRegistration.ts +10 -7
- package/front_end/core/common/Settings.ts +3 -0
- 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/protocol_client/CDPConnection.ts +10 -8
- package/front_end/core/protocol_client/InspectorBackend.ts +36 -42
- package/front_end/core/sdk/EnhancedTracesParser.ts +20 -5
- package/front_end/core/sdk/RehydratingConnection.ts +112 -4
- package/front_end/core/sdk/RehydratingObject.ts +8 -0
- package/front_end/core/sdk/TraceObject.ts +5 -1
- package/front_end/core/sdk/sdk-meta.ts +8 -2
- package/front_end/entrypoints/inspector_main/RenderingOptions.ts +4 -3
- package/front_end/generated/SupportedCSSProperties.js +1 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +23 -7
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +110 -5
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +50 -45
- package/front_end/models/cpu_profile/ProfileTreeModel.ts +7 -7
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
- package/front_end/models/trace/types/File.ts +9 -0
- package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -9
- package/front_end/panels/ai_assistance/components/ChatView.ts +58 -70
- package/front_end/panels/application/BackForwardCacheTreeElement.ts +2 -6
- package/front_end/panels/application/StorageView.ts +3 -2
- package/front_end/panels/application/components/BackForwardCacheView.ts +96 -108
- package/front_end/panels/application/components/FrameDetailsView.ts +8 -11
- package/front_end/panels/application/components/OriginTrialTreeView.ts +136 -137
- package/front_end/panels/application/components/backForwardCacheView.css +8 -0
- package/front_end/panels/application/components/badge.css +9 -1
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +2 -2
- package/front_end/panels/application/preloading/components/PreloadingString.ts +27 -0
- package/front_end/panels/autofill/AutofillView.ts +1 -1
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +44 -53
- package/front_end/panels/console/ConsoleView.ts +11 -9
- package/front_end/panels/coverage/CoverageView.ts +1 -2
- package/front_end/panels/css_overview/CSSOverviewSidebarPanel.ts +1 -1
- package/front_end/panels/developer_resources/DeveloperResourcesView.ts +1 -1
- package/front_end/panels/elements/ElementStatePaneWidget.ts +1 -1
- package/front_end/panels/elements/EventListenersWidget.ts +1 -2
- package/front_end/panels/elements/PropertiesWidget.ts +1 -1
- package/front_end/panels/network/NetworkConfigView.ts +2 -1
- package/front_end/panels/network/NetworkPanel.ts +5 -4
- package/front_end/panels/network/RequestCookiesView.ts +2 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +3 -2
- package/front_end/panels/recorder/RecorderController.ts +1 -2
- package/front_end/panels/recorder/components/CreateRecordingView.ts +153 -129
- package/front_end/panels/sensors/SensorsView.ts +4 -3
- package/front_end/panels/settings/AISettingsTab.ts +162 -171
- package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +8 -6
- package/front_end/panels/settings/KeybindsSettingsTab.ts +3 -2
- package/front_end/panels/settings/SettingsScreen.ts +5 -8
- package/front_end/panels/settings/WorkspaceSettingsTab.ts +1 -1
- package/front_end/panels/settings/aiSettingsTab.css +151 -148
- package/front_end/panels/settings/settings-meta.ts +1 -2
- package/front_end/panels/sources/AddSourceMapURLDialog.ts +23 -26
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -1
- package/front_end/panels/sources/SourcesPanel.ts +2 -1
- package/front_end/panels/sources/sources-meta.ts +8 -1
- package/front_end/panels/timeline/TimelinePanel.ts +64 -14
- package/front_end/panels/timeline/TimelineUIUtils.ts +4 -20
- package/front_end/panels/timeline/components/ExportTraceOptions.ts +33 -34
- package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -0
- package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +2 -0
- 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/adorners/Adorner.ts +2 -1
- package/front_end/ui/components/buttons/Button.docs.ts +195 -0
- package/front_end/ui/components/settings/SettingCheckbox.ts +49 -14
- package/front_end/ui/components/settings/settingCheckbox.css +6 -1
- package/front_end/ui/components/spinners/Spinners.docs.ts +13 -0
- 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.docs.ts +76 -0
- package/front_end/ui/components/tooltips/Tooltip.ts +1 -1
- package/front_end/ui/legacy/Dialog.ts +0 -1
- package/front_end/ui/legacy/FilterBar.ts +1 -2
- package/front_end/ui/legacy/RadioButton.docs.ts +41 -0
- package/front_end/ui/legacy/SelectMenu.docs.ts +98 -0
- package/front_end/ui/legacy/Toolbar.ts +4 -6
- package/front_end/ui/legacy/UIUtils.ts +114 -1
- package/front_end/ui/legacy/Widget.ts +62 -34
- 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/settings_ui/SettingsUI.ts +125 -0
- package/front_end/ui/legacy/components/settings_ui/settings_ui.ts +8 -0
- 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 +5 -0
- package/package.json +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +0 -4
- package/front_end/models/trace/lantern/testing/MetricTestUtils.ts +0 -62
- package/front_end/models/trace/lantern/testing/testing.ts +0 -5
- 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/button/basic.html +0 -44
- package/front_end/ui/components/docs/button/basic.ts +0 -175
- package/front_end/ui/components/docs/radio_button/basic.html +0 -23
- package/front_end/ui/components/docs/radio_button/basic.ts +0 -50
- package/front_end/ui/components/docs/select_menu/basic.html +0 -19
- package/front_end/ui/components/docs/select_menu/basic.ts +0 -95
- package/front_end/ui/components/docs/select_menu/wide-option.html +0 -38
- package/front_end/ui/components/docs/select_menu/wide-option.ts +0 -43
- package/front_end/ui/components/docs/spinners/basic.html +0 -17
- package/front_end/ui/components/docs/spinners/basic.ts +0 -22
- package/front_end/ui/components/docs/tooltip/basic.html +0 -20
- package/front_end/ui/components/docs/tooltip/basic.ts +0 -82
- package/front_end/ui/legacy/SettingsUI.ts +0 -254
|
@@ -0,0 +1,76 @@
|
|
|
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 Lit from '../../lit/lit.js';
|
|
6
|
+
|
|
7
|
+
import {Tooltip} from './Tooltip.js';
|
|
8
|
+
|
|
9
|
+
const {html} = Lit;
|
|
10
|
+
|
|
11
|
+
export async function render(container: HTMLElement) {
|
|
12
|
+
Lit.render(
|
|
13
|
+
html`
|
|
14
|
+
<div style="position: relative; z-index: 0;">
|
|
15
|
+
<button aria-describedby="simple-tooltip" style="position: absolute; left: 16px; top: 16px;">
|
|
16
|
+
Simple
|
|
17
|
+
</button>
|
|
18
|
+
<devtools-tooltip id="simple-tooltip">Simple content</devtools-tooltip>
|
|
19
|
+
</div>
|
|
20
|
+
<div style="position: relative; z-index: 0;">
|
|
21
|
+
<span
|
|
22
|
+
aria-details="rich-tooltip"
|
|
23
|
+
style="position: absolute; left: 16px; top: 116px; border: 1px solid black;"
|
|
24
|
+
>
|
|
25
|
+
Non-button click trigger
|
|
26
|
+
</span>
|
|
27
|
+
<devtools-tooltip id="rich-tooltip" variant="rich" use-click>
|
|
28
|
+
<p>Rich tooltip</p>
|
|
29
|
+
<button>Action</button>
|
|
30
|
+
</devtools-tooltip>
|
|
31
|
+
</div>
|
|
32
|
+
<div style="position: relative; z-index: 0;">
|
|
33
|
+
<button
|
|
34
|
+
id="removable"
|
|
35
|
+
@click=${() => document.getElementById('removable')?.remove()}
|
|
36
|
+
class="anchor"
|
|
37
|
+
aria-details="programatic"
|
|
38
|
+
style="position: absolute; left: 16px; top: 216px;"
|
|
39
|
+
>
|
|
40
|
+
Click to remove anchor
|
|
41
|
+
</button>
|
|
42
|
+
</div>
|
|
43
|
+
`,
|
|
44
|
+
container);
|
|
45
|
+
|
|
46
|
+
const anchor = container.querySelector('.anchor') as HTMLElement;
|
|
47
|
+
const programmaticTooltip = new Tooltip({id: 'programatic', variant: 'rich', anchor});
|
|
48
|
+
programmaticTooltip.append('Text content');
|
|
49
|
+
anchor.insertAdjacentElement('afterend', programmaticTooltip);
|
|
50
|
+
|
|
51
|
+
// Make the buttons draggable, so that we can experiment with the position of the tooltip.
|
|
52
|
+
container.querySelectorAll('button,span').forEach(anchor => draggable(anchor as HTMLElement));
|
|
53
|
+
function draggable(element: HTMLElement|null): void {
|
|
54
|
+
if (!element) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
element.addEventListener('mousedown', event => {
|
|
58
|
+
const target = event.target as HTMLElement;
|
|
59
|
+
const offsetX = event.clientX - target.getBoundingClientRect().left + container.getBoundingClientRect().left;
|
|
60
|
+
const offsetY = event.clientY - target.getBoundingClientRect().top + container.getBoundingClientRect().top;
|
|
61
|
+
|
|
62
|
+
function onMouseMove(event: MouseEvent) {
|
|
63
|
+
target.style.left = `${event.clientX - offsetX}px`;
|
|
64
|
+
target.style.top = `${event.clientY - offsetY}px`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function onMouseUp() {
|
|
68
|
+
document.removeEventListener('mousemove', onMouseMove);
|
|
69
|
+
document.removeEventListener('mouseup', onMouseUp);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
73
|
+
document.addEventListener('mouseup', onMouseUp);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -443,7 +443,7 @@ export class Tooltip extends HTMLElement {
|
|
|
443
443
|
this.#previousAnchorRect = anchorRect;
|
|
444
444
|
this.#previousPopoverRect = currentPopoverRect;
|
|
445
445
|
|
|
446
|
-
const inspectorViewRect = UI.
|
|
446
|
+
const inspectorViewRect = UI.UIUtils.getDevToolsBoundingElement().getBoundingClientRect();
|
|
447
447
|
const preferredPositions =
|
|
448
448
|
this.preferSpanLeft ? [PositionOption.BOTTOM_SPAN_LEFT, PositionOption.TOP_SPAN_LEFT] : [];
|
|
449
449
|
const proposedPopoverRect = this.variant === 'rich' ?
|
|
@@ -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
|
|
@@ -15,11 +15,10 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
|
15
15
|
import * as ARIAUtils from './ARIAUtils.js';
|
|
16
16
|
import filterStyles from './filter.css.js';
|
|
17
17
|
import {KeyboardShortcut, Modifiers} from './KeyboardShortcut.js';
|
|
18
|
-
import {bindCheckbox} from './SettingsUI.js';
|
|
19
18
|
import type {Suggestions} from './SuggestBox.js';
|
|
20
19
|
import {type ToolbarButton, ToolbarFilter, ToolbarInput, ToolbarSettingToggle} from './Toolbar.js';
|
|
21
20
|
import {Tooltip} from './Tooltip.js';
|
|
22
|
-
import {CheckboxLabel, createTextChild} from './UIUtils.js';
|
|
21
|
+
import {bindCheckbox, CheckboxLabel, createTextChild} from './UIUtils.js';
|
|
23
22
|
import {HBox} from './Widget.js';
|
|
24
23
|
|
|
25
24
|
const UIStrings = {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2024 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 {UIUtils} from './legacy.js';
|
|
6
|
+
|
|
7
|
+
export async function render(container: HTMLElement) {
|
|
8
|
+
const styleElement = document.createElement('style');
|
|
9
|
+
styleElement.textContent = 'fieldset { label { display: block; } }';
|
|
10
|
+
container.appendChild(styleElement);
|
|
11
|
+
|
|
12
|
+
function radioExample({name, tabbable, disabled}: {
|
|
13
|
+
name: string,
|
|
14
|
+
tabbable: boolean,
|
|
15
|
+
disabled: boolean,
|
|
16
|
+
}): HTMLElement {
|
|
17
|
+
const example = document.createElement('fieldset');
|
|
18
|
+
example.style.marginTop = '20px';
|
|
19
|
+
const legend = document.createElement('legend');
|
|
20
|
+
legend.textContent = name;
|
|
21
|
+
const list = document.createElement('div');
|
|
22
|
+
for (let i = 0; i < 3; ++i) {
|
|
23
|
+
const {label, radio} = UIUtils.createRadioButton(name, `Option #${i + 1}`, name);
|
|
24
|
+
radio.tabIndex = tabbable ? 0 : -1;
|
|
25
|
+
radio.disabled = disabled;
|
|
26
|
+
radio.checked = i === 0;
|
|
27
|
+
list.append(label);
|
|
28
|
+
}
|
|
29
|
+
example.append(legend, list);
|
|
30
|
+
return example;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Basic
|
|
34
|
+
container.appendChild(radioExample({name: 'basic', tabbable: true, disabled: false}));
|
|
35
|
+
|
|
36
|
+
// Not tab reachable
|
|
37
|
+
container.appendChild(radioExample({name: 'not-table-reachable', tabbable: false, disabled: false}));
|
|
38
|
+
|
|
39
|
+
// Disabled
|
|
40
|
+
container.appendChild(radioExample({name: 'disabled', tabbable: true, disabled: true}));
|
|
41
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Copyright 2023 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 Lit from '../lit/lit.js';
|
|
6
|
+
import * as VisualLogging from '../visual_logging/visual_logging.js';
|
|
7
|
+
|
|
8
|
+
import {UIUtils} from './legacy.js';
|
|
9
|
+
|
|
10
|
+
const {html} = Lit;
|
|
11
|
+
|
|
12
|
+
export async function render(container: HTMLElement) {
|
|
13
|
+
function createDivWithP(text: string): HTMLDivElement {
|
|
14
|
+
const div = document.createElement('div');
|
|
15
|
+
div.style.paddingLeft = '25px';
|
|
16
|
+
const p = document.createElement('p');
|
|
17
|
+
p.style.marginLeft = '-25px';
|
|
18
|
+
p.textContent = text;
|
|
19
|
+
div.appendChild(p);
|
|
20
|
+
container.appendChild(div);
|
|
21
|
+
return div;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function onChange(event: Event): void {
|
|
25
|
+
const menu = event.target;
|
|
26
|
+
if (menu instanceof HTMLSelectElement) {
|
|
27
|
+
// eslint-disable-next-line no-console
|
|
28
|
+
console.log('Option selected: ', menu.value);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
const simpleMenuHTML = createDivWithP('Simple item select with lit-html');
|
|
34
|
+
Lit.render(
|
|
35
|
+
html`<select id="menu" aria-label="Select an option"
|
|
36
|
+
@change=${onChange}>
|
|
37
|
+
<option hidden>Select an option</option>
|
|
38
|
+
<option id="option-1" jslog=${VisualLogging.item('option-1').track({
|
|
39
|
+
click: true
|
|
40
|
+
})}
|
|
41
|
+
value="Option1">Option 1</option>
|
|
42
|
+
<option jslog=${VisualLogging.item('option-2').track({
|
|
43
|
+
click: true
|
|
44
|
+
})}
|
|
45
|
+
value="Option2">Option 2</option>
|
|
46
|
+
<option disabled jslog=${VisualLogging.item('option-3').track({
|
|
47
|
+
click: true
|
|
48
|
+
})}
|
|
49
|
+
value="Option3">Option 3</option>
|
|
50
|
+
</select>`,
|
|
51
|
+
simpleMenuHTML);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
const groupMenuHTML = createDivWithP('Select with groups with lit-html');
|
|
56
|
+
Lit.render(
|
|
57
|
+
html`<select aria-label="Select an option"
|
|
58
|
+
@change=${onChange}>
|
|
59
|
+
<optgroup label="Group 1">
|
|
60
|
+
<option jslog=${VisualLogging.item('option-1').track({
|
|
61
|
+
click: true
|
|
62
|
+
})}
|
|
63
|
+
value="Option1">Option 1</option>
|
|
64
|
+
</optgroup>
|
|
65
|
+
<optgroup label="Group 2">
|
|
66
|
+
<option jslog=${VisualLogging.item('option-2').track({
|
|
67
|
+
click: true
|
|
68
|
+
})}
|
|
69
|
+
value="Option2">Option 2</option>
|
|
70
|
+
<option jslog=${VisualLogging.item('option-3').track({
|
|
71
|
+
click: true
|
|
72
|
+
})}
|
|
73
|
+
value="Option3">Option 3</option>
|
|
74
|
+
</optgroup>
|
|
75
|
+
</select>`,
|
|
76
|
+
groupMenuHTML);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
const simpleMenuImperative = createDivWithP('Simple item select with imperative API');
|
|
81
|
+
const simpleSelect = UIUtils.createSelect('Select an option', [
|
|
82
|
+
'Option 1',
|
|
83
|
+
'Option 2',
|
|
84
|
+
'Option 3',
|
|
85
|
+
]);
|
|
86
|
+
simpleSelect.addEventListener('change', event => onChange(event));
|
|
87
|
+
simpleMenuImperative.appendChild(simpleSelect);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
{
|
|
91
|
+
const groupMenuImperative = createDivWithP('Select with groups with imperative API');
|
|
92
|
+
const group1 = new Map<string, string[]>([['Group 1', ['Option 1']]]);
|
|
93
|
+
const group2 = new Map<string, string[]>([['Group 2', ['Option 2', 'Option 3']]]);
|
|
94
|
+
const groupSelect = UIUtils.createSelect('Select an option', [group1, group2]);
|
|
95
|
+
groupSelect.addEventListener('change', event => onChange(event));
|
|
96
|
+
groupMenuImperative.appendChild(groupSelect);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -10,7 +10,6 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
10
10
|
import * as Root from '../../core/root/root.js';
|
|
11
11
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
12
12
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
13
|
-
import type * as Adorners from '../components/adorners/adorners.js';
|
|
14
13
|
import * as IconButton from '../components/icon_button/icon_button.js';
|
|
15
14
|
|
|
16
15
|
import {type Action, Events as ActionEvents} from './ActionRegistration.js';
|
|
@@ -18,12 +17,11 @@ import {ActionRegistry} from './ActionRegistry.js';
|
|
|
18
17
|
import * as ARIAUtils from './ARIAUtils.js';
|
|
19
18
|
import {ContextMenu} from './ContextMenu.js';
|
|
20
19
|
import {GlassPane, PointerEventsBehavior} from './GlassPane.js';
|
|
21
|
-
import {bindCheckbox} from './SettingsUI.js';
|
|
22
20
|
import type {Suggestion} from './SuggestBox.js';
|
|
23
21
|
import {Events as TextPromptEvents, TextPrompt} from './TextPrompt.js';
|
|
24
22
|
import toolbarStyles from './toolbar.css.js';
|
|
25
23
|
import {Tooltip} from './Tooltip.js';
|
|
26
|
-
import {CheckboxLabel, LongClickController} from './UIUtils.js';
|
|
24
|
+
import {bindCheckbox, CheckboxLabel, LongClickController} from './UIUtils.js';
|
|
27
25
|
|
|
28
26
|
const UIStrings = {
|
|
29
27
|
/**
|
|
@@ -643,7 +641,7 @@ export class ToolbarButton extends ToolbarItem<ToolbarButton.EventTypes, Buttons
|
|
|
643
641
|
this.text = text;
|
|
644
642
|
}
|
|
645
643
|
|
|
646
|
-
setAdorner(adorner:
|
|
644
|
+
setAdorner(adorner: HTMLElement): void {
|
|
647
645
|
if (this.adorner) {
|
|
648
646
|
this.adorner.replaceWith(adorner);
|
|
649
647
|
} else {
|
|
@@ -971,7 +969,7 @@ export class ToolbarMenuButton extends ToolbarItem<ToolbarButton.EventTypes> {
|
|
|
971
969
|
private textElement?: HTMLElement;
|
|
972
970
|
private text?: string;
|
|
973
971
|
private iconName?: string;
|
|
974
|
-
private adorner?:
|
|
972
|
+
private adorner?: HTMLElement;
|
|
975
973
|
private readonly contextMenuHandler: (arg0: ContextMenu) => void;
|
|
976
974
|
private readonly useSoftMenu: boolean;
|
|
977
975
|
private readonly keepOpen: boolean;
|
|
@@ -1028,7 +1026,7 @@ export class ToolbarMenuButton extends ToolbarItem<ToolbarButton.EventTypes> {
|
|
|
1028
1026
|
this.text = text;
|
|
1029
1027
|
}
|
|
1030
1028
|
|
|
1031
|
-
setAdorner(adorner:
|
|
1029
|
+
setAdorner(adorner: HTMLElement): void {
|
|
1032
1030
|
if (this.iconName) {
|
|
1033
1031
|
return;
|
|
1034
1032
|
}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
import './Toolbar.js';
|
|
38
38
|
|
|
39
|
-
import
|
|
39
|
+
import * as Common from '../../core/common/common.js';
|
|
40
40
|
import * as Host from '../../core/host/host.js';
|
|
41
41
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
42
42
|
import * as Platform from '../../core/platform/platform.js';
|
|
@@ -2353,3 +2353,116 @@ export function copyTextToClipboard(text: string, alert?: string): void {
|
|
|
2353
2353
|
export function getDevToolsBoundingElement(): HTMLElement {
|
|
2354
2354
|
return InspectorView.maybeGetInspectorViewInstance()?.element || document.body;
|
|
2355
2355
|
}
|
|
2356
|
+
|
|
2357
|
+
/**
|
|
2358
|
+
* @deprecated Prefer {@link bindToSetting} as this function leaks the checkbox via the setting listener.
|
|
2359
|
+
*/
|
|
2360
|
+
export const bindCheckbox = function(
|
|
2361
|
+
input: CheckboxLabel, setting: Common.Settings.Setting<boolean>, metric?: UserMetricOptions): void {
|
|
2362
|
+
const setValue = bindCheckboxImpl(input, setting.set.bind(setting), metric);
|
|
2363
|
+
setting.addChangeListener(event => setValue(event.data));
|
|
2364
|
+
setValue(setting.get());
|
|
2365
|
+
};
|
|
2366
|
+
|
|
2367
|
+
export const bindCheckboxImpl = function(
|
|
2368
|
+
input: CheckboxLabel, apply: (value: boolean) => void, metric?: UserMetricOptions): (value: boolean) => void {
|
|
2369
|
+
input.addEventListener('change', onInputChanged, false);
|
|
2370
|
+
|
|
2371
|
+
function onInputChanged(): void {
|
|
2372
|
+
apply(input.checked);
|
|
2373
|
+
|
|
2374
|
+
if (input.checked && metric?.enable) {
|
|
2375
|
+
Host.userMetrics.actionTaken(metric.enable);
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
if (!input.checked && metric?.disable) {
|
|
2379
|
+
Host.userMetrics.actionTaken(metric.disable);
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
if (metric?.toggle) {
|
|
2383
|
+
Host.userMetrics.actionTaken(metric.toggle);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
return function setValue(value: boolean): void {
|
|
2388
|
+
if (value !== input.checked) {
|
|
2389
|
+
input.checked = value;
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
};
|
|
2393
|
+
|
|
2394
|
+
export const bindToSetting =
|
|
2395
|
+
(settingOrName: string|Common.Settings.Setting<boolean|string>|Common.Settings.RegExpSetting,
|
|
2396
|
+
stringValidator?: (newSettingValue: string) => boolean): ReturnType<typeof Directives.ref> => {
|
|
2397
|
+
const setting = typeof settingOrName === 'string' ?
|
|
2398
|
+
Common.Settings.Settings.instance().moduleSetting(settingOrName) :
|
|
2399
|
+
settingOrName;
|
|
2400
|
+
|
|
2401
|
+
// We can't use `setValue` as the change listener directly, otherwise we won't
|
|
2402
|
+
// be able to remove it again.
|
|
2403
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2404
|
+
let setValue: (value: any) => void;
|
|
2405
|
+
function settingChanged(): void {
|
|
2406
|
+
setValue(setting.get());
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
if (setting.type() === Common.Settings.SettingType.BOOLEAN || typeof setting.defaultValue === 'boolean') {
|
|
2410
|
+
return Directives.ref(e => {
|
|
2411
|
+
if (e === undefined) {
|
|
2412
|
+
setting.removeChangeListener(settingChanged);
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
setting.addChangeListener(settingChanged);
|
|
2417
|
+
setValue =
|
|
2418
|
+
bindCheckboxImpl(e as CheckboxLabel, (setting as Common.Settings.Setting<boolean>).set.bind(setting));
|
|
2419
|
+
setValue(setting.get());
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
if (setting.type() === Common.Settings.SettingType.REGEX || setting instanceof Common.Settings.RegExpSetting) {
|
|
2424
|
+
return Directives.ref(e => {
|
|
2425
|
+
if (e === undefined) {
|
|
2426
|
+
setting.removeChangeListener(settingChanged);
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
setting.addChangeListener(settingChanged);
|
|
2431
|
+
setValue = bindInput(e as HTMLInputElement, setting.set.bind(setting), (value: string) => {
|
|
2432
|
+
try {
|
|
2433
|
+
new RegExp(value);
|
|
2434
|
+
return true;
|
|
2435
|
+
} catch {
|
|
2436
|
+
return false;
|
|
2437
|
+
}
|
|
2438
|
+
}, /* numeric */ false);
|
|
2439
|
+
setValue(setting.get());
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
if (typeof setting.defaultValue === 'string') {
|
|
2444
|
+
return Directives.ref(e => {
|
|
2445
|
+
if (e === undefined) {
|
|
2446
|
+
setting.removeChangeListener(settingChanged);
|
|
2447
|
+
return;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
setting.addChangeListener(settingChanged);
|
|
2451
|
+
setValue = bindInput(
|
|
2452
|
+
e as HTMLInputElement, setting.set.bind(setting), stringValidator ?? (() => true), /* numeric */ false);
|
|
2453
|
+
setValue(setting.get());
|
|
2454
|
+
});
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
throw new Error(`Cannot infer type for setting '${setting.name}'`);
|
|
2458
|
+
};
|
|
2459
|
+
|
|
2460
|
+
/**
|
|
2461
|
+
* Track toggle action as a whole or
|
|
2462
|
+
* track on and off action separately.
|
|
2463
|
+
*/
|
|
2464
|
+
export interface UserMetricOptions {
|
|
2465
|
+
toggle?: Host.UserMetrics.Action;
|
|
2466
|
+
enable?: Host.UserMetrics.Action;
|
|
2467
|
+
disable?: Host.UserMetrics.Action;
|
|
2468
|
+
}
|
|
@@ -68,6 +68,64 @@ export function widgetConfig<F extends WidgetFactory<Widget>, ParamKeys extends
|
|
|
68
68
|
return new WidgetConfig(widgetClass, widgetParams);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
let currentUpdateQueue: Map<Widget, PromiseWithResolvers<void>>|null = null;
|
|
72
|
+
const currentlyProcessed = new Set<Widget>();
|
|
73
|
+
let nextUpdateQueue = new Map<Widget, PromiseWithResolvers<void>>();
|
|
74
|
+
let pendingAnimationFrame: number|null = null;
|
|
75
|
+
|
|
76
|
+
function enqueueIntoNextUpdateQueue(widget: Widget): Promise<void> {
|
|
77
|
+
const scheduledUpdate = nextUpdateQueue.get(widget) ?? Promise.withResolvers<void>();
|
|
78
|
+
nextUpdateQueue.delete(widget);
|
|
79
|
+
nextUpdateQueue.set(widget, scheduledUpdate);
|
|
80
|
+
if (pendingAnimationFrame === null) {
|
|
81
|
+
pendingAnimationFrame = requestAnimationFrame(runNextUpdate);
|
|
82
|
+
}
|
|
83
|
+
return scheduledUpdate.promise;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function enqueueWidgetUpdate(widget: Widget): Promise<void> {
|
|
87
|
+
if (currentUpdateQueue) {
|
|
88
|
+
if (currentlyProcessed.has(widget)) {
|
|
89
|
+
return enqueueIntoNextUpdateQueue(widget);
|
|
90
|
+
}
|
|
91
|
+
const scheduledUpdate = currentUpdateQueue.get(widget) ?? Promise.withResolvers<void>();
|
|
92
|
+
currentUpdateQueue.delete(widget);
|
|
93
|
+
currentUpdateQueue.set(widget, scheduledUpdate);
|
|
94
|
+
return scheduledUpdate.promise;
|
|
95
|
+
}
|
|
96
|
+
return enqueueIntoNextUpdateQueue(widget);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function cancelUpdate(widget: Widget): void {
|
|
100
|
+
if (currentUpdateQueue) {
|
|
101
|
+
const scheduledUpdate = currentUpdateQueue.get(widget);
|
|
102
|
+
if (scheduledUpdate) {
|
|
103
|
+
scheduledUpdate.resolve();
|
|
104
|
+
currentUpdateQueue.delete(widget);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const scheduledUpdate = nextUpdateQueue.get(widget);
|
|
108
|
+
if (scheduledUpdate) {
|
|
109
|
+
scheduledUpdate.resolve();
|
|
110
|
+
nextUpdateQueue.delete(widget);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function runNextUpdate(): void {
|
|
115
|
+
pendingAnimationFrame = null;
|
|
116
|
+
currentUpdateQueue = nextUpdateQueue;
|
|
117
|
+
nextUpdateQueue = new Map();
|
|
118
|
+
for (const [widget, {resolve}] of currentUpdateQueue) {
|
|
119
|
+
currentlyProcessed.add(widget);
|
|
120
|
+
void (async () => {
|
|
121
|
+
await widget.performUpdate();
|
|
122
|
+
resolve();
|
|
123
|
+
})();
|
|
124
|
+
}
|
|
125
|
+
currentUpdateQueue = null;
|
|
126
|
+
currentlyProcessed.clear();
|
|
127
|
+
}
|
|
128
|
+
|
|
71
129
|
export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
|
|
72
130
|
#widgetClass?: WidgetFactory<WidgetT>;
|
|
73
131
|
#widgetParams?: Partial<WidgetT>;
|
|
@@ -218,8 +276,7 @@ function decrementWidgetCounter(parentElement: Element, childElement: Element):
|
|
|
218
276
|
// The resolved `updateComplete` promise, which is used as a marker for the
|
|
219
277
|
// Widget's `#updateComplete` private property to indicate that there's no
|
|
220
278
|
// pending update.
|
|
221
|
-
const UPDATE_COMPLETE = Promise.resolve(
|
|
222
|
-
const UPDATE_COMPLETE_RESOLVE = (_result: boolean): void => {};
|
|
279
|
+
const UPDATE_COMPLETE = Promise.resolve();
|
|
223
280
|
|
|
224
281
|
/**
|
|
225
282
|
* Additional options passed to the `Widget` constructor to configure the
|
|
@@ -277,8 +334,6 @@ export class Widget {
|
|
|
277
334
|
#invalidationsRequested?: boolean;
|
|
278
335
|
#externallyManaged?: boolean;
|
|
279
336
|
#updateComplete = UPDATE_COMPLETE;
|
|
280
|
-
#updateCompleteResolve = UPDATE_COMPLETE_RESOLVE;
|
|
281
|
-
#updateRequestID = 0;
|
|
282
337
|
|
|
283
338
|
/**
|
|
284
339
|
* Constructs a new `Widget` with the given `options`.
|
|
@@ -617,14 +672,7 @@ export class Widget {
|
|
|
617
672
|
return;
|
|
618
673
|
}
|
|
619
674
|
|
|
620
|
-
|
|
621
|
-
if (this.#updateRequestID !== 0) {
|
|
622
|
-
cancelAnimationFrame(this.#updateRequestID);
|
|
623
|
-
this.#updateCompleteResolve(true);
|
|
624
|
-
this.#updateCompleteResolve = UPDATE_COMPLETE_RESOLVE;
|
|
625
|
-
this.#updateComplete = UPDATE_COMPLETE;
|
|
626
|
-
this.#updateRequestID = 0;
|
|
627
|
-
}
|
|
675
|
+
cancelUpdate(this);
|
|
628
676
|
|
|
629
677
|
// hideOnDetach means that we should never remove element from dom - content
|
|
630
678
|
// has iframes and detaching it will hurt.
|
|
@@ -876,21 +924,6 @@ export class Widget {
|
|
|
876
924
|
performUpdate(): Promise<void>|void {
|
|
877
925
|
}
|
|
878
926
|
|
|
879
|
-
async #performUpdateCallback(): Promise<boolean> {
|
|
880
|
-
// Mark this update cycle as complete by assigning
|
|
881
|
-
// the marker sentinel.
|
|
882
|
-
this.#updateComplete = UPDATE_COMPLETE;
|
|
883
|
-
this.#updateCompleteResolve = UPDATE_COMPLETE_RESOLVE;
|
|
884
|
-
this.#updateRequestID = 0;
|
|
885
|
-
|
|
886
|
-
// Run the actual update logic.
|
|
887
|
-
await this.performUpdate();
|
|
888
|
-
|
|
889
|
-
// Resolve the `updateComplete` with `true` if no
|
|
890
|
-
// new update was triggered during this cycle.
|
|
891
|
-
return this.#updateComplete === UPDATE_COMPLETE;
|
|
892
|
-
}
|
|
893
|
-
|
|
894
927
|
/**
|
|
895
928
|
* Schedules an asynchronous update for this widget.
|
|
896
929
|
*
|
|
@@ -898,12 +931,7 @@ export class Widget {
|
|
|
898
931
|
* frame.
|
|
899
932
|
*/
|
|
900
933
|
requestUpdate(): void {
|
|
901
|
-
|
|
902
|
-
this.#updateComplete = new Promise((resolve, reject) => {
|
|
903
|
-
this.#updateCompleteResolve = resolve;
|
|
904
|
-
this.#updateRequestID = requestAnimationFrame(() => this.#performUpdateCallback().then(resolve, reject));
|
|
905
|
-
});
|
|
906
|
-
}
|
|
934
|
+
this.#updateComplete = enqueueWidgetUpdate(this);
|
|
907
935
|
}
|
|
908
936
|
|
|
909
937
|
/**
|
|
@@ -931,7 +959,7 @@ export class Widget {
|
|
|
931
959
|
* updating, the value is `true` if there are no more pending updates,
|
|
932
960
|
* and `false` if the update cycle triggered another update.
|
|
933
961
|
*/
|
|
934
|
-
get updateComplete(): Promise<
|
|
962
|
+
get updateComplete(): Promise<void> {
|
|
935
963
|
return this.#updateComplete;
|
|
936
964
|
}
|
|
937
965
|
}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Host from '../../core/host/host.js';
|
|
6
6
|
import * as Platform from '../../core/platform/platform.js';
|
|
7
|
-
import {html} from '../lit/lit.js';
|
|
8
7
|
import * as VisualLogging from '../visual_logging/visual_logging.js';
|
|
9
8
|
|
|
10
9
|
import * as ARIAUtils from './ARIAUtils.js';
|
|
@@ -155,5 +154,3 @@ export class ContextMenuProvider implements Provider<Node> {
|
|
|
155
154
|
}
|
|
156
155
|
|
|
157
156
|
customElements.define('x-link', XLink);
|
|
158
|
-
|
|
159
|
-
export const sample = html`<p>Hello, <x-link>world!</x-link></p>`;
|
|
@@ -372,6 +372,15 @@ class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate {
|
|
|
372
372
|
this.#updateColumns();
|
|
373
373
|
}
|
|
374
374
|
this.#updateCreationNode();
|
|
375
|
+
|
|
376
|
+
const hadAddedNodes = mutationList.some(m => m.addedNodes.length > 0);
|
|
377
|
+
// If we got an update, and the data grid is sorted, we need to update the
|
|
378
|
+
// columns to maintain the sort order as the data within has changed.
|
|
379
|
+
// However, if we have nodes added, that will trigger a sort anyway so we
|
|
380
|
+
// don't need to re-sort again.
|
|
381
|
+
if (this.#dataGrid.sortColumnId() !== null && !hadAddedNodes) {
|
|
382
|
+
this.#dataGrid.dispatchEventToListeners(DataGridEvents.SORTING_CHANGED);
|
|
383
|
+
}
|
|
375
384
|
}
|
|
376
385
|
|
|
377
386
|
#editCallback(
|