chrome-devtools-frontend 1.0.1606789 → 1.0.1608868
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/ui_engineering.md +2 -0
- package/eslint.config.mjs +2 -0
- package/front_end/core/common/VersionController.ts +18 -1
- package/front_end/core/host/UserMetrics.ts +0 -2
- package/front_end/core/platform/node/HostRuntime.ts +1 -1
- package/front_end/core/root/ExperimentNames.ts +0 -2
- package/front_end/core/sdk/AccessibilityModel.ts +13 -1
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -13
- package/front_end/core/sdk/StorageBucketsModel.ts +0 -12
- package/front_end/entrypoints/main/MainImpl.ts +2 -11
- package/front_end/generated/InspectorBackendCommands.ts +3 -33
- package/front_end/generated/SupportedCSSProperties.js +8 -4
- package/front_end/generated/protocol-mapping.d.ts +7 -26
- package/front_end/generated/protocol-proxy-api.d.ts +5 -24
- package/front_end/generated/protocol.ts +2 -296
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +2 -2
- package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -6
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +2 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +46 -21
- package/front_end/{panels/profiler → models/heap_snapshot_model}/ChildrenProvider.ts +3 -4
- package/front_end/{panels/profiler → models/heap_snapshot_model}/HeapSnapshotProxy.ts +19 -36
- package/front_end/models/heap_snapshot_model/heap_snapshot_model.ts +4 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +0 -4
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +53 -10
- package/front_end/panels/accessibility/accessibility.ts +0 -2
- package/front_end/panels/accessibility/accessibilitySidebarView.css +10 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +6 -5
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +36 -17
- package/front_end/panels/ai_assistance/components/chatMessage.css +7 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +39 -11
- package/front_end/panels/application/CrashReportContextView.ts +237 -0
- package/front_end/panels/application/IndexedDBModel.ts +0 -10
- package/front_end/panels/application/InterestGroupStorageModel.ts +0 -11
- package/front_end/panels/application/ReportingApiTreeElement.ts +40 -1
- package/front_end/panels/application/SharedStorageModel.ts +0 -11
- package/front_end/panels/application/WebMCPView.ts +389 -52
- package/front_end/panels/application/application.ts +4 -0
- package/front_end/panels/application/components/CrashReportContextGrid.ts +154 -0
- package/front_end/panels/application/components/components.ts +2 -0
- package/front_end/panels/application/webMCPView.css +107 -10
- package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +12 -2
- package/front_end/panels/elements/AccessibilityTreeView.ts +10 -6
- package/front_end/panels/elements/ElementsPanel.ts +9 -50
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
- package/front_end/panels/elements/elements-meta.ts +1 -0
- package/front_end/panels/elements/elementsPanel.css +4 -14
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +23 -13
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +30 -30
- package/front_end/panels/profiler/HeapSnapshotView.ts +16 -13
- package/front_end/panels/profiler/profiler.ts +0 -4
- package/front_end/panels/snippets/SnippetsQuickOpen.ts +5 -5
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -2
- package/front_end/panels/sources/sources-meta.ts +7 -7
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +1 -3
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +6 -1
- package/front_end/panels/timeline/ThreadAppender.ts +1 -3
- package/front_end/panels/timeline/TimelineController.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +2 -4
- package/front_end/panels/timeline/TimelineTreeView.ts +32 -2
- package/front_end/panels/timeline/components/LiveMetricsView.ts +75 -54
- package/front_end/panels/timeline/components/timelineRangeSummaryView.css +8 -0
- package/front_end/panels/timeline/thirdPartyTreeView.css +0 -1
- package/front_end/panels/timeline/timeline-meta.ts +13 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/TabbedPane.ts +3 -1
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +3 -3
- package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +2 -5
- package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +4 -4
- package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +5 -1
- package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -1
- package/front_end/ui/legacy/components/utils/imagePreview.css +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -3
- package/package.json +1 -1
- package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +0 -653
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Copyright 2026 The Chromium Authors
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import '../../../ui/legacy/components/data_grid/data_grid.js';
|
|
6
|
+
|
|
7
|
+
import * as Host from '../../../core/host/host.js';
|
|
8
|
+
import * as i18n from '../../../core/i18n/i18n.js';
|
|
9
|
+
import type * as TextUtils from '../../../models/text_utils/text_utils.js';
|
|
10
|
+
import * as UI from '../../../ui/legacy/legacy.js';
|
|
11
|
+
import {html, render} from '../../../ui/lit/lit.js';
|
|
12
|
+
|
|
13
|
+
const UIStrings = {
|
|
14
|
+
/**
|
|
15
|
+
* @description Text in Crash Report Context Items View of the Application panel
|
|
16
|
+
*/
|
|
17
|
+
key: 'Key',
|
|
18
|
+
/**
|
|
19
|
+
* @description Text in Crash Report Context Items View of the Application panel
|
|
20
|
+
*/
|
|
21
|
+
value: 'Value',
|
|
22
|
+
/**
|
|
23
|
+
* @description Context menu item to copy the key of a context entry
|
|
24
|
+
*/
|
|
25
|
+
copyKey: 'Copy key',
|
|
26
|
+
/**
|
|
27
|
+
* @description Context menu item to copy the value of a context entry
|
|
28
|
+
*/
|
|
29
|
+
copyValue: 'Copy value',
|
|
30
|
+
} as const;
|
|
31
|
+
const str_ = i18n.i18n.registerUIStrings('panels/application/components/CrashReportContextGrid.ts', UIStrings);
|
|
32
|
+
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
33
|
+
|
|
34
|
+
export interface CrashReportContextGridData {
|
|
35
|
+
entries: Array<{key: string, value: string}>;
|
|
36
|
+
selectedKey?: string;
|
|
37
|
+
filters?: TextUtils.TextUtils.ParsedFilter[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ViewInput {
|
|
41
|
+
entries: Array<{key: string, value: string}>;
|
|
42
|
+
selectedKey?: string;
|
|
43
|
+
onSelect: (key: string) => void;
|
|
44
|
+
onContextMenu: (e: Event, key: string, value: string) => void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const DEFAULT_VIEW = (input: ViewInput, output: undefined, target: HTMLElement|ShadowRoot): void => {
|
|
48
|
+
// clang-format off
|
|
49
|
+
render(
|
|
50
|
+
html`
|
|
51
|
+
<style>
|
|
52
|
+
:host {
|
|
53
|
+
display: block;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
div {
|
|
57
|
+
overflow: auto;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
td {
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
text-overflow: ellipsis;
|
|
64
|
+
}
|
|
65
|
+
</style>
|
|
66
|
+
<style>${UI.inspectorCommonStyles}</style>
|
|
67
|
+
<div>
|
|
68
|
+
<devtools-data-grid striped inline>
|
|
69
|
+
<table>
|
|
70
|
+
<thead>
|
|
71
|
+
<tr>
|
|
72
|
+
<th id="key" weight="50">${i18nString(UIStrings.key)}</th>
|
|
73
|
+
<th id="value" weight="50">${i18nString(UIStrings.value)}</th>
|
|
74
|
+
</tr>
|
|
75
|
+
</thead>
|
|
76
|
+
<tbody>
|
|
77
|
+
${input.entries.map(entry => html`
|
|
78
|
+
<tr class=${input.selectedKey === entry.key ? 'selected' : ''}
|
|
79
|
+
@select=${() => input.onSelect(entry.key)}
|
|
80
|
+
@contextmenu=${(e: Event) => input.onContextMenu(e, entry.key, entry.value)}>
|
|
81
|
+
<td title=${entry.key}>${entry.key}</td>
|
|
82
|
+
<td title=${entry.value}>${entry.value}</td>
|
|
83
|
+
</tr>
|
|
84
|
+
`)}
|
|
85
|
+
</tbody>
|
|
86
|
+
</table>
|
|
87
|
+
</devtools-data-grid>
|
|
88
|
+
</div>
|
|
89
|
+
`,
|
|
90
|
+
target);
|
|
91
|
+
// clang-format on
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
type View = (input: ViewInput, output: undefined, target: HTMLElement|ShadowRoot) => void;
|
|
95
|
+
|
|
96
|
+
export class CrashReportContextGrid extends UI.Widget.Widget {
|
|
97
|
+
#entries: Array<{key: string, value: string}> = [];
|
|
98
|
+
#filteredEntries: Array<{key: string, value: string}> = [];
|
|
99
|
+
#selectedKey?: string;
|
|
100
|
+
#filters: TextUtils.TextUtils.ParsedFilter[] = [];
|
|
101
|
+
readonly #view: View;
|
|
102
|
+
|
|
103
|
+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
104
|
+
super(element, {useShadowDom: true});
|
|
105
|
+
this.#view = view;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
set data(data: CrashReportContextGridData) {
|
|
109
|
+
this.#entries = data.entries;
|
|
110
|
+
this.#selectedKey = data.selectedKey;
|
|
111
|
+
this.#filters = data.filters || [];
|
|
112
|
+
this.requestUpdate();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#computeFilteredEntries(): void {
|
|
116
|
+
if (this.#filters.length === 0) {
|
|
117
|
+
this.#filteredEntries = this.#entries;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.#filteredEntries = this.#entries.filter(entry => {
|
|
121
|
+
return this.#filters.every(filter => {
|
|
122
|
+
const regex = filter.regex;
|
|
123
|
+
if (!regex) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
const matches = regex.test(entry.key) || regex.test(entry.value);
|
|
127
|
+
return filter.negative ? !matches : matches;
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
#onContextMenu(e: Event, key: string, value: string): void {
|
|
133
|
+
const customEvent = e as CustomEvent<UI.ContextMenu.ContextMenu>;
|
|
134
|
+
const contextMenu = customEvent.detail;
|
|
135
|
+
contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyKey), () => {
|
|
136
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(key);
|
|
137
|
+
}, {jslogContext: 'copy-key'});
|
|
138
|
+
contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyValue), () => {
|
|
139
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(value);
|
|
140
|
+
}, {jslogContext: 'copy-value'});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
override performUpdate(): void {
|
|
144
|
+
this.#computeFilteredEntries();
|
|
145
|
+
this.#view(
|
|
146
|
+
{
|
|
147
|
+
entries: this.#filteredEntries,
|
|
148
|
+
selectedKey: this.#selectedKey,
|
|
149
|
+
onSelect: (key: string) => this.element.dispatchEvent(new CustomEvent('select', {detail: key})),
|
|
150
|
+
onContextMenu: (e: Event, key: string, value: string) => this.#onContextMenu(e, key, value),
|
|
151
|
+
},
|
|
152
|
+
undefined, this.contentElement);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import * as BackForwardCacheView from './BackForwardCacheView.js';
|
|
6
6
|
import * as BounceTrackingMitigationsView from './BounceTrackingMitigationsView.js';
|
|
7
|
+
import * as CrashReportContextGrid from './CrashReportContextGrid.js';
|
|
7
8
|
import * as EndpointsGrid from './EndpointsGrid.js';
|
|
8
9
|
import * as InterestGroupAccessGrid from './InterestGroupAccessGrid.js';
|
|
9
10
|
import * as PermissionsPolicySection from './PermissionsPolicySection.js';
|
|
@@ -18,6 +19,7 @@ import * as TrustTokensView from './TrustTokensView.js';
|
|
|
18
19
|
export {
|
|
19
20
|
BackForwardCacheView,
|
|
20
21
|
BounceTrackingMitigationsView,
|
|
22
|
+
CrashReportContextGrid,
|
|
21
23
|
EndpointsGrid,
|
|
22
24
|
InterestGroupAccessGrid,
|
|
23
25
|
PermissionsPolicySection,
|
|
@@ -27,11 +27,36 @@
|
|
|
27
27
|
flex: auto;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
.data-grid {
|
|
31
|
+
th {
|
|
32
|
+
height: 26px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
td {
|
|
31
36
|
vertical-align: middle;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
tr.status-cancelled {
|
|
40
|
+
color: var(--sys-color-on-surface-light);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
tr.status-error {
|
|
44
|
+
color: var(--sys-color-error);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
tr.selected {
|
|
48
|
+
background-color: var(--sys-color-tonal-container);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
tr.selected.status-error {
|
|
52
|
+
background-color: var(--sys-color-error-container);
|
|
53
|
+
color: var(--sys-color-error);
|
|
54
|
+
}
|
|
32
55
|
}
|
|
33
56
|
|
|
34
57
|
.section-title {
|
|
58
|
+
display: flex;
|
|
59
|
+
gap: var(--sys-size-2);
|
|
35
60
|
background-color: var(--sys-color-surface1);
|
|
36
61
|
padding: 0 5px;
|
|
37
62
|
line-height: 22px;
|
|
@@ -47,6 +72,57 @@
|
|
|
47
72
|
gap: 4px;
|
|
48
73
|
}
|
|
49
74
|
|
|
75
|
+
.tool-details {
|
|
76
|
+
height: 100%;
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
overflow: auto;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.tool-details-grid {
|
|
83
|
+
display: grid;
|
|
84
|
+
grid-template-columns: min-content 1fr;
|
|
85
|
+
gap: 0 var(--sys-size-16);
|
|
86
|
+
padding: calc(0.5*var(--sys-size-6)) var(--sys-size-8);
|
|
87
|
+
align-items: flex-start;
|
|
88
|
+
|
|
89
|
+
.label {
|
|
90
|
+
color: var(--sys-color-on-surface-subtle);
|
|
91
|
+
white-space: nowrap;
|
|
92
|
+
padding: var(--sys-size-6) 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.value {
|
|
96
|
+
&.source-code {
|
|
97
|
+
color: var(--sys-color-token-attribute);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
padding: var(--sys-size-6) 0;
|
|
101
|
+
color: var(--sys-color-on-surface);
|
|
102
|
+
overflow-wrap: anywhere;
|
|
103
|
+
|
|
104
|
+
&:has(> .stack-preview-container) {
|
|
105
|
+
padding: var(--sys-size-4) 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.tool-origin-container {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
gap: var(--sys-size-4);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.tool-origin-node {
|
|
115
|
+
display: flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
cursor: default;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.show-element {
|
|
122
|
+
height: 1lh;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
50
126
|
devtools-list {
|
|
51
127
|
flex: 1 1 auto;
|
|
52
128
|
margin: 0;
|
|
@@ -60,8 +136,17 @@
|
|
|
60
136
|
padding: 8px 0;
|
|
61
137
|
gap: 4px;
|
|
62
138
|
width: 100%;
|
|
63
|
-
|
|
139
|
+
box-sizing: border-box;
|
|
64
140
|
border-bottom: 1px solid var(--sys-color-divider);
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.tool-item:hover {
|
|
145
|
+
background-color: var(--sys-color-state-hover-on-subtle);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.tool-item.selected {
|
|
149
|
+
background-color: var(--sys-color-tonal-container);
|
|
65
150
|
}
|
|
66
151
|
|
|
67
152
|
.tool-name-container {
|
|
@@ -91,10 +176,9 @@
|
|
|
91
176
|
|
|
92
177
|
.tool-description {
|
|
93
178
|
color: var(--sys-color-on-surface);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
color: var(--sys-color-error);
|
|
179
|
+
white-space: nowrap;
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
text-overflow: ellipsis;
|
|
98
182
|
}
|
|
99
183
|
|
|
100
184
|
devtools-toolbar-input {
|
|
@@ -102,10 +186,6 @@
|
|
|
102
186
|
flex-shrink: 1;
|
|
103
187
|
}
|
|
104
188
|
|
|
105
|
-
tr.status-cancelled {
|
|
106
|
-
color: var(--sys-color-on-surface-light);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
189
|
.toolbar-text.status-error-text {
|
|
110
190
|
color: var(--sys-color-error);
|
|
111
191
|
}
|
|
@@ -113,4 +193,21 @@
|
|
|
113
193
|
.toolbar-text.status-cancelled-text {
|
|
114
194
|
color: var(--sys-color-on-surface-light);
|
|
115
195
|
}
|
|
196
|
+
|
|
197
|
+
.call-details-tabbed-pane {
|
|
198
|
+
flex: auto;
|
|
199
|
+
border-bottom: 1px solid var(--sys-color-divider);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.call-payload-view {
|
|
203
|
+
display: flex;
|
|
204
|
+
flex-direction: column;
|
|
205
|
+
height: 100%;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.call-payload-content {
|
|
209
|
+
padding: var(--sys-size-5);
|
|
210
|
+
flex: auto;
|
|
211
|
+
overflow: auto;
|
|
212
|
+
}
|
|
116
213
|
}
|
|
@@ -44,6 +44,16 @@ const UIStringsNotTranslate = {
|
|
|
44
44
|
*/
|
|
45
45
|
tooltipDisclaimerTextForAiCodeCompletionNoLoggingInSources:
|
|
46
46
|
'To generate code suggestions, the contents of the currently open file are shared with Google. This data will not be used to improve Google’s AI models. Your organization may change these settings at any time.',
|
|
47
|
+
/**
|
|
48
|
+
* @description Text for tooltip shown on hovering over "Relevant Data" in the disclaimer text for AI code completion in Styles pane.
|
|
49
|
+
*/
|
|
50
|
+
tooltipDisclaimerTextForAiCodeCompletionInStyles:
|
|
51
|
+
'To generate code suggestions, the CSS properties of the selected element and the relevant CSS files are shared with Google. This data may be seen by human reviewers to improve this feature.',
|
|
52
|
+
/**
|
|
53
|
+
* @description Text for tooltip shown on hovering over "Relevant Data" in the disclaimer text for AI code completion in Styles pane.
|
|
54
|
+
*/
|
|
55
|
+
tooltipDisclaimerTextForAiCodeCompletionNoLoggingInStyles:
|
|
56
|
+
'To generate code suggestions, the CSS properties of the selected element and the relevant CSS files are shared with Google. This data will not be used to improve Google’s AI models. Your organization may change these settings at any time.',
|
|
47
57
|
/**
|
|
48
58
|
* Text for tooltip shown on hovering over spinner.
|
|
49
59
|
*/
|
|
@@ -71,8 +81,8 @@ function getTooltipDisclaimerText(noLogging: boolean, panel: AiCodeCompletion.Ai
|
|
|
71
81
|
lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeCompletionNoLoggingInSources) :
|
|
72
82
|
lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeCompletionInSources);
|
|
73
83
|
case AiCodeCompletion.AiCodeCompletion.ContextFlavor.STYLES:
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
return noLogging ? lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeCompletionNoLoggingInStyles) :
|
|
85
|
+
lockedString(UIStringsNotTranslate.tooltipDisclaimerTextForAiCodeCompletionInStyles);
|
|
76
86
|
}
|
|
77
87
|
}
|
|
78
88
|
|
|
@@ -16,25 +16,19 @@ import {ElementsPanel} from './ElementsPanel.js';
|
|
|
16
16
|
export class AccessibilityTreeView extends UI.Widget.VBox implements
|
|
17
17
|
SDK.TargetManager.SDKModelObserver<SDK.AccessibilityModel.AccessibilityModel> {
|
|
18
18
|
private accessibilityTreeComponent: TreeOutline.TreeOutline.TreeOutline<AccessibilityTreeUtils.AXTreeNodeData>;
|
|
19
|
-
private readonly toggleButton: HTMLElement;
|
|
20
19
|
private inspectedDOMNode: SDK.DOMModel.DOMNode|null = null;
|
|
21
20
|
private root: SDK.AccessibilityModel.AccessibilityNode|null = null;
|
|
22
21
|
|
|
23
22
|
constructor(
|
|
24
|
-
toggleButton: HTMLElement,
|
|
25
23
|
accessibilityTreeComponent: TreeOutline.TreeOutline.TreeOutline<AccessibilityTreeUtils.AXTreeNodeData>) {
|
|
26
24
|
super();
|
|
27
25
|
this.registerRequiredCSS(accessibilityTreeViewStyles);
|
|
28
|
-
// toggleButton is bound to a click handler on ElementsPanel to switch between the DOM tree
|
|
29
|
-
// and accessibility tree views.
|
|
30
|
-
this.toggleButton = toggleButton;
|
|
31
26
|
this.accessibilityTreeComponent = accessibilityTreeComponent;
|
|
32
27
|
|
|
33
28
|
const container = this.contentElement.createChild('div');
|
|
34
29
|
|
|
35
30
|
container.classList.add('accessibility-tree-view-container');
|
|
36
31
|
container.setAttribute('jslog', `${VisualLogging.tree('full-accessibility')}`);
|
|
37
|
-
container.appendChild(this.toggleButton);
|
|
38
32
|
container.appendChild(this.accessibilityTreeComponent);
|
|
39
33
|
|
|
40
34
|
SDK.TargetManager.TargetManager.instance().observeModels(
|
|
@@ -95,6 +89,12 @@ export class AccessibilityTreeView extends UI.Widget.VBox implements
|
|
|
95
89
|
}
|
|
96
90
|
|
|
97
91
|
async renderTree(): Promise<void> {
|
|
92
|
+
if (!this.root) {
|
|
93
|
+
const frameId = SDK.FrameManager.FrameManager.instance().getOutermostFrame()?.id;
|
|
94
|
+
if (frameId) {
|
|
95
|
+
this.root = await AccessibilityTreeUtils.getRootNode(frameId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
98
|
if (!this.root) {
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
@@ -149,10 +149,14 @@ export class AccessibilityTreeView extends UI.Widget.VBox implements
|
|
|
149
149
|
treeUpdated({data}: Common.EventTarget
|
|
150
150
|
.EventTargetEvent<SDK.AccessibilityModel.EventTypes[SDK.AccessibilityModel.Events.TREE_UPDATED]>):
|
|
151
151
|
void {
|
|
152
|
+
if (data.root) {
|
|
153
|
+
this.root = data.root;
|
|
154
|
+
}
|
|
152
155
|
if (!this.isShowing()) {
|
|
153
156
|
return;
|
|
154
157
|
}
|
|
155
158
|
if (!data.root) {
|
|
159
|
+
this.root = null;
|
|
156
160
|
void this.renderTree();
|
|
157
161
|
return;
|
|
158
162
|
}
|
|
@@ -44,7 +44,6 @@ import * as Annotations from '../../models/annotations/annotations.js';
|
|
|
44
44
|
import * as ComputedStyle from '../../models/computed_style/computed_style.js';
|
|
45
45
|
import * as PanelCommon from '../../panels/common/common.js';
|
|
46
46
|
import type * as Adorners from '../../ui/components/adorners/adorners.js';
|
|
47
|
-
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
48
47
|
import * as TreeOutline from '../../ui/components/tree_outline/tree_outline.js';
|
|
49
48
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
50
49
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -72,16 +71,6 @@ const UIStrings = {
|
|
|
72
71
|
* selectors.
|
|
73
72
|
*/
|
|
74
73
|
findByStringSelectorOrXpath: 'Find by string, selector, or `XPath`',
|
|
75
|
-
/**
|
|
76
|
-
* @description Button text for a button that takes the user to the Accessibility Tree View from the
|
|
77
|
-
* DOM tree view, in the Elements panel.
|
|
78
|
-
*/
|
|
79
|
-
switchToAccessibilityTreeView: 'Switch to Accessibility Tree view',
|
|
80
|
-
/**
|
|
81
|
-
* @description Button text for a button that takes the user to the DOM tree view from the
|
|
82
|
-
* Accessibility Tree View, in the Elements panel.
|
|
83
|
-
*/
|
|
84
|
-
switchToDomTreeView: 'Switch to DOM Tree view',
|
|
85
74
|
/**
|
|
86
75
|
* @description Tooltip for the the Computed Styles sidebar toggle in the Styles pane. Command to
|
|
87
76
|
* open/show the sidebar.
|
|
@@ -179,25 +168,6 @@ type RevealAndSelectNodeOpts = RevealAndSelectNodeOptsSelectionAndFocus&{
|
|
|
179
168
|
highlightInOverlay?: boolean,
|
|
180
169
|
};
|
|
181
170
|
|
|
182
|
-
const createAccessibilityTreeToggleButton = (isActive: boolean): HTMLElement => {
|
|
183
|
-
const button = new Buttons.Button.Button();
|
|
184
|
-
const title =
|
|
185
|
-
isActive ? i18nString(UIStrings.switchToDomTreeView) : i18nString(UIStrings.switchToAccessibilityTreeView);
|
|
186
|
-
button.data = {
|
|
187
|
-
active: isActive,
|
|
188
|
-
variant: Buttons.Button.Variant.TOOLBAR,
|
|
189
|
-
iconName: 'person',
|
|
190
|
-
title,
|
|
191
|
-
jslogContext: 'toggle-accessibility-tree',
|
|
192
|
-
};
|
|
193
|
-
button.tabIndex = 0;
|
|
194
|
-
button.classList.add('axtree-button');
|
|
195
|
-
if (isActive) {
|
|
196
|
-
button.classList.add('active');
|
|
197
|
-
}
|
|
198
|
-
return button;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
171
|
let elementsPanelInstance: ElementsPanel;
|
|
202
172
|
|
|
203
173
|
export const DEFAULT_COMPUTED_STYLES_DEBOUNCE_MS = 100;
|
|
@@ -268,9 +238,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
268
238
|
this.mainContainer = document.createElement('div');
|
|
269
239
|
this.domTreeContainer = document.createElement('div');
|
|
270
240
|
const crumbsContainer = document.createElement('div');
|
|
271
|
-
if (Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.FULL_ACCESSIBILITY_TREE)) {
|
|
272
|
-
this.initializeFullAccessibilityTreeView();
|
|
273
|
-
}
|
|
274
241
|
this.mainContainer.appendChild(this.domTreeContainer);
|
|
275
242
|
stackElement.appendChild(this.mainContainer);
|
|
276
243
|
stackElement.appendChild(crumbsContainer);
|
|
@@ -293,10 +260,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
293
260
|
.addChangeListener(this.domWordWrapSettingChanged.bind(this));
|
|
294
261
|
|
|
295
262
|
crumbsContainer.id = 'elements-crumbs';
|
|
296
|
-
|
|
297
|
-
this.accessibilityTreeView =
|
|
298
|
-
new AccessibilityTreeView(this.domTreeButton, new TreeOutline.TreeOutline.TreeOutline<AXTreeNodeData>());
|
|
299
|
-
}
|
|
263
|
+
this.accessibilityTreeView = new AccessibilityTreeView(new TreeOutline.TreeOutline.TreeOutline<AXTreeNodeData>());
|
|
300
264
|
this.breadcrumbs = new ElementsComponents.ElementsBreadcrumbs.ElementsBreadcrumbs();
|
|
301
265
|
this.breadcrumbs.addEventListener('breadcrumbsnodeselected', event => {
|
|
302
266
|
this.crumbNodeSelected(event);
|
|
@@ -401,24 +365,22 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
401
365
|
}
|
|
402
366
|
}
|
|
403
367
|
|
|
404
|
-
private initializeFullAccessibilityTreeView(): void {
|
|
405
|
-
this.accessibilityTreeButton = createAccessibilityTreeToggleButton(false);
|
|
406
|
-
this.accessibilityTreeButton.addEventListener('click', this.showAccessibilityTree.bind(this));
|
|
407
|
-
|
|
408
|
-
this.domTreeButton = createAccessibilityTreeToggleButton(true);
|
|
409
|
-
this.domTreeButton.addEventListener('click', this.showDOMTree.bind(this));
|
|
410
|
-
|
|
411
|
-
this.mainContainer.appendChild(this.accessibilityTreeButton);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
368
|
private showAccessibilityTree(): void {
|
|
415
369
|
if (this.accessibilityTreeView) {
|
|
416
370
|
this.splitWidget.setMainWidget(this.accessibilityTreeView);
|
|
371
|
+
const toggleAction = UI.ActionRegistry.ActionRegistry.instance().getAction('elements.toggle-a11y-tree');
|
|
372
|
+
if (toggleAction) {
|
|
373
|
+
toggleAction.setToggled(true);
|
|
374
|
+
}
|
|
417
375
|
}
|
|
418
376
|
}
|
|
419
377
|
|
|
420
378
|
private showDOMTree(): void {
|
|
421
379
|
this.splitWidget.setMainWidget(this.#searchableView);
|
|
380
|
+
const toggleAction = UI.ActionRegistry.ActionRegistry.instance().getAction('elements.toggle-a11y-tree');
|
|
381
|
+
if (toggleAction) {
|
|
382
|
+
toggleAction.setToggled(false);
|
|
383
|
+
}
|
|
422
384
|
const selectedNode = this.selectedDOMNode();
|
|
423
385
|
if (!selectedNode) {
|
|
424
386
|
return;
|
|
@@ -427,9 +389,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
427
389
|
}
|
|
428
390
|
|
|
429
391
|
toggleAccessibilityTree(): void {
|
|
430
|
-
if (!this.domTreeButton) {
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
392
|
if (this.splitWidget.mainWidget() === this.accessibilityTreeView) {
|
|
434
393
|
this.showDOMTree();
|
|
435
394
|
} else {
|
|
@@ -299,7 +299,7 @@ export class StylePropertiesSection {
|
|
|
299
299
|
const newRuleButton = new UI.Toolbar.ToolbarButton(
|
|
300
300
|
i18nString(UIStrings.insertStyleRuleBelow), 'plus', undefined, 'elements.new-style-rule');
|
|
301
301
|
newRuleButton.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, this.onNewRuleClick, this);
|
|
302
|
-
newRuleButton.setSize(Buttons.Button.Size.
|
|
302
|
+
newRuleButton.setSize(Buttons.Button.Size.MICRO);
|
|
303
303
|
newRuleButton.element.tabIndex = -1;
|
|
304
304
|
if (!this.newStyleRuleToolbar) {
|
|
305
305
|
this.newStyleRuleToolbar =
|
|
@@ -367,6 +367,7 @@ UI.ActionRegistration.registerActionExtension({
|
|
|
367
367
|
actionId: 'elements.toggle-a11y-tree',
|
|
368
368
|
category: UI.ActionRegistration.ActionCategory.ELEMENTS,
|
|
369
369
|
title: i18nLazyString(UIStrings.toggleA11yTree),
|
|
370
|
+
toggleable: true,
|
|
370
371
|
async loadActionDelegate() {
|
|
371
372
|
const Elements = await loadElementsModule();
|
|
372
373
|
return new Elements.ElementsPanel.ElementsActionDelegate();
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* Copyright 2026 The Chromium Authors
|
|
2
|
+
* Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
* found in the LICENSE file.
|
|
4
|
+
*
|
|
2
5
|
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
|
|
3
6
|
* Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
|
|
4
7
|
*
|
|
@@ -83,19 +86,6 @@ devtools-tree-outline {
|
|
|
83
86
|
overflow: auto;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
.axtree-button {
|
|
87
|
-
position: absolute;
|
|
88
|
-
top: var(--sys-size-8);
|
|
89
|
-
right: var(--sys-size-9);
|
|
90
|
-
background-color: var(--sys-color-cdt-base-container);
|
|
91
|
-
display: flex;
|
|
92
|
-
justify-content: center;
|
|
93
|
-
align-items: center;
|
|
94
|
-
z-index: 1;
|
|
95
|
-
border-radius: var(--sys-shape-corner-full);
|
|
96
|
-
box-shadow: var(--sys-elevation-level1);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
89
|
.computed-styles-wrapper {
|
|
100
90
|
flex-shrink: 0;
|
|
101
91
|
}
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
HeapSnapshotObjectNode,
|
|
20
20
|
HeapSnapshotRetainingObjectNode,
|
|
21
21
|
} from './HeapSnapshotGridNodes.js';
|
|
22
|
-
import type {HeapSnapshotProxy} from './HeapSnapshotProxy.js';
|
|
23
22
|
import type {HeapProfileHeader} from './HeapSnapshotView.js';
|
|
24
23
|
import type {DataDisplayDelegate} from './ProfileHeader.js';
|
|
25
24
|
|
|
@@ -132,7 +131,7 @@ class HeapSnapshotSortableDataGridBase extends DataGrid.DataGrid.DataGridImpl<He
|
|
|
132
131
|
export class HeapSnapshotSortableDataGrid extends Common.ObjectWrapper
|
|
133
132
|
.eventMixin<EventTypes, typeof HeapSnapshotSortableDataGridBase>(
|
|
134
133
|
HeapSnapshotSortableDataGridBase) {
|
|
135
|
-
snapshot: HeapSnapshotProxy|null = null;
|
|
134
|
+
snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy|null = null;
|
|
136
135
|
override selectedNode: HeapSnapshotGridNode|null = null;
|
|
137
136
|
readonly heapProfilerModelInternal: SDK.HeapProfilerModel.HeapProfilerModel|null;
|
|
138
137
|
readonly dataDisplayDelegateInternal: DataDisplayDelegate;
|
|
@@ -170,7 +169,8 @@ export class HeapSnapshotSortableDataGrid extends Common.ObjectWrapper
|
|
|
170
169
|
this.setRowContextMenuCallback(this.populateContextMenu.bind(this));
|
|
171
170
|
}
|
|
172
171
|
|
|
173
|
-
async setDataSource(_snapshot: HeapSnapshotProxy, _nodeIndex: number):
|
|
172
|
+
async setDataSource(_snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy, _nodeIndex: number):
|
|
173
|
+
Promise<void> {
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
isFilteredOut(node: HeapSnapshotGridNode): boolean {
|
|
@@ -643,7 +643,9 @@ export class HeapSnapshotContainmentDataGrid extends HeapSnapshotSortableDataGri
|
|
|
643
643
|
super(heapProfilerModel, dataDisplayDelegate, {displayName, columns});
|
|
644
644
|
}
|
|
645
645
|
|
|
646
|
-
override async setDataSource(
|
|
646
|
+
override async setDataSource(
|
|
647
|
+
snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy, nodeIndex: number,
|
|
648
|
+
nodeId?: number): Promise<void> {
|
|
647
649
|
this.snapshot = snapshot;
|
|
648
650
|
const node = new HeapSnapshotModel.HeapSnapshotModel.Node(
|
|
649
651
|
nodeId ?? -1, 'root', 0, nodeIndex || snapshot.rootNodeIndex, 0, 0, '');
|
|
@@ -651,7 +653,9 @@ export class HeapSnapshotContainmentDataGrid extends HeapSnapshotSortableDataGri
|
|
|
651
653
|
void (this.rootNode() as HeapSnapshotGridNode).sort();
|
|
652
654
|
}
|
|
653
655
|
|
|
654
|
-
createRootNode(
|
|
656
|
+
createRootNode(
|
|
657
|
+
snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy,
|
|
658
|
+
node: HeapSnapshotModel.HeapSnapshotModel.Node): HeapSnapshotObjectNode {
|
|
655
659
|
const fakeEdge = new HeapSnapshotModel.HeapSnapshotModel.Edge('', node, '', -1);
|
|
656
660
|
return new HeapSnapshotObjectNode(this, snapshot, fakeEdge, null);
|
|
657
661
|
}
|
|
@@ -684,8 +688,9 @@ export class HeapSnapshotRetainmentDataGrid extends HeapSnapshotContainmentDataG
|
|
|
684
688
|
super(heapProfilerModel, dataDisplayDelegate, i18nString(UIStrings.heapSnapshotRetainment), columns);
|
|
685
689
|
}
|
|
686
690
|
|
|
687
|
-
override createRootNode(
|
|
688
|
-
|
|
691
|
+
override createRootNode(
|
|
692
|
+
snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy,
|
|
693
|
+
node: HeapSnapshotModel.HeapSnapshotModel.Node): HeapSnapshotRetainingObjectNode {
|
|
689
694
|
const fakeEdge = new HeapSnapshotModel.HeapSnapshotModel.Edge('', node, '', -1);
|
|
690
695
|
return new HeapSnapshotRetainingObjectNode(this, snapshot, fakeEdge, null);
|
|
691
696
|
}
|
|
@@ -719,7 +724,9 @@ export class HeapSnapshotRetainmentDataGrid extends HeapSnapshotContainmentDataG
|
|
|
719
724
|
});
|
|
720
725
|
}
|
|
721
726
|
|
|
722
|
-
override async setDataSource(
|
|
727
|
+
override async setDataSource(
|
|
728
|
+
snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy, nodeIndex: number,
|
|
729
|
+
nodeId?: number): Promise<void> {
|
|
723
730
|
await super.setDataSource(snapshot, nodeIndex, nodeId);
|
|
724
731
|
this.rootNode().expand();
|
|
725
732
|
this.updateResetButtonVisibility();
|
|
@@ -824,7 +831,8 @@ export class HeapSnapshotConstructorsDataGrid extends HeapSnapshotViewportDataGr
|
|
|
824
831
|
this.removeTopLevelNodes();
|
|
825
832
|
}
|
|
826
833
|
|
|
827
|
-
override async setDataSource(snapshot: HeapSnapshotProxy, _nodeIndex: number):
|
|
834
|
+
override async setDataSource(snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy, _nodeIndex: number):
|
|
835
|
+
Promise<void> {
|
|
828
836
|
this.snapshot = snapshot;
|
|
829
837
|
if (this.profileIndex === -1) {
|
|
830
838
|
void this.populateChildren();
|
|
@@ -904,7 +912,7 @@ export class HeapSnapshotConstructorsDataGrid extends HeapSnapshotViewportDataGr
|
|
|
904
912
|
}
|
|
905
913
|
|
|
906
914
|
export class HeapSnapshotDiffDataGrid extends HeapSnapshotViewportDataGrid {
|
|
907
|
-
baseSnapshot?: HeapSnapshotProxy;
|
|
915
|
+
baseSnapshot?: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy;
|
|
908
916
|
|
|
909
917
|
constructor(
|
|
910
918
|
heapProfilerModel: SDK.HeapProfilerModel.HeapProfilerModel|null, dataDisplayDelegate: DataDisplayDelegate) {
|
|
@@ -955,11 +963,12 @@ export class HeapSnapshotDiffDataGrid extends HeapSnapshotViewportDataGrid {
|
|
|
955
963
|
}
|
|
956
964
|
}
|
|
957
965
|
|
|
958
|
-
override async setDataSource(snapshot: HeapSnapshotProxy, _nodeIndex: number):
|
|
966
|
+
override async setDataSource(snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy, _nodeIndex: number):
|
|
967
|
+
Promise<void> {
|
|
959
968
|
this.snapshot = snapshot;
|
|
960
969
|
}
|
|
961
970
|
|
|
962
|
-
setBaseDataSource(baseSnapshot: HeapSnapshotProxy): void {
|
|
971
|
+
setBaseDataSource(baseSnapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy): void {
|
|
963
972
|
this.baseSnapshot = baseSnapshot;
|
|
964
973
|
this.removeTopLevelNodes();
|
|
965
974
|
this.resetSortingCache();
|
|
@@ -1023,7 +1032,8 @@ export class AllocationDataGrid extends HeapSnapshotViewportDataGrid {
|
|
|
1023
1032
|
this.linkifierInternal.reset();
|
|
1024
1033
|
}
|
|
1025
1034
|
|
|
1026
|
-
override async setDataSource(snapshot: HeapSnapshotProxy, _nodeIndex: number):
|
|
1035
|
+
override async setDataSource(snapshot: HeapSnapshotModel.HeapSnapshotProxy.HeapSnapshotProxy, _nodeIndex: number):
|
|
1036
|
+
Promise<void> {
|
|
1027
1037
|
this.snapshot = snapshot;
|
|
1028
1038
|
this.topNodes = await this.snapshot.allocationTracesTops();
|
|
1029
1039
|
this.populateChildren();
|