chrome-devtools-frontend 1.0.1016605 → 1.0.1017938
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/config/gni/devtools_grd_files.gni +2 -0
- package/front_end/core/i18n/locales/en-US.json +6 -6
- package/front_end/core/i18n/locales/en-XL.json +6 -6
- package/front_end/core/sdk/DOMModel.ts +11 -0
- package/front_end/core/sdk/DebuggerModel.ts +4 -0
- package/front_end/core/sdk/FrameManager.ts +36 -15
- package/front_end/core/sdk/ResourceTreeModel.ts +88 -6
- package/front_end/core/sdk/Script.ts +1 -1
- package/front_end/core/sdk/SecurityOriginManager.ts +1 -1
- package/front_end/core/sdk/StorageKeyManager.ts +71 -0
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/entrypoints/formatter_worker/ScopeParser.ts +4 -2
- package/front_end/models/issues_manager/DeprecationIssue.ts +5 -2
- package/front_end/models/timeline_model/TimelineModel.ts +8 -6
- package/front_end/panels/application/ApplicationPanelSidebar.ts +5 -1
- package/front_end/panels/application/DOMStorageModel.ts +138 -10
- package/front_end/panels/application/StorageView.ts +64 -5
- package/front_end/panels/application/components/FrameDetailsView.ts +31 -5
- package/front_end/panels/elements/ElementsTreeElement.ts +25 -37
- package/front_end/panels/elements/ElementsTreeOutline.ts +44 -8
- package/front_end/panels/elements/TopLayerContainer.ts +97 -0
- package/front_end/panels/elements/components/AdornerManager.ts +7 -0
- package/front_end/panels/elements/elements.ts +4 -0
- package/front_end/panels/performance_monitor/PerformanceMonitor.ts +7 -0
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +5 -6
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +5 -3
- package/package.json +1 -1
@@ -43,6 +43,7 @@ import {ElementsPanel} from './ElementsPanel.js';
|
|
43
43
|
import {ElementsTreeElement, InitialChildrenLimit} from './ElementsTreeElement.js';
|
44
44
|
import elementsTreeOutlineStyles from './elementsTreeOutline.css.js';
|
45
45
|
import {ImagePreviewPopover} from './ImagePreviewPopover.js';
|
46
|
+
import {TopLayerContainer} from './TopLayerContainer.js';
|
46
47
|
|
47
48
|
import type {MarkerDecoratorRegistration} from './MarkerDecorator.js';
|
48
49
|
|
@@ -100,6 +101,7 @@ export class ElementsTreeOutline extends
|
|
100
101
|
private treeElementBeingDragged?: ElementsTreeElement;
|
101
102
|
private dragOverTreeElement?: ElementsTreeElement;
|
102
103
|
private updateModifiedNodesTimeout?: number;
|
104
|
+
private topLayerContainer?: TopLayerContainer;
|
103
105
|
|
104
106
|
constructor(omitRootDOMNode?: boolean, selectEnabled?: boolean, hideGutter?: boolean) {
|
105
107
|
super();
|
@@ -1001,6 +1003,7 @@ export class ElementsTreeOutline extends
|
|
1001
1003
|
domModel.addEventListener(SDK.DOMModel.Events.DocumentUpdated, this.documentUpdated, this);
|
1002
1004
|
domModel.addEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
|
1003
1005
|
domModel.addEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
|
1006
|
+
domModel.addEventListener(SDK.DOMModel.Events.TopLayerElementsChanged, this.topLayerElementsChanged, this);
|
1004
1007
|
}
|
1005
1008
|
|
1006
1009
|
unwireFromDOMModel(domModel: SDK.DOMModel.DOMModel): void {
|
@@ -1013,6 +1016,7 @@ export class ElementsTreeOutline extends
|
|
1013
1016
|
domModel.removeEventListener(SDK.DOMModel.Events.DocumentUpdated, this.documentUpdated, this);
|
1014
1017
|
domModel.removeEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
|
1015
1018
|
domModel.removeEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
|
1019
|
+
domModel.removeEventListener(SDK.DOMModel.Events.TopLayerElementsChanged, this.topLayerElementsChanged, this);
|
1016
1020
|
elementsTreeOutlineByDOMModel.delete(domModel);
|
1017
1021
|
}
|
1018
1022
|
|
@@ -1164,13 +1168,41 @@ export class ElementsTreeOutline extends
|
|
1164
1168
|
return Promise.resolve();
|
1165
1169
|
}
|
1166
1170
|
|
1167
|
-
return new Promise(resolve => {
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1171
|
+
return new Promise<void>(resolve => {
|
1172
|
+
treeElement.node().getChildNodes(() => {
|
1173
|
+
populatedTreeElements.add(treeElement);
|
1174
|
+
this.updateModifiedParentNode(treeElement.node());
|
1175
|
+
resolve();
|
1176
|
+
});
|
1177
|
+
})
|
1178
|
+
.then(() => {
|
1179
|
+
if (treeElement.node().nodeName() === 'BODY') {
|
1180
|
+
void this.createTopLayerContainer(treeElement);
|
1181
|
+
}
|
1182
|
+
});
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
async createTopLayerContainer(bodyElement: ElementsTreeElement): Promise<void> {
|
1186
|
+
if (!this.topLayerContainer) {
|
1187
|
+
this.topLayerContainer = new TopLayerContainer(bodyElement);
|
1188
|
+
}
|
1189
|
+
this.topLayerContainer.updateBody(bodyElement);
|
1190
|
+
await this.updateTopLayerContainer();
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
async updateTopLayerContainer(): Promise<void> {
|
1194
|
+
if (this.topLayerContainer) {
|
1195
|
+
const bodyElement = this.topLayerContainer.bodyElement;
|
1196
|
+
if (!bodyElement.children().includes(this.topLayerContainer) && !this.topLayerContainer.parent &&
|
1197
|
+
!this.topLayerContainer.treeOutline) {
|
1198
|
+
bodyElement.insertChild(this.topLayerContainer, bodyElement.childCount() - 1);
|
1199
|
+
}
|
1200
|
+
this.topLayerContainer.removeChildren();
|
1201
|
+
const topLayerElementsExists = await this.topLayerContainer.addTopLayerElementsAsChildren();
|
1202
|
+
if (!topLayerElementsExists) {
|
1203
|
+
bodyElement.removeChild(this.topLayerContainer);
|
1204
|
+
}
|
1205
|
+
}
|
1174
1206
|
}
|
1175
1207
|
|
1176
1208
|
private createElementTreeElement(node: SDK.DOMModel.DOMNode, isClosingTag?: boolean): ElementsTreeElement {
|
@@ -1318,7 +1350,7 @@ export class ElementsTreeOutline extends
|
|
1318
1350
|
}
|
1319
1351
|
|
1320
1352
|
insertChildElement(
|
1321
|
-
treeElement: ElementsTreeElement, child: SDK.DOMModel.DOMNode, index: number,
|
1353
|
+
treeElement: ElementsTreeElement|TopLayerContainer, child: SDK.DOMModel.DOMNode, index: number,
|
1322
1354
|
isClosingTag?: boolean): ElementsTreeElement {
|
1323
1355
|
const newElement = this.createElementTreeElement(child, isClosingTag);
|
1324
1356
|
treeElement.insertChild(newElement, index);
|
@@ -1427,6 +1459,10 @@ export class ElementsTreeOutline extends
|
|
1427
1459
|
}
|
1428
1460
|
}
|
1429
1461
|
|
1462
|
+
private async topLayerElementsChanged(): Promise<void> {
|
1463
|
+
await this.updateTopLayerContainer();
|
1464
|
+
}
|
1465
|
+
|
1430
1466
|
private static treeOutlineSymbol = Symbol('treeOutline');
|
1431
1467
|
}
|
1432
1468
|
|
@@ -0,0 +1,97 @@
|
|
1
|
+
// Copyright 2022 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
import * as i18n from '../../core/i18n/i18n.js';
|
5
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
6
|
+
import * as UI from '../../ui/legacy/legacy.js';
|
7
|
+
|
8
|
+
import * as ElementsComponents from './components/components.js';
|
9
|
+
import * as ElementsTreeOutline from './ElementsTreeOutline.js';
|
10
|
+
|
11
|
+
import type {ElementsTreeElement} from './ElementsTreeElement.js';
|
12
|
+
|
13
|
+
const UIStrings = {
|
14
|
+
/**
|
15
|
+
* @description Top layer is rendered closest to the user within a viewport, therefore its elements always appear on top of all other content
|
16
|
+
*/
|
17
|
+
topLayer: 'top-layer',
|
18
|
+
};
|
19
|
+
|
20
|
+
const str_ = i18n.i18n.registerUIStrings('panels/elements/TopLayerContainer.ts', UIStrings);
|
21
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
22
|
+
|
23
|
+
export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
24
|
+
treeOutline: ElementsTreeOutline.ElementsTreeOutline|null;
|
25
|
+
domModel: SDK.DOMModel.DOMModel;
|
26
|
+
currentTopLayerElements: Set<ElementsTreeElement>;
|
27
|
+
bodyElement: ElementsTreeElement;
|
28
|
+
|
29
|
+
constructor(bodyElement: ElementsTreeElement) {
|
30
|
+
super('#top-layer');
|
31
|
+
this.bodyElement = bodyElement;
|
32
|
+
this.domModel = bodyElement.node().domModel();
|
33
|
+
this.treeOutline = null;
|
34
|
+
this.currentTopLayerElements = new Set();
|
35
|
+
}
|
36
|
+
|
37
|
+
updateBody(bodyElement: ElementsTreeElement): void {
|
38
|
+
this.bodyElement = bodyElement;
|
39
|
+
}
|
40
|
+
|
41
|
+
async addTopLayerElementsAsChildren(): Promise<boolean> {
|
42
|
+
this.removeCurrentTopLayerElementsAdorners();
|
43
|
+
this.currentTopLayerElements = new Set();
|
44
|
+
const newTopLayerElementsIDs = await this.domModel.getTopLayerElements();
|
45
|
+
if (newTopLayerElementsIDs === null) {
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
let topLayerElementIndex = 0;
|
49
|
+
if (newTopLayerElementsIDs) {
|
50
|
+
for (const elementID of newTopLayerElementsIDs) {
|
51
|
+
const topLayerDOMNode = this.domModel.idToDOMNode.get(elementID);
|
52
|
+
// Will need to add support for backdrop in the future.
|
53
|
+
if (topLayerDOMNode && topLayerDOMNode.nodeName() !== '::backdrop') {
|
54
|
+
topLayerElementIndex++;
|
55
|
+
const topLayerElementShortcut = new SDK.DOMModel.DOMNodeShortcut(
|
56
|
+
this.domModel.target(), topLayerDOMNode.backendNodeId(), 0, topLayerDOMNode.nodeName());
|
57
|
+
const topLayerTreeElement = this.treeOutline?.treeElementByNode.get(topLayerDOMNode);
|
58
|
+
const topLayerElementRepresentation = new ElementsTreeOutline.ShortcutTreeElement(topLayerElementShortcut);
|
59
|
+
if (topLayerTreeElement && !this.currentTopLayerElements.has(topLayerTreeElement)) {
|
60
|
+
this.appendChild(topLayerElementRepresentation);
|
61
|
+
this.addTopLayerAdorner(topLayerTreeElement, topLayerElementRepresentation, topLayerElementIndex);
|
62
|
+
this.currentTopLayerElements.add(topLayerTreeElement);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
return topLayerElementIndex > 0;
|
68
|
+
}
|
69
|
+
|
70
|
+
private removeCurrentTopLayerElementsAdorners(): void {
|
71
|
+
for (const topLayerElement of this.currentTopLayerElements) {
|
72
|
+
topLayerElement.removeAllAdorners();
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
private addTopLayerAdorner(
|
77
|
+
element: ElementsTreeElement, topLayerElementRepresentation: ElementsTreeOutline.ShortcutTreeElement,
|
78
|
+
topLayerElementIndex: number): void {
|
79
|
+
const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
|
80
|
+
ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER);
|
81
|
+
const adornerContent = document.createElement('span');
|
82
|
+
adornerContent.textContent = ` top-layer (${topLayerElementIndex}) `;
|
83
|
+
const adorner = element?.adorn(config, adornerContent);
|
84
|
+
if (adorner) {
|
85
|
+
const onClick = (((): void => {
|
86
|
+
topLayerElementRepresentation.revealAndSelect();
|
87
|
+
}) as EventListener);
|
88
|
+
adorner.addInteraction(onClick, {
|
89
|
+
isToggle: false,
|
90
|
+
shouldPropagateOnKeydown: false,
|
91
|
+
ariaLabelDefault: i18nString(UIStrings.topLayer),
|
92
|
+
ariaLabelActive: i18nString(UIStrings.topLayer),
|
93
|
+
});
|
94
|
+
adorner.addEventListener('mousedown', e => e.consume(), false);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
@@ -30,6 +30,7 @@ export enum RegisteredAdorners {
|
|
30
30
|
SCROLL_SNAP = 'scroll-snap',
|
31
31
|
CONTAINER = 'container',
|
32
32
|
SLOT = 'slot',
|
33
|
+
TOP_LAYER = 'top-layer',
|
33
34
|
}
|
34
35
|
|
35
36
|
// This enum-like const object serves as the authoritative registry for all the
|
@@ -72,6 +73,12 @@ export function getRegisteredAdorner(which: RegisteredAdorners): RegisteredAdorn
|
|
72
73
|
category: AdornerCategories.LAYOUT,
|
73
74
|
enabledByDefault: true,
|
74
75
|
};
|
76
|
+
case RegisteredAdorners.TOP_LAYER:
|
77
|
+
return {
|
78
|
+
name: 'top-layer',
|
79
|
+
category: AdornerCategories.LAYOUT,
|
80
|
+
enabledByDefault: true,
|
81
|
+
};
|
75
82
|
}
|
76
83
|
}
|
77
84
|
|
@@ -9,6 +9,7 @@ import './DOMLinkifier.js';
|
|
9
9
|
import './DOMPath.js';
|
10
10
|
import './ElementsSidebarPane.js';
|
11
11
|
import './ElementsTreeElement.js';
|
12
|
+
import './TopLayerContainer.js';
|
12
13
|
import './ElementsTreeOutline.js';
|
13
14
|
import './EventListenersWidget.js';
|
14
15
|
import './MarkerDecorator.js';
|
@@ -25,6 +26,7 @@ import './ElementsPanel.js';
|
|
25
26
|
import './ClassesPaneWidget.js';
|
26
27
|
import './ElementStatePaneWidget.js';
|
27
28
|
import './ElementsTreeElementHighlighter.js';
|
29
|
+
import './TopLayerContainer.js';
|
28
30
|
|
29
31
|
import * as ClassesPaneWidget from './ClassesPaneWidget.js';
|
30
32
|
import * as ColorSwatchPopoverIcon from './ColorSwatchPopoverIcon.js';
|
@@ -53,6 +55,7 @@ import * as StylePropertyHighlighter from './StylePropertyHighlighter.js';
|
|
53
55
|
import * as StylePropertyTreeElement from './StylePropertyTreeElement.js';
|
54
56
|
import * as StylePropertyUtils from './StylePropertyUtils.js';
|
55
57
|
import * as StylesSidebarPane from './StylesSidebarPane.js';
|
58
|
+
import * as TopLayerContainer from './TopLayerContainer.js';
|
56
59
|
|
57
60
|
export {
|
58
61
|
ClassesPaneWidget,
|
@@ -82,4 +85,5 @@ export {
|
|
82
85
|
StylePropertyTreeElement,
|
83
86
|
StylePropertyUtils,
|
84
87
|
StylesSidebarPane,
|
88
|
+
TopLayerContainer,
|
85
89
|
};
|
@@ -116,6 +116,13 @@ export class PerformanceMonitorImpl extends UI.Widget.HBox implements
|
|
116
116
|
}
|
117
117
|
this.registerCSSFiles([performanceMonitorStyles]);
|
118
118
|
this.controlPane.instantiateMetricData();
|
119
|
+
const themeSupport = ThemeSupport.ThemeSupport.instance();
|
120
|
+
themeSupport.addEventListener(ThemeSupport.ThemeChangeEvent.eventName, () => {
|
121
|
+
// instantiateMetricData sets the colors for the metrics, which we need
|
122
|
+
// to re-evaluate when the theme changes before re-drawing the canvas.
|
123
|
+
this.controlPane.instantiateMetricData();
|
124
|
+
this.draw();
|
125
|
+
});
|
119
126
|
SDK.TargetManager.TargetManager.instance().addEventListener(
|
120
127
|
SDK.TargetManager.Events.SuspendStateChanged, this.suspendStateChanged, this);
|
121
128
|
void this.model.enable();
|
@@ -319,6 +319,6 @@ export class OpenLinearMemoryInspector extends UI.Widget.VBox implements UI.Cont
|
|
319
319
|
private async openMemoryInspector(obj: SDK.RemoteObject.RemoteObject): Promise<void> {
|
320
320
|
const controller = LinearMemoryInspector.LinearMemoryInspectorController.LinearMemoryInspectorController.instance();
|
321
321
|
Host.userMetrics.linearMemoryInspectorRevealedFrom(Host.UserMetrics.LinearMemoryInspectorRevealedFrom.ContextMenu);
|
322
|
-
void controller.openInspectorView(obj
|
322
|
+
void controller.openInspectorView(obj);
|
323
323
|
}
|
324
324
|
}
|
@@ -77,17 +77,16 @@ async function getBufferFromObject(obj: SDK.RemoteObject.RemoteObject): Promise<
|
|
77
77
|
return new SDK.RemoteObject.RemoteArrayBuffer(obj);
|
78
78
|
}
|
79
79
|
|
80
|
+
export function isDWARFMemoryObject(obj: SDK.RemoteObject.RemoteObject): boolean {
|
81
|
+
return obj instanceof Bindings.DebuggerLanguagePlugins.ValueNode && obj.inspectableAddress !== undefined;
|
82
|
+
}
|
83
|
+
|
80
84
|
export function isMemoryObjectProperty(obj: SDK.RemoteObject.RemoteObject): boolean {
|
81
85
|
const isWasmOrBuffer = obj.type === 'object' && obj.subtype && ACCEPTED_MEMORY_TYPES.includes(obj.subtype);
|
82
|
-
if (isWasmOrBuffer) {
|
86
|
+
if (isWasmOrBuffer || isDWARFMemoryObject(obj)) {
|
83
87
|
return true;
|
84
88
|
}
|
85
89
|
|
86
|
-
const isWasmDWARF = obj instanceof Bindings.DebuggerLanguagePlugins.ValueNode;
|
87
|
-
if (isWasmDWARF) {
|
88
|
-
return obj.inspectableAddress !== undefined;
|
89
|
-
}
|
90
|
-
|
91
90
|
return false;
|
92
91
|
}
|
93
92
|
|
@@ -388,11 +388,13 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
|
|
388
388
|
}
|
389
389
|
|
390
390
|
static appendMemoryIcon(element: Element, obj: SDK.RemoteObject.RemoteObject): void {
|
391
|
-
// We show the memory icon only on ArrayBuffer
|
391
|
+
// We show the memory icon only on ArrayBuffer, WebAssembly.Memory and DWARF memory instances.
|
392
392
|
// TypedArrays DataViews are also supported, but showing the icon next to their
|
393
393
|
// previews is quite a significant visual overhead, and users can easily get to
|
394
394
|
// their buffers and open the memory inspector from there.
|
395
|
-
|
395
|
+
const arrayBufferOrWasmMemory =
|
396
|
+
(obj.type === 'object' && (obj.subtype === 'arraybuffer' || obj.subtype === 'webassemblymemory'));
|
397
|
+
if (!arrayBufferOrWasmMemory && !LinearMemoryInspector.LinearMemoryInspectorController.isDWARFMemoryObject(obj)) {
|
396
398
|
return;
|
397
399
|
}
|
398
400
|
const memoryIcon = new IconButton.Icon.Icon();
|
@@ -408,7 +410,7 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
|
|
408
410
|
const controller =
|
409
411
|
LinearMemoryInspector.LinearMemoryInspectorController.LinearMemoryInspectorController.instance();
|
410
412
|
Host.userMetrics.linearMemoryInspectorRevealedFrom(Host.UserMetrics.LinearMemoryInspectorRevealedFrom.MemoryIcon);
|
411
|
-
void controller.openInspectorView(obj
|
413
|
+
void controller.openInspectorView(obj);
|
412
414
|
};
|
413
415
|
|
414
416
|
UI.Tooltip.Tooltip.install(memoryIcon, 'Reveal in Memory Inspector panel');
|
package/package.json
CHANGED