chrome-devtools-frontend 1.0.1643099 → 1.0.1643855
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/eslint.config.mjs +3 -1
- package/extension-api/ExtensionAPI.d.ts +83 -12
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/ConsoleModel.ts +4 -0
- package/front_end/core/sdk/NetworkRequest.ts +12 -0
- package/front_end/core/sdk/SourceMap.ts +15 -18
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -2
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
- package/front_end/entrypoints/main/MainImpl.ts +0 -6
- package/front_end/models/ai_assistance/AiAgent2.ts +1 -0
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +22 -16
- package/front_end/models/ai_assistance/agents/AiAgent.ts +19 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +5 -5
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -94
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +25 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +22 -0
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +54 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -2
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +5 -0
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +4 -10
- package/front_end/models/ai_assistance/tools/Tool.ts +6 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +6 -9
- package/front_end/models/bindings/DefaultScriptMapping.ts +2 -1
- package/front_end/models/bindings/SymbolizedError.ts +45 -35
- package/front_end/models/extensions/ExtensionAPI.ts +138 -47
- package/front_end/models/har/Importer.ts +1 -0
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +12 -2
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +44 -51
- package/front_end/models/stack_trace/StackTrace.ts +7 -0
- package/front_end/models/stack_trace/StackTraceImpl.ts +13 -4
- package/front_end/models/stack_trace/StackTraceModel.ts +9 -8
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +2 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -1
- package/front_end/panels/application/ApplicationPanelSidebar.ts +39 -0
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +39 -0
- package/front_end/panels/application/CookieItemsView.ts +2 -2
- package/front_end/panels/application/resourcesSidebar.css +11 -0
- package/front_end/panels/console/SymbolizedErrorWidget.ts +10 -7
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -0
- package/front_end/panels/sources/SourcesPanel.ts +2 -1
- package/front_end/ui/legacy/StackedPane.ts +229 -0
- package/front_end/ui/legacy/ViewManager.ts +59 -169
- package/front_end/ui/legacy/legacy.ts +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,229 @@
|
|
|
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
|
+
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
6
|
+
|
|
7
|
+
import type * as Lit from '../../ui/lit/lit.js';
|
|
8
|
+
import {createIcon, type Icon} from '../kit/kit.js';
|
|
9
|
+
import * as VisualLogging from '../visual_logging/visual_logging.js';
|
|
10
|
+
|
|
11
|
+
import * as ARIAUtils from './ARIAUtils.js';
|
|
12
|
+
import type * as Toolbar from './Toolbar.js';
|
|
13
|
+
import {createTextChild} from './UIUtils.js';
|
|
14
|
+
import type {View} from './View.js';
|
|
15
|
+
import viewContainersStyles from './viewContainers.css.js';
|
|
16
|
+
import {type AnyWidget, VBox} from './Widget.js';
|
|
17
|
+
|
|
18
|
+
type CreateToolbarFn = (toolbarItems: Toolbar.ToolbarItem[]|Lit.TemplateResult) => Element|null;
|
|
19
|
+
type SetWidgetForViewFn = (view: View, widget: AnyWidget) => void;
|
|
20
|
+
|
|
21
|
+
export class ExpandableContainerWidget extends VBox {
|
|
22
|
+
private titleElement: HTMLDivElement;
|
|
23
|
+
private readonly titleExpandIcon: Icon;
|
|
24
|
+
private readonly view: View;
|
|
25
|
+
private widget?: AnyWidget;
|
|
26
|
+
private materializePromise?: Promise<void>;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
view: View,
|
|
30
|
+
private readonly createToolbar: CreateToolbarFn,
|
|
31
|
+
private readonly setWidgetForView: SetWidgetForViewFn,
|
|
32
|
+
private readonly onVisibilityChanged?: (isExpanded: boolean) => void,
|
|
33
|
+
) {
|
|
34
|
+
super({useShadowDom: true});
|
|
35
|
+
this.element.classList.add('flex-none');
|
|
36
|
+
this.registerRequiredCSS(viewContainersStyles);
|
|
37
|
+
|
|
38
|
+
this.onVisibilityChanged = onVisibilityChanged;
|
|
39
|
+
this.createToolbar = createToolbar;
|
|
40
|
+
|
|
41
|
+
this.titleElement = document.createElement('div');
|
|
42
|
+
this.titleElement.classList.add('expandable-view-title');
|
|
43
|
+
this.titleElement.setAttribute('jslog', `${VisualLogging.sectionHeader().context(view.viewId()).track({
|
|
44
|
+
click: true,
|
|
45
|
+
keydown: 'Enter|Space|ArrowLeft|ArrowRight',
|
|
46
|
+
})}`);
|
|
47
|
+
ARIAUtils.markAsTreeitem(this.titleElement);
|
|
48
|
+
this.titleExpandIcon = createIcon('triangle-right', 'title-expand-icon');
|
|
49
|
+
this.titleElement.appendChild(this.titleExpandIcon);
|
|
50
|
+
const titleText = view.title();
|
|
51
|
+
createTextChild(this.titleElement, titleText);
|
|
52
|
+
ARIAUtils.setLabel(this.titleElement, titleText);
|
|
53
|
+
ARIAUtils.setExpanded(this.titleElement, false);
|
|
54
|
+
this.titleElement.tabIndex = 0;
|
|
55
|
+
self.onInvokeElement(this.titleElement, this.toggleExpanded.bind(this));
|
|
56
|
+
this.titleElement.addEventListener('keydown', this.onTitleKeyDown.bind(this), false);
|
|
57
|
+
this.contentElement.insertBefore(this.titleElement, this.contentElement.firstChild);
|
|
58
|
+
|
|
59
|
+
ARIAUtils.setControls(this.titleElement, this.contentElement.createChild('slot'));
|
|
60
|
+
this.view = view;
|
|
61
|
+
expandableContainerForView.set(view, this);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
isExpanded(): boolean {
|
|
65
|
+
return this.titleElement.classList.contains('expanded');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
override wasShown(): void {
|
|
69
|
+
super.wasShown();
|
|
70
|
+
if (this.widget && this.materializePromise) {
|
|
71
|
+
void this.materializePromise.then(() => {
|
|
72
|
+
if (this.isExpanded() && this.widget) {
|
|
73
|
+
this.widget.show(this.element);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private materialize(): Promise<void> {
|
|
80
|
+
if (this.materializePromise) {
|
|
81
|
+
return this.materializePromise;
|
|
82
|
+
}
|
|
83
|
+
// TODO(crbug.com/1006759): Transform to async-await
|
|
84
|
+
const promises = [];
|
|
85
|
+
promises.push(this.view.toolbarItems().then(toolbarItems => {
|
|
86
|
+
const toolbarElement = this.createToolbar(toolbarItems);
|
|
87
|
+
if (toolbarElement) {
|
|
88
|
+
this.titleElement.appendChild(toolbarElement);
|
|
89
|
+
}
|
|
90
|
+
}));
|
|
91
|
+
promises.push(this.view.widget().then(widget => {
|
|
92
|
+
this.widget = widget;
|
|
93
|
+
this.setWidgetForView(this.view, widget);
|
|
94
|
+
}));
|
|
95
|
+
this.materializePromise = Promise.all(promises).then(() => {});
|
|
96
|
+
return this.materializePromise;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
expand(): Promise<void> {
|
|
100
|
+
if (this.isExpanded()) {
|
|
101
|
+
return this.materialize();
|
|
102
|
+
}
|
|
103
|
+
this.titleElement.classList.add('expanded');
|
|
104
|
+
ARIAUtils.setExpanded(this.titleElement, true);
|
|
105
|
+
this.titleExpandIcon.name = 'triangle-down';
|
|
106
|
+
this.onVisibilityChanged?.(true);
|
|
107
|
+
return this.materialize().then(() => {
|
|
108
|
+
if (this.isExpanded() && this.widget) {
|
|
109
|
+
this.widget.show(this.element);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private collapse(): void {
|
|
115
|
+
if (!this.isExpanded()) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.titleElement.classList.remove('expanded');
|
|
119
|
+
ARIAUtils.setExpanded(this.titleElement, false);
|
|
120
|
+
this.titleExpandIcon.name = 'triangle-right';
|
|
121
|
+
this.onVisibilityChanged?.(false);
|
|
122
|
+
void this.materialize().then(() => {
|
|
123
|
+
if (this.widget) {
|
|
124
|
+
this.widget.detach();
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private toggleExpanded(event: Event): void {
|
|
130
|
+
if (event.type === 'keydown' && event.target !== this.titleElement) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (this.isExpanded()) {
|
|
134
|
+
this.collapse();
|
|
135
|
+
} else {
|
|
136
|
+
void this.expand();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private onTitleKeyDown(event: Event): void {
|
|
141
|
+
if (event.target !== this.titleElement) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const keyEvent = (event as KeyboardEvent);
|
|
145
|
+
if (keyEvent.key === 'ArrowLeft') {
|
|
146
|
+
this.collapse();
|
|
147
|
+
} else if (keyEvent.key === 'ArrowRight') {
|
|
148
|
+
if (!this.isExpanded()) {
|
|
149
|
+
void this.expand();
|
|
150
|
+
} else if (this.widget) {
|
|
151
|
+
this.widget.focus();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const expandableContainerForView = new WeakMap<View, ExpandableContainerWidget>();
|
|
158
|
+
|
|
159
|
+
export class StackedPane extends VBox {
|
|
160
|
+
readonly expandableContainers = new Map<string, ExpandableContainerWidget>();
|
|
161
|
+
constructor(
|
|
162
|
+
private readonly createToolbar: CreateToolbarFn,
|
|
163
|
+
private readonly setWidgetForView: SetWidgetForViewFn,
|
|
164
|
+
private readonly onViewVisibilityChanged?: (viewId: string, isExpanded: boolean) => void,
|
|
165
|
+
) {
|
|
166
|
+
super();
|
|
167
|
+
this.createToolbar = createToolbar;
|
|
168
|
+
this.onViewVisibilityChanged = onViewVisibilityChanged;
|
|
169
|
+
ARIAUtils.markAsTree(this.element);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
appendView(view: View, insertBefore?: View|null): void {
|
|
173
|
+
let container = this.expandableContainers.get(view.viewId());
|
|
174
|
+
if (!container) {
|
|
175
|
+
container =
|
|
176
|
+
new ExpandableContainerWidget(view, this.createToolbar, this.setWidgetForView,
|
|
177
|
+
isExpanded => this.onViewVisibilityChanged?.(view.viewId(), isExpanded));
|
|
178
|
+
let beforeElement: Node|null = null;
|
|
179
|
+
if (insertBefore) {
|
|
180
|
+
const beforeContainer = expandableContainerForView.get(insertBefore);
|
|
181
|
+
beforeElement = beforeContainer ? beforeContainer.element : null;
|
|
182
|
+
}
|
|
183
|
+
container.show(this.contentElement, beforeElement);
|
|
184
|
+
this.expandableContainers.set(view.viewId(), container);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override wasShown(): void {
|
|
189
|
+
super.wasShown();
|
|
190
|
+
for (const [viewId, container] of this.expandableContainers) {
|
|
191
|
+
if (container.isExpanded()) {
|
|
192
|
+
this.onViewVisibilityChanged?.(viewId, true);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
override willHide(): void {
|
|
198
|
+
super.willHide();
|
|
199
|
+
for (const [viewId, container] of this.expandableContainers) {
|
|
200
|
+
if (container.isExpanded()) {
|
|
201
|
+
this.onViewVisibilityChanged?.(viewId, false);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
removeView(view: View): void {
|
|
207
|
+
const container = this.expandableContainers.get(view.viewId());
|
|
208
|
+
if (container) {
|
|
209
|
+
container.detach();
|
|
210
|
+
this.expandableContainers.delete(view.viewId());
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async expandView(view: View): Promise<void> {
|
|
215
|
+
const container = this.expandableContainers.get(view.viewId());
|
|
216
|
+
if (container) {
|
|
217
|
+
await container.expand();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
isViewExpanded(viewId: string): boolean {
|
|
222
|
+
const container = this.expandableContainers.get(viewId);
|
|
223
|
+
return container ? container.isExpanded() : false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
getContainerForView(view: View): ExpandableContainerWidget|undefined {
|
|
227
|
+
return this.expandableContainers.get(view.viewId());
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -11,18 +11,17 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
11
11
|
import * as Platform from '../../core/platform/platform.js';
|
|
12
12
|
import * as Root from '../../core/root/root.js';
|
|
13
13
|
import type * as Foundation from '../../foundation/foundation.js';
|
|
14
|
-
import {createIcon
|
|
14
|
+
import {createIcon} from '../kit/kit.js';
|
|
15
15
|
import {render, type TemplateResult} from '../lit/lit.js';
|
|
16
16
|
import * as VisualLogging from '../visual_logging/visual_logging.js';
|
|
17
17
|
|
|
18
18
|
import * as ARIAUtils from './ARIAUtils.js';
|
|
19
19
|
import type {ContextMenu} from './ContextMenu.js';
|
|
20
20
|
import * as PlusButton from './PlusButton.js';
|
|
21
|
+
import {StackedPane} from './StackedPane.js';
|
|
21
22
|
import {type EventData, Events as TabbedPaneEvents, TabbedPane} from './TabbedPane.js';
|
|
22
23
|
import {type ItemsProvider, type ToolbarItem, ToolbarMenuButton} from './Toolbar.js';
|
|
23
|
-
import {createTextChild} from './UIUtils.js';
|
|
24
24
|
import type {TabbedViewLocation, View, ViewLocation} from './View.js';
|
|
25
|
-
import viewContainersStyles from './viewContainers.css.js';
|
|
26
25
|
import {
|
|
27
26
|
getLocalizedViewLocationCategory,
|
|
28
27
|
getRegisteredLocationResolvers,
|
|
@@ -262,6 +261,10 @@ export class ViewManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
262
261
|
return toolbar;
|
|
263
262
|
}
|
|
264
263
|
|
|
264
|
+
static setWidgetForView(view: View, widget: AnyWidget): void {
|
|
265
|
+
widgetForView.set(view, widget);
|
|
266
|
+
}
|
|
267
|
+
|
|
265
268
|
getRegisteredViewExtensions(): PreRegisteredView[] {
|
|
266
269
|
return this.preRegisteredViews;
|
|
267
270
|
}
|
|
@@ -402,7 +405,7 @@ export class ViewManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
402
405
|
return new TabbedLocation(this, revealCallback, location, restoreSelection, allowReorder, options);
|
|
403
406
|
}
|
|
404
407
|
|
|
405
|
-
createStackLocation(revealCallback?: (() => void), location?: string, jslogContext?: string):
|
|
408
|
+
createStackLocation(revealCallback?: (() => void), location?: string, jslogContext?: string): StackLocation {
|
|
406
409
|
return new StackLocation(this, revealCallback, location, jslogContext);
|
|
407
410
|
}
|
|
408
411
|
|
|
@@ -453,7 +456,7 @@ export class ContainerWidget extends VBox {
|
|
|
453
456
|
// Move focus from |this| to loaded |widget| if any.
|
|
454
457
|
const shouldFocus = this.element.hasFocus();
|
|
455
458
|
this.setDefaultFocusedElement(null);
|
|
456
|
-
|
|
459
|
+
ViewManager.setWidgetForView(this.view, widget);
|
|
457
460
|
widget.show(this.element);
|
|
458
461
|
if (shouldFocus) {
|
|
459
462
|
widget.focus();
|
|
@@ -479,131 +482,6 @@ export class ContainerWidget extends VBox {
|
|
|
479
482
|
}
|
|
480
483
|
}
|
|
481
484
|
|
|
482
|
-
class ExpandableContainerWidget extends VBox {
|
|
483
|
-
private titleElement: HTMLDivElement;
|
|
484
|
-
private readonly titleExpandIcon: Icon;
|
|
485
|
-
private readonly view: View;
|
|
486
|
-
private widget?: AnyWidget;
|
|
487
|
-
private materializePromise?: Promise<void>;
|
|
488
|
-
|
|
489
|
-
constructor(view: View) {
|
|
490
|
-
super({useShadowDom: true});
|
|
491
|
-
this.element.classList.add('flex-none');
|
|
492
|
-
this.registerRequiredCSS(viewContainersStyles);
|
|
493
|
-
|
|
494
|
-
this.titleElement = document.createElement('div');
|
|
495
|
-
this.titleElement.classList.add('expandable-view-title');
|
|
496
|
-
this.titleElement.setAttribute('jslog', `${VisualLogging.sectionHeader().context(view.viewId()).track({
|
|
497
|
-
click: true,
|
|
498
|
-
keydown: 'Enter|Space|ArrowLeft|ArrowRight',
|
|
499
|
-
})}`);
|
|
500
|
-
ARIAUtils.markAsTreeitem(this.titleElement);
|
|
501
|
-
this.titleExpandIcon = createIcon('triangle-right', 'title-expand-icon');
|
|
502
|
-
this.titleElement.appendChild(this.titleExpandIcon);
|
|
503
|
-
const titleText = view.title();
|
|
504
|
-
createTextChild(this.titleElement, titleText);
|
|
505
|
-
ARIAUtils.setLabel(this.titleElement, titleText);
|
|
506
|
-
ARIAUtils.setExpanded(this.titleElement, false);
|
|
507
|
-
this.titleElement.tabIndex = 0;
|
|
508
|
-
self.onInvokeElement(this.titleElement, this.toggleExpanded.bind(this));
|
|
509
|
-
this.titleElement.addEventListener('keydown', this.onTitleKeyDown.bind(this), false);
|
|
510
|
-
this.contentElement.insertBefore(this.titleElement, this.contentElement.firstChild);
|
|
511
|
-
|
|
512
|
-
ARIAUtils.setControls(this.titleElement, this.contentElement.createChild('slot'));
|
|
513
|
-
this.view = view;
|
|
514
|
-
expandableContainerForView.set(view, this);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
override wasShown(): void {
|
|
518
|
-
super.wasShown();
|
|
519
|
-
if (this.widget && this.materializePromise) {
|
|
520
|
-
void this.materializePromise.then(() => {
|
|
521
|
-
if (this.titleElement.classList.contains('expanded') && this.widget) {
|
|
522
|
-
this.widget.show(this.element);
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
private materialize(): Promise<void> {
|
|
529
|
-
if (this.materializePromise) {
|
|
530
|
-
return this.materializePromise;
|
|
531
|
-
}
|
|
532
|
-
// TODO(crbug.com/1006759): Transform to async-await
|
|
533
|
-
const promises = [];
|
|
534
|
-
promises.push(this.view.toolbarItems().then(toolbarItems => {
|
|
535
|
-
const toolbarElement = ViewManager.createToolbar(toolbarItems);
|
|
536
|
-
if (toolbarElement) {
|
|
537
|
-
this.titleElement.appendChild(toolbarElement);
|
|
538
|
-
}
|
|
539
|
-
}));
|
|
540
|
-
promises.push(this.view.widget().then(widget => {
|
|
541
|
-
this.widget = widget;
|
|
542
|
-
widgetForView.set(this.view, widget);
|
|
543
|
-
widget.show(this.element);
|
|
544
|
-
}));
|
|
545
|
-
this.materializePromise = Promise.all(promises).then(() => {});
|
|
546
|
-
return this.materializePromise;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
expand(): Promise<void> {
|
|
550
|
-
if (this.titleElement.classList.contains('expanded')) {
|
|
551
|
-
return this.materialize();
|
|
552
|
-
}
|
|
553
|
-
this.titleElement.classList.add('expanded');
|
|
554
|
-
ARIAUtils.setExpanded(this.titleElement, true);
|
|
555
|
-
this.titleExpandIcon.name = 'triangle-down';
|
|
556
|
-
return this.materialize().then(() => {
|
|
557
|
-
if (this.widget) {
|
|
558
|
-
this.widget.show(this.element);
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
private collapse(): void {
|
|
564
|
-
if (!this.titleElement.classList.contains('expanded')) {
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
this.titleElement.classList.remove('expanded');
|
|
568
|
-
ARIAUtils.setExpanded(this.titleElement, false);
|
|
569
|
-
this.titleExpandIcon.name = 'triangle-right';
|
|
570
|
-
void this.materialize().then(() => {
|
|
571
|
-
if (this.widget) {
|
|
572
|
-
this.widget.detach();
|
|
573
|
-
}
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
private toggleExpanded(event: Event): void {
|
|
578
|
-
if (event.type === 'keydown' && event.target !== this.titleElement) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
if (this.titleElement.classList.contains('expanded')) {
|
|
582
|
-
this.collapse();
|
|
583
|
-
} else {
|
|
584
|
-
void this.expand();
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
private onTitleKeyDown(event: Event): void {
|
|
589
|
-
if (event.target !== this.titleElement) {
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
const keyEvent = (event as KeyboardEvent);
|
|
593
|
-
if (keyEvent.key === 'ArrowLeft') {
|
|
594
|
-
this.collapse();
|
|
595
|
-
} else if (keyEvent.key === 'ArrowRight') {
|
|
596
|
-
if (!this.titleElement.classList.contains('expanded')) {
|
|
597
|
-
void this.expand();
|
|
598
|
-
} else if (this.widget) {
|
|
599
|
-
this.widget.focus();
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
const expandableContainerForView = new WeakMap<View, ExpandableContainerWidget>();
|
|
606
|
-
|
|
607
485
|
class Location {
|
|
608
486
|
protected readonly manager: ViewManager;
|
|
609
487
|
private readonly revealCallback: (() => void)|undefined;
|
|
@@ -958,68 +836,80 @@ class TabbedLocation extends Location implements TabbedViewLocation {
|
|
|
958
836
|
static orderStep = 10; // Keep in sync with descriptors.
|
|
959
837
|
}
|
|
960
838
|
|
|
961
|
-
class StackLocation extends Location implements ViewLocation {
|
|
962
|
-
private readonly
|
|
963
|
-
private readonly
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
839
|
+
export class StackLocation extends Location implements ViewLocation {
|
|
840
|
+
private readonly stackedPane: StackedPane;
|
|
841
|
+
private readonly location: string;
|
|
842
|
+
#isVisible: boolean;
|
|
843
|
+
|
|
844
|
+
constructor(manager: ViewManager, revealCallback?: (() => void), location?: string, jslogContext?: string,
|
|
845
|
+
initialVisibility = true) {
|
|
846
|
+
const stackedPane =
|
|
847
|
+
new StackedPane(ViewManager.createToolbar, ViewManager.setWidgetForView, (viewId, isExpanded) => {
|
|
848
|
+
if (this.#isVisible) {
|
|
849
|
+
manager.dispatchEventToListeners(Events.VIEW_VISIBILITY_CHANGED, {
|
|
850
|
+
location: this.location,
|
|
851
|
+
revealedViewId: isExpanded ? viewId : undefined,
|
|
852
|
+
hiddenViewId: isExpanded ? undefined : viewId,
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
stackedPane.element.setAttribute('jslog', `${VisualLogging.pane(jslogContext || 'sidebar').track({resize: true})}`);
|
|
857
|
+
super(manager, stackedPane, revealCallback);
|
|
858
|
+
this.location = location || '';
|
|
859
|
+
this.stackedPane = stackedPane;
|
|
860
|
+
this.#isVisible = initialVisibility;
|
|
973
861
|
|
|
974
862
|
if (location) {
|
|
975
863
|
this.appendApplicableItems(location);
|
|
976
864
|
}
|
|
977
865
|
}
|
|
978
866
|
|
|
867
|
+
// Blink test(s) rely on this
|
|
868
|
+
get expandableContainers(): Map<string, AnyWidget> {
|
|
869
|
+
return this.stackedPane.expandableContainers;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
notifyVisibilityChanged(isVisible: boolean): void {
|
|
873
|
+
if (this.#isVisible === isVisible) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
this.#isVisible = isVisible;
|
|
877
|
+
|
|
878
|
+
for (const [viewId, container] of this.stackedPane.expandableContainers) {
|
|
879
|
+
if (container.isExpanded()) {
|
|
880
|
+
this.manager.dispatchEventToListeners(Events.VIEW_VISIBILITY_CHANGED, {
|
|
881
|
+
location: this.location,
|
|
882
|
+
revealedViewId: isVisible ? viewId : undefined,
|
|
883
|
+
hiddenViewId: isVisible ? undefined : viewId,
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
|
|
979
889
|
appendView(view: View, insertBefore?: View|null): void {
|
|
980
890
|
const oldLocation = locationForView.get(view);
|
|
981
891
|
if (oldLocation && oldLocation !== this) {
|
|
982
892
|
oldLocation.removeView(view);
|
|
983
893
|
}
|
|
984
894
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
this.manager.views.set(view.viewId(), view);
|
|
989
|
-
container = new ExpandableContainerWidget(view);
|
|
990
|
-
let beforeElement: Node|null = null;
|
|
991
|
-
if (insertBefore) {
|
|
992
|
-
const beforeContainer = expandableContainerForView.get(insertBefore);
|
|
993
|
-
beforeElement = beforeContainer ? beforeContainer.element : null;
|
|
994
|
-
}
|
|
995
|
-
container.show(this.vbox.contentElement, beforeElement);
|
|
996
|
-
this.expandableContainers.set(view.viewId(), container);
|
|
997
|
-
}
|
|
895
|
+
locationForView.set(view, this);
|
|
896
|
+
this.manager.views.set(view.viewId(), view);
|
|
897
|
+
this.stackedPane.appendView(view, insertBefore);
|
|
998
898
|
}
|
|
999
899
|
|
|
1000
900
|
override async showView(view: View, insertBefore?: View|null): Promise<void> {
|
|
1001
901
|
this.appendView(view, insertBefore);
|
|
1002
|
-
|
|
1003
|
-
if (container) {
|
|
1004
|
-
await container.expand();
|
|
1005
|
-
}
|
|
902
|
+
await this.stackedPane.expandView(view);
|
|
1006
903
|
}
|
|
1007
904
|
|
|
1008
905
|
override removeView(view: View): void {
|
|
1009
|
-
|
|
1010
|
-
if (!container) {
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
container.detach();
|
|
1015
|
-
this.expandableContainers.delete(view.viewId());
|
|
906
|
+
this.stackedPane.removeView(view);
|
|
1016
907
|
locationForView.delete(view);
|
|
1017
908
|
this.manager.views.delete(view.viewId());
|
|
1018
909
|
}
|
|
1019
910
|
|
|
1020
|
-
override isViewVisible(
|
|
1021
|
-
|
|
1022
|
-
throw new Error('not implemented');
|
|
911
|
+
override isViewVisible(view: View): boolean {
|
|
912
|
+
return this.#isVisible && this.stackedPane.isViewExpanded(view.viewId());
|
|
1023
913
|
}
|
|
1024
914
|
|
|
1025
915
|
appendApplicableItems(locationName: string): void {
|
|
@@ -41,6 +41,7 @@ import * as ShortcutRegistry from './ShortcutRegistry.js';
|
|
|
41
41
|
import * as SoftContextMenu from './SoftContextMenu.js';
|
|
42
42
|
import * as SoftDropDown from './SoftDropDown.js';
|
|
43
43
|
import * as SplitWidget from './SplitWidget.js';
|
|
44
|
+
import * as StackedPane from './StackedPane.js';
|
|
44
45
|
import * as SuggestBox from './SuggestBox.js';
|
|
45
46
|
import * as TabbedPane from './TabbedPane.js';
|
|
46
47
|
import * as TargetCrashedScreen from './TargetCrashedScreen.js';
|
|
@@ -95,6 +96,7 @@ export {
|
|
|
95
96
|
SoftContextMenu,
|
|
96
97
|
SoftDropDown,
|
|
97
98
|
SplitWidget,
|
|
99
|
+
StackedPane,
|
|
98
100
|
SuggestBox,
|
|
99
101
|
TabbedPane,
|
|
100
102
|
TargetCrashedScreen,
|
|
@@ -107,5 +109,5 @@ export {
|
|
|
107
109
|
View,
|
|
108
110
|
ViewManager,
|
|
109
111
|
Widget,
|
|
110
|
-
ZoomManager
|
|
112
|
+
ZoomManager,
|
|
111
113
|
};
|
package/package.json
CHANGED