chrome-devtools-frontend 1.0.1662289 → 1.0.1662965
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/devtools-unicode-escaping/SKILL.md +64 -0
- package/.agents/skills/migrate-chromium-test/SKILL.md +29 -4
- package/front_end/core/common/SettingRegistration.ts +0 -5
- package/front_end/core/common/Settings.ts +69 -3
- package/front_end/core/platform/StringUtilities.ts +38 -6
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -10
- package/front_end/core/sdk/StorageBucketsModel.ts +0 -10
- package/front_end/core/sdk/sdk-meta.ts +0 -1
- package/front_end/entrypoints/inspector_main/OutermostTargetSelector.ts +0 -13
- package/front_end/entrypoints/inspector_main/RenderingOptions.ts +8 -3
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +3 -3
- package/front_end/entrypoints/main/MainImpl.ts +7 -2
- package/front_end/foundation/Universe.ts +16 -0
- package/front_end/generated/InspectorBackendCommands.ts +2 -14
- package/front_end/generated/protocol-mapping.d.ts +0 -53
- package/front_end/generated/protocol-proxy-api.d.ts +0 -46
- package/front_end/generated/protocol.ts +0 -148
- package/front_end/models/ai_assistance/AiAgent2.ts +3 -3
- package/front_end/models/ai_assistance/AiConversation.ts +21 -10
- package/front_end/models/ai_assistance/AiHistoryStorage.ts +21 -10
- package/front_end/models/ai_assistance/ChangeManager.ts +2 -2
- package/front_end/models/ai_assistance/ExtensionScope.ts +6 -2
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/AiAgent.ts +8 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
- package/front_end/models/badges/UserBadges.ts +31 -17
- package/front_end/models/bindings/NetworkProject.ts +16 -4
- package/front_end/models/emulation/DeviceModeModel.ts +67 -5
- package/front_end/models/extensions/RecorderPluginManager.ts +10 -6
- package/front_end/models/har/Log.snapshot.txt +193 -0
- package/front_end/models/har/Log.ts +3 -2
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +7 -5
- package/front_end/models/source_map_scopes/NamesResolver.ts +36 -30
- package/front_end/models/stack_trace/StackTrace.ts +17 -0
- package/front_end/panels/application/IndexedDBModel.ts +0 -10
- package/front_end/panels/application/IndexedDBViews.ts +240 -164
- package/front_end/panels/application/SharedStorageModel.ts +0 -10
- package/front_end/panels/application/components/AdsView.ts +23 -0
- package/front_end/panels/application/components/SharedStorageAccessGrid.ts +1 -1
- package/front_end/panels/application/components/adsView.css +21 -1
- package/front_end/panels/application/indexedDBViews.css +1 -1
- package/front_end/panels/network/NetworkDataGridNode.ts +43 -1
- package/front_end/panels/network/RequestInitiatorView.ts +24 -2
- package/front_end/panels/network/networkLogView.css +5 -0
- package/front_end/panels/network/requestInitiatorViewTree.css +5 -0
- package/front_end/panels/profiler/HeapProfileView.ts +198 -79
- package/front_end/panels/recorder/README.md +1 -2
- package/front_end/panels/recorder/RecorderPanel.ts +1749 -17
- package/front_end/panels/recorder/recorder.ts +0 -2
- package/front_end/panels/settings/AISettingsTab.ts +13 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/spinners/Spinner.ts +29 -32
- package/front_end/ui/components/spinners/spinner.css +32 -84
- package/front_end/ui/legacy/Treeoutline.ts +14 -6
- package/front_end/ui/legacy/UIUtils.ts +25 -10
- package/front_end/ui/legacy/Widget.ts +17 -10
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +36 -7
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +63 -68
- package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/objectValue.css +2 -1
- package/front_end/ui/legacy/inspectorCommon.css +4 -4
- package/front_end/ui/lit/lit.ts +1 -0
- package/front_end/ui/lit/render.ts +44 -10
- package/front_end/ui/lit/strip-whitespace.ts +23 -2
- package/package.json +1 -1
- package/front_end/panels/recorder/RecorderController.ts +0 -1759
- /package/front_end/panels/recorder/{recorderController.css → recorderPanel.css} +0 -0
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import * as ControlButton from './ControlButton.js';
|
|
6
6
|
import * as CreateRecordingView from './CreateRecordingView.js';
|
|
7
|
-
import * as RecorderController from './RecorderController.js';
|
|
8
7
|
import * as RecorderEvents from './RecorderEvents.js';
|
|
9
8
|
import * as RecorderPanel from './RecorderPanel.js';
|
|
10
9
|
import * as RecordingListView from './RecordingListView.js';
|
|
@@ -18,7 +17,6 @@ import * as TimelineSection from './TimelineSection.js';
|
|
|
18
17
|
export {
|
|
19
18
|
ControlButton,
|
|
20
19
|
CreateRecordingView,
|
|
21
|
-
RecorderController,
|
|
22
20
|
RecorderEvents,
|
|
23
21
|
RecorderPanel,
|
|
24
22
|
RecordingListView,
|
|
@@ -75,6 +75,16 @@ const UIStrings = {
|
|
|
75
75
|
* @description Label for a button to collapse an accordion.
|
|
76
76
|
*/
|
|
77
77
|
showLess: 'Show less',
|
|
78
|
+
/**
|
|
79
|
+
* @description Accessible label for a button to expand an accordion for a specific setting.
|
|
80
|
+
* @example {Code suggestions} PH1
|
|
81
|
+
*/
|
|
82
|
+
showMoreOfSetting: 'Show more of {PH1}',
|
|
83
|
+
/**
|
|
84
|
+
* @description Accessible label for a button to collapse an accordion for a specific setting.
|
|
85
|
+
* @example {Code suggestions} PH1
|
|
86
|
+
*/
|
|
87
|
+
showLessOfSetting: 'Show less of {PH1}',
|
|
78
88
|
/**
|
|
79
89
|
* @description Header for a list of feature attributes. 'When on, you’ll be able to …'.
|
|
80
90
|
*/
|
|
@@ -358,6 +368,9 @@ export const AI_SETTINGS_TAB_DEFAULT_VIEW: View = (input, _output, target): void
|
|
|
358
368
|
<devtools-button
|
|
359
369
|
.data=${{
|
|
360
370
|
title: settingData.settingExpandState.isSettingExpanded ? i18nString(UIStrings.showLess) : i18nString(UIStrings.showMore),
|
|
371
|
+
accessibleLabel: settingData.settingExpandState.isSettingExpanded ?
|
|
372
|
+
i18nString(UIStrings.showLessOfSetting, {PH1: settingData.settingName}) :
|
|
373
|
+
i18nString(UIStrings.showMoreOfSetting, {PH1: settingData.settingName}),
|
|
361
374
|
size: Buttons.Button.Size.SMALL,
|
|
362
375
|
iconName: settingData.settingExpandState.isSettingExpanded ? 'chevron-up' : 'chevron-down',
|
|
363
376
|
variant: Buttons.Button.Variant.ICON,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: Internal
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: 7eaaa785deda657a652efc66266b8cc2957167f9
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
/* eslint-disable @devtools/no-lit-render-outside-of-view, @devtools/enforce-custom-element-definitions-location */
|
|
5
5
|
|
|
6
|
-
import {html, render} from '../../lit/lit.js';
|
|
6
|
+
import {Directives, html, render} from '../../lit/lit.js';
|
|
7
7
|
|
|
8
8
|
import spinnerStyles from './spinner.css.js';
|
|
9
9
|
|
|
10
|
+
const {classMap} = Directives;
|
|
11
|
+
|
|
10
12
|
export interface SpinnerProperties {
|
|
11
13
|
active: boolean;
|
|
12
14
|
}
|
|
@@ -48,39 +50,34 @@ export class Spinner extends HTMLElement {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
#render(): void {
|
|
51
|
-
// The radius
|
|
52
|
-
//
|
|
53
|
-
// https://github.com/material-components/material-components-web/tree/master/packages/mdc-circular-progress.
|
|
54
|
-
// Changing the value of the radius will cause errors in animation.
|
|
53
|
+
// The radius is set to 40 to allow for stroke width padding, and
|
|
54
|
+
// pathLength=100 is used for scalable, unitless animation length.
|
|
55
55
|
// clang-format off
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
</
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
56
|
+
const spinnerClasses = {
|
|
57
|
+
indeterminate: this.active,
|
|
58
|
+
spinner: true,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
render(
|
|
62
|
+
html`
|
|
63
|
+
<style>
|
|
64
|
+
${spinnerStyles}
|
|
65
|
+
</style>
|
|
66
|
+
<svg
|
|
67
|
+
class=${classMap(spinnerClasses)}
|
|
68
|
+
viewBox="0 0 100 100"
|
|
69
|
+
>
|
|
70
|
+
<circle
|
|
71
|
+
cx="50"
|
|
72
|
+
cy="50"
|
|
73
|
+
r="44"
|
|
74
|
+
pathLength="100"
|
|
75
|
+
></circle>
|
|
75
76
|
</svg>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
${spinnerStyles}
|
|
81
|
-
</style>
|
|
82
|
-
${content}
|
|
83
|
-
`, this.#shadow, {host: this});
|
|
77
|
+
`,
|
|
78
|
+
this.#shadow,
|
|
79
|
+
{host: this},
|
|
80
|
+
);
|
|
84
81
|
// clang-format on
|
|
85
82
|
}
|
|
86
83
|
}
|
|
@@ -18,87 +18,43 @@
|
|
|
18
18
|
animation: spinner-container-animation 1.5s linear infinite;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
.
|
|
21
|
+
.spinner {
|
|
22
|
+
height: 100%;
|
|
23
|
+
width: 100%;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.spinner.indeterminate {
|
|
22
27
|
/*
|
|
23
28
|
* The value for animation duration has been obtained by plugging in values defined
|
|
24
29
|
* in packages/mdc-circular-progress/_circular-progress-theme.scss to
|
|
25
30
|
* functions defined in packages/mdc-circular-progress/_circular-progress.scss.
|
|
26
31
|
* https://github.com/material-components/material-components-web
|
|
27
32
|
*/
|
|
28
|
-
animation: indeterminate-spinner-animation 5332ms cubic-bezier(0.4, 0, 0.2, 1)
|
|
29
|
-
|
|
30
|
-
width: 100%;
|
|
31
|
-
|
|
32
|
-
.left-circle {
|
|
33
|
-
height: 100%;
|
|
34
|
-
width: 50%;
|
|
35
|
-
display: inline-block;
|
|
36
|
-
position: relative;
|
|
37
|
-
overflow: hidden;
|
|
38
|
-
|
|
39
|
-
& > svg {
|
|
40
|
-
position: absolute;
|
|
41
|
-
width: 200%;
|
|
42
|
-
/*
|
|
43
|
-
* The value for animation duration has been obtained from values defined
|
|
44
|
-
* in packages/mdc-circular-progress/_circular-progress-theme.scss
|
|
45
|
-
* https://github.com/material-components/material-components-web
|
|
46
|
-
*/
|
|
47
|
-
animation: indeterminate-left-circle-spinner-animation 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.center-circle {
|
|
52
|
-
height: 100%;
|
|
53
|
-
width: 5%;
|
|
54
|
-
display: inline-block;
|
|
55
|
-
position: absolute;
|
|
56
|
-
overflow: hidden;
|
|
57
|
-
top: 0;
|
|
58
|
-
left: 47.5%;
|
|
59
|
-
box-sizing: border-box;
|
|
60
|
-
|
|
61
|
-
& > svg {
|
|
62
|
-
position: absolute;
|
|
63
|
-
width: 2000%;
|
|
64
|
-
left: -900%;
|
|
65
|
-
transform: rotate(180deg);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
33
|
+
animation: indeterminate-spinner-animation 5332ms cubic-bezier(0.4, 0, 0.2, 1)
|
|
34
|
+
infinite both;
|
|
68
35
|
|
|
69
|
-
.right-circle {
|
|
70
|
-
height: 100%;
|
|
71
|
-
width: 50%;
|
|
72
|
-
display: inline-block;
|
|
73
|
-
position: relative;
|
|
74
|
-
overflow: hidden;
|
|
75
|
-
|
|
76
|
-
& > svg {
|
|
77
|
-
position: absolute;
|
|
78
|
-
width: 200%;
|
|
79
|
-
left: -100%;
|
|
80
|
-
/*
|
|
81
|
-
* The value for animation duration has been obtained from values defined
|
|
82
|
-
* in packages/mdc-circular-progress/_circular-progress-theme.scss
|
|
83
|
-
* https://github.com/material-components/material-components-web
|
|
84
|
-
*/
|
|
85
|
-
animation: indeterminate-right-circle-spinner-animation 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
36
|
}
|
|
89
37
|
|
|
90
|
-
.
|
|
38
|
+
.spinner circle {
|
|
91
39
|
stroke: var(--sys-color-state-disabled);
|
|
92
40
|
stroke-width: var(--sys-size-6);
|
|
93
41
|
fill: transparent;
|
|
42
|
+
transform-origin: 50% 50%;
|
|
43
|
+
transform: rotate(-90deg);
|
|
94
44
|
}
|
|
95
45
|
|
|
96
|
-
|
|
46
|
+
|
|
47
|
+
.spinner.indeterminate circle {
|
|
97
48
|
stroke: var(--sys-color-primary);
|
|
98
|
-
stroke-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
49
|
+
stroke-dasharray: 100, 100;
|
|
50
|
+
stroke-dashoffset: 0;
|
|
51
|
+
/*
|
|
52
|
+
* The value for animation duration has been obtained from values defined
|
|
53
|
+
* in packages/mdc-circular-progress/_circular-progress-theme.scss
|
|
54
|
+
* https://github.com/material-components/material-components-web
|
|
55
|
+
*/
|
|
56
|
+
animation: indeterminate-spinner-circle-animation 1333ms
|
|
57
|
+
cubic-bezier(0.4, 0, 0.2, 1) infinite both;
|
|
102
58
|
}
|
|
103
59
|
|
|
104
60
|
@keyframes spinner-container-animation {
|
|
@@ -141,30 +97,22 @@
|
|
|
141
97
|
}
|
|
142
98
|
}
|
|
143
99
|
|
|
144
|
-
@keyframes indeterminate-
|
|
145
|
-
0% {
|
|
146
|
-
transform: rotate(265deg);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
50% {
|
|
150
|
-
transform: rotate(130deg);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
100% {
|
|
154
|
-
transform: rotate(265deg);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
@keyframes indeterminate-right-circle-spinner-animation {
|
|
100
|
+
@keyframes indeterminate-spinner-circle-animation {
|
|
159
101
|
0% {
|
|
160
|
-
|
|
102
|
+
stroke-dasharray: 5, 100;
|
|
103
|
+
stroke-dashoffset: 0;
|
|
104
|
+
transform: rotate(-90deg);
|
|
161
105
|
}
|
|
162
106
|
|
|
163
107
|
50% {
|
|
164
|
-
|
|
108
|
+
stroke-dasharray: 75, 100;
|
|
109
|
+
stroke-dashoffset: 0;
|
|
110
|
+
transform: rotate(-225deg);
|
|
165
111
|
}
|
|
166
112
|
|
|
167
113
|
100% {
|
|
168
|
-
|
|
114
|
+
stroke-dasharray: 5, 100;
|
|
115
|
+
stroke-dashoffset: 0;
|
|
116
|
+
transform: rotate(-90deg);
|
|
169
117
|
}
|
|
170
118
|
}
|
|
@@ -1864,7 +1864,7 @@ export class TreeViewElement extends HTMLElementWithLightDOMTemplate {
|
|
|
1864
1864
|
}
|
|
1865
1865
|
}
|
|
1866
1866
|
|
|
1867
|
-
protected override addNodes(nodes: NodeList|Node[]
|
|
1867
|
+
protected override addNodes(nodes: NodeList|Node[]): void {
|
|
1868
1868
|
for (const node of getTreeNodes(nodes)) {
|
|
1869
1869
|
if (TreeViewTreeElement.get(node)) {
|
|
1870
1870
|
continue; // Not sure this can happen
|
|
@@ -1876,10 +1876,18 @@ export class TreeViewElement extends HTMLElementWithLightDOMTemplate {
|
|
|
1876
1876
|
if (parent.treeElement.childCount() === 0) {
|
|
1877
1877
|
parent.treeElement.childrenListElement.classList.add(...parent.classes.values());
|
|
1878
1878
|
}
|
|
1879
|
-
|
|
1880
|
-
|
|
1879
|
+
let nextElement: TreeElement|null = null;
|
|
1880
|
+
for (let e: Element|null = node.nextElementSibling; e; e = e.nextElementSibling) {
|
|
1881
|
+
const nextTreeEl = TreeViewTreeElement.get(e);
|
|
1882
|
+
if (nextTreeEl) {
|
|
1883
|
+
nextElement = nextTreeEl;
|
|
1884
|
+
break;
|
|
1885
|
+
}
|
|
1886
|
+
if (e instanceof TreeElementWrapper && e.treeElement && e.treeElement.parent === parent.treeElement) {
|
|
1887
|
+
nextElement = e.treeElement;
|
|
1888
|
+
break;
|
|
1889
|
+
}
|
|
1881
1890
|
}
|
|
1882
|
-
const nextElement = nextSibling ? TreeViewTreeElement.get(nextSibling) : null;
|
|
1883
1891
|
const index = nextElement ? parent.treeElement.indexOfChild(nextElement) : parent.treeElement.children().length;
|
|
1884
1892
|
let treeElement;
|
|
1885
1893
|
if (node instanceof HTMLLIElement) {
|
|
@@ -1906,12 +1914,12 @@ export class TreeViewElement extends HTMLElementWithLightDOMTemplate {
|
|
|
1906
1914
|
}
|
|
1907
1915
|
}
|
|
1908
1916
|
}
|
|
1909
|
-
for (const element of getStyleElements(nodes)) {
|
|
1917
|
+
for (const element of new Set(getStyleElements(nodes))) {
|
|
1910
1918
|
this.#treeOutline.shadowRoot.appendChild(element.cloneNode(true));
|
|
1911
1919
|
}
|
|
1912
1920
|
}
|
|
1913
1921
|
|
|
1914
|
-
protected override removeNodes(nodes: NodeList): void {
|
|
1922
|
+
protected override removeNodes(nodes: NodeList|Node[]): void {
|
|
1915
1923
|
for (const node of getTreeNodes(nodes)) {
|
|
1916
1924
|
if (node instanceof HTMLLIElement) {
|
|
1917
1925
|
TreeViewTreeElement.get(node)?.remove();
|
|
@@ -2124,10 +2124,6 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2124
2124
|
value['_$litType$'] === 1);
|
|
2125
2125
|
}
|
|
2126
2126
|
|
|
2127
|
-
function isLitDirective(value: unknown): value is {values: unknown[]} {
|
|
2128
|
-
return Boolean(typeof value === 'object' && value && '_$litDirective$' in value && 'values' in value);
|
|
2129
|
-
}
|
|
2130
|
-
|
|
2131
2127
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2132
2128
|
function isCallable(value: unknown): value is(...args: any[]) => any {
|
|
2133
2129
|
// Native class constructors cannot be invoked without 'new', and we shouldn't attempt to wrap them.
|
|
@@ -2148,7 +2144,7 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2148
2144
|
HTMLElementWithLightDOMTemplate.patchLitTemplate(value);
|
|
2149
2145
|
return value;
|
|
2150
2146
|
}
|
|
2151
|
-
if (isLitDirective(value)) {
|
|
2147
|
+
if (Lit.isLitDirective(value)) {
|
|
2152
2148
|
for (let i = 0; i < value.values.length; i++) {
|
|
2153
2149
|
const subvalue = value.values[i];
|
|
2154
2150
|
if (isCallable(subvalue)) {
|
|
@@ -2186,9 +2182,28 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2186
2182
|
|
|
2187
2183
|
#onChange(mutationList: MutationRecord[]): void {
|
|
2188
2184
|
this.onChange(mutationList);
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2185
|
+
const addedNodes = new Set<Node>();
|
|
2186
|
+
const removedNodes = new Set<Node>();
|
|
2187
|
+
for (let i = 0; i < mutationList.length; i++) {
|
|
2188
|
+
const mutation = mutationList[i];
|
|
2189
|
+
for (const node of mutation.addedNodes) {
|
|
2190
|
+
addedNodes.add(node);
|
|
2191
|
+
}
|
|
2192
|
+
for (const node of mutation.removedNodes) {
|
|
2193
|
+
removedNodes.add(node);
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
if (removedNodes.size > 0) {
|
|
2197
|
+
this.removeNodes([...removedNodes]);
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
const finalAddedNodes = [...addedNodes].filter(n => this.templateRoot.contains(n));
|
|
2201
|
+
if (finalAddedNodes.length > 0) {
|
|
2202
|
+
this.addNodes(finalAddedNodes);
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
for (let i = 0; i < mutationList.length; i++) {
|
|
2206
|
+
const mutation = mutationList[i];
|
|
2192
2207
|
this.updateNode(mutation.target, mutation.attributeName);
|
|
2193
2208
|
}
|
|
2194
2209
|
}
|
|
@@ -2199,10 +2214,10 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
|
|
|
2199
2214
|
protected updateNode(_node: Node, _attributeName: string|null): void {
|
|
2200
2215
|
}
|
|
2201
2216
|
|
|
2202
|
-
protected addNodes(_nodes: NodeList|Node[]
|
|
2217
|
+
protected addNodes(_nodes: NodeList|Node[]): void {
|
|
2203
2218
|
}
|
|
2204
2219
|
|
|
2205
|
-
protected removeNodes(_nodes: NodeList): void {
|
|
2220
|
+
protected removeNodes(_nodes: NodeList|Node[]): void {
|
|
2206
2221
|
}
|
|
2207
2222
|
|
|
2208
2223
|
static findCorrespondingElement(
|
|
@@ -76,16 +76,20 @@ export function widgetConfig<F extends WidgetFactory<AnyWidget>, ParamKeys exten
|
|
|
76
76
|
let currentUpdateQueue: Map<AnyWidget, PromiseWithResolvers<void>>|null = null;
|
|
77
77
|
const currentlyProcessed = new Set<AnyWidget>();
|
|
78
78
|
let nextUpdateQueue = new Map<AnyWidget, PromiseWithResolvers<void>>();
|
|
79
|
-
|
|
79
|
+
const pendingAnimationFrames = new WeakMap<Window, number>();
|
|
80
80
|
let overallUpdatePromise: PromiseWithResolvers<void>|null = null;
|
|
81
81
|
|
|
82
82
|
function enqueueIntoNextUpdateQueue(widget: AnyWidget): Promise<void> {
|
|
83
83
|
const scheduledUpdate = nextUpdateQueue.get(widget) ?? Promise.withResolvers<void>();
|
|
84
84
|
nextUpdateQueue.delete(widget);
|
|
85
85
|
nextUpdateQueue.set(widget, scheduledUpdate);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
const widgetWindow = widget.contentElement.window() || window;
|
|
87
|
+
if (!pendingAnimationFrames.has(widgetWindow)) {
|
|
88
|
+
const frameId = widgetWindow.requestAnimationFrame(() => {
|
|
89
|
+
pendingAnimationFrames.delete(widgetWindow);
|
|
90
|
+
runNextUpdate();
|
|
91
|
+
});
|
|
92
|
+
pendingAnimationFrames.set(widgetWindow, frameId);
|
|
89
93
|
}
|
|
90
94
|
return scheduledUpdate.promise;
|
|
91
95
|
}
|
|
@@ -121,14 +125,13 @@ function cancelUpdate(widget: AnyWidget): void {
|
|
|
121
125
|
|
|
122
126
|
function resolveOverallUpdatePromise(): void {
|
|
123
127
|
if (currentlyProcessed.size === 0 && (!currentUpdateQueue || currentUpdateQueue.size === 0) &&
|
|
124
|
-
nextUpdateQueue.size === 0 &&
|
|
128
|
+
nextUpdateQueue.size === 0 && overallUpdatePromise) {
|
|
125
129
|
overallUpdatePromise.resolve();
|
|
126
130
|
overallUpdatePromise = null;
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
133
|
|
|
130
134
|
function runNextUpdate(): void {
|
|
131
|
-
pendingAnimationFrame = null;
|
|
132
135
|
if (!currentUpdateQueue) {
|
|
133
136
|
currentUpdateQueue = nextUpdateQueue;
|
|
134
137
|
nextUpdateQueue = new Map();
|
|
@@ -155,9 +158,13 @@ function runNextUpdate(): void {
|
|
|
155
158
|
const nextUpdate = nextUpdateQueue.get(widget);
|
|
156
159
|
if (nextUpdate) {
|
|
157
160
|
void nextUpdate.promise.then(resolve);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
+
const widgetWindow = widget.contentElement.window() || window;
|
|
162
|
+
if (!pendingAnimationFrames.has(widgetWindow)) {
|
|
163
|
+
const frameId = widgetWindow.requestAnimationFrame(() => {
|
|
164
|
+
pendingAnimationFrames.delete(widgetWindow);
|
|
165
|
+
runNextUpdate();
|
|
166
|
+
});
|
|
167
|
+
pendingAnimationFrames.set(widgetWindow, frameId);
|
|
161
168
|
}
|
|
162
169
|
} else {
|
|
163
170
|
resolve();
|
|
@@ -578,7 +585,7 @@ export class Widget<ContentTypeT extends HTMLElement|DocumentFragment = HTMLElem
|
|
|
578
585
|
}
|
|
579
586
|
|
|
580
587
|
static get allUpdatesComplete(): Promise<void> {
|
|
581
|
-
if (
|
|
588
|
+
if (nextUpdateQueue.size === 0 && !currentUpdateQueue && currentlyProcessed.size === 0) {
|
|
582
589
|
return Promise.resolve();
|
|
583
590
|
}
|
|
584
591
|
if (!overallUpdatePromise) {
|
|
@@ -71,6 +71,7 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
71
71
|
#hideableColumns = new Set<string>();
|
|
72
72
|
#hiddenColumns = new Set<string>();
|
|
73
73
|
#usedCreationNode: DataGridElementNode|null = null;
|
|
74
|
+
#sortingChangedScheduled = false;
|
|
74
75
|
|
|
75
76
|
constructor() {
|
|
76
77
|
super();
|
|
@@ -247,6 +248,7 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
247
248
|
const sort = column.getAttribute('sort') === 'descending' ? Order.Descending :
|
|
248
249
|
column.getAttribute('sort') === 'ascending' ? Order.Ascending :
|
|
249
250
|
undefined;
|
|
251
|
+
const disclosure = hasBooleanAttribute(column, 'disclosure');
|
|
250
252
|
const columnDescriptor = {
|
|
251
253
|
id,
|
|
252
254
|
title: title as Platform.UIString.LocalizedString,
|
|
@@ -259,6 +261,7 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
259
261
|
weight,
|
|
260
262
|
editable,
|
|
261
263
|
dataType,
|
|
264
|
+
disclosure,
|
|
262
265
|
};
|
|
263
266
|
this.#dataGrid.addColumn(columnDescriptor);
|
|
264
267
|
this.#columns.push(columnDescriptor);
|
|
@@ -289,7 +292,7 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
289
292
|
return false;
|
|
290
293
|
}
|
|
291
294
|
|
|
292
|
-
#getDataRows(nodes: NodeList): HTMLElement[] {
|
|
295
|
+
#getDataRows(nodes: NodeList|Node[]): HTMLElement[] {
|
|
293
296
|
return [...nodes]
|
|
294
297
|
.flatMap(node => {
|
|
295
298
|
if (node instanceof HTMLTableRowElement) {
|
|
@@ -303,7 +306,7 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
303
306
|
.filter(node => node.querySelector('td') && !hasBooleanAttribute(node, 'placeholder'));
|
|
304
307
|
}
|
|
305
308
|
|
|
306
|
-
#getStyleElements(nodes: NodeList): HTMLElement[] {
|
|
309
|
+
#getStyleElements(nodes: NodeList|Node[]): HTMLElement[] {
|
|
307
310
|
return [...nodes].flatMap(node => {
|
|
308
311
|
if (node instanceof HTMLStyleElement) {
|
|
309
312
|
return [node];
|
|
@@ -325,10 +328,16 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
325
328
|
return null;
|
|
326
329
|
}
|
|
327
330
|
|
|
328
|
-
override addNodes(nodes: NodeList): void {
|
|
331
|
+
override addNodes(nodes: NodeList|Node[]): void {
|
|
329
332
|
for (const element of this.#getDataRows(nodes)) {
|
|
333
|
+
if (getNode(element)) {
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
330
336
|
const parentRow = element.parentElement?.closest('td')?.closest('tr');
|
|
331
337
|
const parentDataGridNode = parentRow ? getNode(parentRow) : undefined;
|
|
338
|
+
if (parentRow && !parentDataGridNode) {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
332
341
|
const parentNode = parentDataGridNode || this.#dataGrid.rootNode();
|
|
333
342
|
const nextNode = this.#findNextExistingNode(element);
|
|
334
343
|
const index = nextNode ? parentNode.children.indexOf(nextNode) : parentNode.children.length;
|
|
@@ -352,14 +361,17 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
352
361
|
if (hasBooleanAttribute(element, 'highlighted')) {
|
|
353
362
|
node.setHighlighted(true);
|
|
354
363
|
}
|
|
364
|
+
if (hasBooleanAttribute(element, 'expanded')) {
|
|
365
|
+
node.expand();
|
|
366
|
+
}
|
|
355
367
|
}
|
|
356
|
-
for (const element of this.#getStyleElements(nodes)) {
|
|
368
|
+
for (const element of new Set(this.#getStyleElements(nodes))) {
|
|
357
369
|
this.#shadowRoot.appendChild(element.cloneNode(true));
|
|
358
370
|
}
|
|
359
|
-
this.#
|
|
371
|
+
this.#scheduleSortingChanged();
|
|
360
372
|
}
|
|
361
373
|
|
|
362
|
-
override removeNodes(nodes: NodeList): void {
|
|
374
|
+
override removeNodes(nodes: NodeList|Node[]): void {
|
|
363
375
|
for (const element of this.#getDataRows(nodes)) {
|
|
364
376
|
const node = getNode(element);
|
|
365
377
|
if (node) {
|
|
@@ -387,6 +399,12 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
387
399
|
dataGridNode.setInactive(hasBooleanAttribute(dataRow, 'inactive'));
|
|
388
400
|
} else if (attributeName === 'highlighted') {
|
|
389
401
|
dataGridNode.setHighlighted(hasBooleanAttribute(dataRow, 'highlighted'));
|
|
402
|
+
} else if (attributeName === 'expanded') {
|
|
403
|
+
if (hasBooleanAttribute(dataRow, 'expanded')) {
|
|
404
|
+
dataGridNode.expand();
|
|
405
|
+
} else {
|
|
406
|
+
dataGridNode.collapse();
|
|
407
|
+
}
|
|
390
408
|
} else {
|
|
391
409
|
this.#updateHasChildren(dataGridNode, dataRow);
|
|
392
410
|
dataGridNode.refresh();
|
|
@@ -394,6 +412,17 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
394
412
|
}
|
|
395
413
|
}
|
|
396
414
|
|
|
415
|
+
#scheduleSortingChanged(): void {
|
|
416
|
+
if (this.#sortingChangedScheduled) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
this.#sortingChangedScheduled = true;
|
|
420
|
+
queueMicrotask(() => {
|
|
421
|
+
this.#sortingChangedScheduled = false;
|
|
422
|
+
this.#dataGrid.dispatchEventToListeners(DataGridEvents.SORTING_CHANGED);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
397
426
|
deselectRow(): void {
|
|
398
427
|
this.#dataGrid.selectedNode?.deselect();
|
|
399
428
|
}
|
|
@@ -430,7 +459,7 @@ export class DataGridElement extends UI.UIUtils.HTMLElementWithLightDOMTemplate
|
|
|
430
459
|
// However, if we have nodes added, that will trigger a sort anyway so we
|
|
431
460
|
// don't need to re-sort again.
|
|
432
461
|
if (this.#dataGrid.sortColumnId() !== null && !hadAddedNodes) {
|
|
433
|
-
this.#
|
|
462
|
+
this.#scheduleSortingChanged();
|
|
434
463
|
}
|
|
435
464
|
}
|
|
436
465
|
|