chrome-devtools-frontend 1.0.927127 → 1.0.928589
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/AUTHORS +1 -0
- package/config/gni/all_devtools_files.gni +0 -1
- package/config/gni/devtools_grd_files.gni +30 -4
- package/config/gni/devtools_image_files.gni +1 -0
- package/front_end/Images/src/ic_preview_feature.svg +3 -0
- package/front_end/Tests.js +2 -3
- package/front_end/core/common/Settings.ts +26 -45
- package/front_end/core/host/UserMetrics.ts +2 -2
- package/front_end/core/i18n/locales/en-US.json +60 -15
- package/front_end/core/i18n/locales/en-XL.json +60 -15
- package/front_end/core/platform/keyboard-utilities.ts +1 -0
- package/front_end/core/root/Runtime.ts +62 -61
- package/front_end/core/sdk/AccessibilityModel.ts +73 -73
- package/front_end/core/sdk/CPUProfileDataModel.ts +14 -14
- package/front_end/core/sdk/CPUProfilerModel.ts +33 -33
- package/front_end/core/sdk/CPUThrottlingManager.ts +8 -8
- package/front_end/core/sdk/CSSFontFace.ts +10 -10
- package/front_end/core/sdk/CSSMatchedStyles.ts +114 -114
- package/front_end/core/sdk/CSSMedia.ts +22 -22
- package/front_end/core/sdk/CSSMetadata.ts +53 -49
- package/front_end/core/sdk/CSSModel.ts +139 -135
- package/front_end/core/sdk/CSSProperty.ts +18 -18
- package/front_end/core/sdk/CSSRule.ts +15 -15
- package/front_end/core/sdk/CSSStyleDeclaration.ts +49 -47
- package/front_end/core/sdk/CSSStyleSheetHeader.ts +12 -12
- package/front_end/core/sdk/ChildTargetManager.ts +41 -40
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +10 -10
- package/front_end/core/sdk/Connections.ts +81 -81
- package/front_end/core/sdk/ConsoleModel.ts +68 -68
- package/front_end/core/sdk/Cookie.ts +48 -48
- package/front_end/core/sdk/CookieModel.ts +13 -13
- package/front_end/core/sdk/CookieParser.ts +45 -45
- package/front_end/core/sdk/DOMDebuggerModel.ts +131 -131
- package/front_end/core/sdk/DOMModel.ts +264 -252
- package/front_end/core/sdk/DebuggerModel.ts +209 -205
- package/front_end/core/sdk/EmulationModel.ts +76 -76
- package/front_end/core/sdk/FilmStripModel.ts +29 -29
- package/front_end/core/sdk/FrameManager.ts +43 -42
- package/front_end/core/sdk/HeapProfilerModel.ts +36 -36
- package/front_end/core/sdk/IsolateManager.ts +82 -82
- package/front_end/core/sdk/IssuesModel.ts +6 -6
- package/front_end/core/sdk/LayerTreeBase.ts +37 -37
- package/front_end/core/sdk/LogModel.ts +5 -5
- package/front_end/core/sdk/NetworkManager.ts +229 -225
- package/front_end/core/sdk/NetworkRequest.ts +368 -360
- package/front_end/core/sdk/OverlayColorGenerator.ts +9 -9
- package/front_end/core/sdk/OverlayModel.ts +155 -153
- package/front_end/core/sdk/OverlayPersistentHighlighter.ts +100 -101
- package/front_end/core/sdk/PageResourceLoader.ts +30 -30
- package/front_end/core/sdk/PaintProfiler.ts +16 -16
- package/front_end/core/sdk/PerformanceMetricsModel.ts +12 -12
- package/front_end/core/sdk/ProfileTreeModel.ts +3 -3
- package/front_end/core/sdk/RemoteObject.ts +108 -104
- package/front_end/core/sdk/Resource.ts +85 -84
- package/front_end/core/sdk/ResourceTreeModel.ts +150 -145
- package/front_end/core/sdk/RuntimeModel.ts +38 -34
- package/front_end/core/sdk/SDKModel.ts +3 -3
- package/front_end/core/sdk/ScreenCaptureModel.ts +19 -19
- package/front_end/core/sdk/Script.ts +29 -29
- package/front_end/core/sdk/SecurityOriginManager.ts +19 -19
- package/front_end/core/sdk/ServerTiming.ts +2 -2
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +43 -43
- package/front_end/core/sdk/ServiceWorkerManager.ts +72 -68
- package/front_end/core/sdk/SourceMap.ts +40 -36
- package/front_end/core/sdk/SourceMapManager.ts +57 -57
- package/front_end/core/sdk/Target.ts +64 -63
- package/front_end/core/sdk/TargetManager.ts +60 -56
- package/front_end/core/sdk/TracingManager.ts +39 -39
- package/front_end/core/sdk/TracingModel.ts +125 -125
- package/front_end/core/sdk/WebAuthnModel.ts +9 -9
- package/front_end/entrypoints/lighthouse_worker/{LighthouseService.js → LighthouseService.ts} +20 -45
- package/front_end/entrypoints/lighthouse_worker/{lighthouse_worker.js → lighthouse_worker.ts} +0 -0
- package/front_end/entrypoints/main/MainImpl.ts +7 -2
- package/front_end/legacy_test_runner/elements_test_runner/ElementsTestRunner.js +4 -4
- package/front_end/legacy_test_runner/sdk_test_runner/sdk_test_runner.js +1 -1
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +0 -6
- package/front_end/models/issues_manager/GenericIssue.ts +86 -0
- package/front_end/models/issues_manager/Issue.ts +24 -0
- package/front_end/models/issues_manager/IssuesManager.ts +18 -6
- package/front_end/models/issues_manager/descriptions/genericCrossOriginPortalPostMessageError.md +3 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +5422 -1
- package/front_end/panels/console/ConsoleSidebar.ts +0 -3
- package/front_end/panels/elements/ElementsTreeElement.ts +53 -61
- package/front_end/panels/elements/ElementsTreeOutline.ts +0 -1
- package/front_end/panels/elements/components/LayoutPane.ts +5 -1
- package/front_end/panels/issues/GenericIssueDetailsView.ts +68 -0
- package/front_end/panels/issues/IssueAggregator.ts +16 -0
- package/front_end/panels/issues/IssueKindView.ts +95 -0
- package/front_end/panels/issues/IssueView.ts +6 -0
- package/front_end/panels/issues/IssuesPane.ts +81 -18
- package/front_end/panels/issues/issuesTree.css +8 -3
- package/front_end/panels/lighthouse/LighthouseController.ts +3 -1
- package/front_end/panels/network/NetworkItemView.ts +1 -1
- package/front_end/panels/network/networkLogView.css +5 -0
- package/front_end/panels/sensors/LocationsSettingsTab.ts +1 -1
- package/front_end/panels/settings/SettingsScreen.ts +1 -0
- package/front_end/panels/settings/settingsScreen.css +24 -0
- package/front_end/panels/snippets/SnippetsQuickOpen.ts +8 -3
- package/front_end/panels/sources/TabbedEditorContainer.ts +1 -1
- package/front_end/panels/sources/sources-meta.ts +22 -7
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/package.json +4 -4
- package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +137 -0
- package/front_end/ui/components/code_highlighter/codeHighlighter.css +51 -0
- package/front_end/ui/components/code_highlighter/code_highlighter.ts +11 -0
- package/front_end/ui/components/docs/text_editor/basic.html +28 -0
- package/front_end/ui/components/docs/text_editor/basic.ts +14 -0
- package/front_end/ui/components/docs/text_prompt/basic.html +35 -0
- package/front_end/ui/components/docs/text_prompt/basic.ts +19 -0
- package/front_end/ui/components/issue_counter/IssueLinkIcon.ts +1 -0
- package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +17 -0
- package/front_end/ui/components/request_link_icon/RequestLinkIcon.ts +1 -0
- package/front_end/ui/components/text_editor/TextEditor.ts +161 -0
- package/front_end/ui/components/text_editor/config.ts +264 -0
- package/front_end/{panels/console/components/components.ts → ui/components/text_editor/text_editor.ts} +2 -5
- package/front_end/ui/components/text_editor/theme.ts +113 -0
- package/front_end/ui/components/text_prompt/TextPrompt.ts +144 -0
- package/front_end/ui/components/text_prompt/textPrompt.css +33 -0
- package/front_end/ui/components/text_prompt/text_prompt.ts +9 -0
- package/front_end/ui/legacy/ARIAUtils.ts +14 -11
- package/front_end/ui/legacy/TabbedPane.ts +32 -3
- package/front_end/ui/legacy/UIUtils.ts +3 -1
- package/front_end/ui/legacy/View.ts +6 -0
- package/front_end/ui/legacy/ViewManager.ts +5 -1
- package/front_end/ui/legacy/ViewRegistration.ts +5 -0
- package/front_end/ui/legacy/XLink.ts +1 -1
- package/front_end/ui/legacy/closeButton.css +6 -0
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +8 -3
- package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +38 -38
- package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +10 -4
- package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +23 -6
- package/front_end/ui/legacy/components/quick_open/filteredListWidget.css +14 -16
- package/front_end/ui/legacy/filter.css +1 -0
- package/front_end/ui/legacy/tabbedPane.css +24 -0
- package/front_end/ui/legacy/toolbar.css +5 -0
- package/inspector_overlay/main.ts +2 -1
- package/inspector_overlay/tool_screenshot.ts +8 -1
- package/package.json +1 -1
- package/scripts/build/rollup.config.js +9 -0
- package/scripts/migration/class-fields/migrate.js +56 -0
- package/scripts/migration/class-fields/package.json +5 -0
- package/front_end/panels/console/components/SidebarDeprecation.ts +0 -58
- package/front_end/panels/console/components/sidebarDeprecation.css +0 -17
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* copyright notice, this list of conditions and the following disclaimer
|
|
17
17
|
* in the documentation and/or other materials provided with the
|
|
18
18
|
* distribution.
|
|
19
|
-
* * Neither the name of Google Inc. nor the names of its
|
|
19
|
+
* * Neither the #name of Google Inc. nor the names of its
|
|
20
20
|
* contributors may be used to endorse or promote products derived from
|
|
21
21
|
* this software without specific prior written permission.
|
|
22
22
|
*
|
|
@@ -52,31 +52,31 @@ import {TargetManager} from './TargetManager.js';
|
|
|
52
52
|
import {ResourceTreeModel} from './ResourceTreeModel.js';
|
|
53
53
|
|
|
54
54
|
export class DOMNode {
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
#domModelInternal: DOMModel;
|
|
56
|
+
#agent: ProtocolProxyApi.DOMApi;
|
|
57
57
|
ownerDocument!: DOMDocument|null;
|
|
58
|
-
|
|
58
|
+
#isInShadowTreeInternal!: boolean;
|
|
59
59
|
id!: Protocol.DOM.NodeId;
|
|
60
60
|
index: number|undefined;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
#backendNodeIdInternal!: Protocol.DOM.BackendNodeId;
|
|
62
|
+
#nodeTypeInternal!: number;
|
|
63
|
+
#nodeNameInternal!: string;
|
|
64
|
+
#localNameInternal!: string;
|
|
65
65
|
nodeValueInternal!: string;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
#pseudoTypeInternal!: Protocol.DOM.PseudoType|undefined;
|
|
67
|
+
#shadowRootTypeInternal!: Protocol.DOM.ShadowRootType|undefined;
|
|
68
|
+
#frameOwnerFrameIdInternal!: Protocol.Page.FrameId|null;
|
|
69
|
+
#xmlVersion!: string|undefined;
|
|
70
|
+
#isSVGNodeInternal!: boolean;
|
|
71
|
+
#creationStackTraceInternal: Promise<Protocol.Runtime.StackTrace|null>|null;
|
|
72
72
|
pseudoElementsInternal: Map<string, DOMNode>;
|
|
73
|
-
|
|
73
|
+
#distributedNodesInternal: DOMNodeShortcut[];
|
|
74
74
|
readonly shadowRootsInternal: DOMNode[];
|
|
75
|
-
|
|
75
|
+
#attributesInternal: Map<string, Attribute>;
|
|
76
76
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
77
77
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
#markers: Map<string, any>;
|
|
79
|
+
#subtreeMarkerCount: number;
|
|
80
80
|
childNodeCountInternal!: number;
|
|
81
81
|
childrenInternal: DOMNode[]|null;
|
|
82
82
|
nextSibling: DOMNode|null;
|
|
@@ -86,8 +86,8 @@ export class DOMNode {
|
|
|
86
86
|
parentNode: DOMNode|null;
|
|
87
87
|
templateContentInternal?: DOMNode;
|
|
88
88
|
contentDocumentInternal?: DOMDocument;
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
childDocumentPromiseForTesting?: Promise<DOMDocument|null>;
|
|
90
|
+
#importedDocumentInternal?: DOMNode;
|
|
91
91
|
publicId?: string;
|
|
92
92
|
systemId?: string;
|
|
93
93
|
internalSubset?: string;
|
|
@@ -95,16 +95,16 @@ export class DOMNode {
|
|
|
95
95
|
value?: string;
|
|
96
96
|
|
|
97
97
|
constructor(domModel: DOMModel) {
|
|
98
|
-
this
|
|
99
|
-
this
|
|
98
|
+
this.#domModelInternal = domModel;
|
|
99
|
+
this.#agent = this.#domModelInternal.getAgent();
|
|
100
100
|
this.index = undefined;
|
|
101
|
-
this
|
|
101
|
+
this.#creationStackTraceInternal = null;
|
|
102
102
|
this.pseudoElementsInternal = new Map();
|
|
103
|
-
this
|
|
103
|
+
this.#distributedNodesInternal = [];
|
|
104
104
|
this.shadowRootsInternal = [];
|
|
105
|
-
this
|
|
106
|
-
this
|
|
107
|
-
this
|
|
105
|
+
this.#attributesInternal = new Map();
|
|
106
|
+
this.#markers = new Map();
|
|
107
|
+
this.#subtreeMarkerCount = 0;
|
|
108
108
|
this.childrenInternal = null;
|
|
109
109
|
this.nextSibling = null;
|
|
110
110
|
this.previousSibling = null;
|
|
@@ -121,22 +121,22 @@ export class DOMNode {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
init(doc: DOMDocument|null, isInShadowTree: boolean, payload: Protocol.DOM.Node): void {
|
|
124
|
-
this
|
|
124
|
+
this.#agent = this.#domModelInternal.getAgent();
|
|
125
125
|
this.ownerDocument = doc;
|
|
126
|
-
this
|
|
126
|
+
this.#isInShadowTreeInternal = isInShadowTree;
|
|
127
127
|
|
|
128
128
|
this.id = payload.nodeId;
|
|
129
|
-
this
|
|
130
|
-
this
|
|
131
|
-
this
|
|
132
|
-
this
|
|
133
|
-
this
|
|
129
|
+
this.#backendNodeIdInternal = payload.backendNodeId;
|
|
130
|
+
this.#domModelInternal.registerNode(this);
|
|
131
|
+
this.#nodeTypeInternal = payload.nodeType;
|
|
132
|
+
this.#nodeNameInternal = payload.nodeName;
|
|
133
|
+
this.#localNameInternal = payload.localName;
|
|
134
134
|
this.nodeValueInternal = payload.nodeValue;
|
|
135
|
-
this
|
|
136
|
-
this
|
|
137
|
-
this
|
|
138
|
-
this
|
|
139
|
-
this
|
|
135
|
+
this.#pseudoTypeInternal = payload.pseudoType;
|
|
136
|
+
this.#shadowRootTypeInternal = payload.shadowRootType;
|
|
137
|
+
this.#frameOwnerFrameIdInternal = payload.frameId || null;
|
|
138
|
+
this.#xmlVersion = payload.xmlVersion;
|
|
139
|
+
this.#isSVGNodeInternal = Boolean(payload.isSVG);
|
|
140
140
|
|
|
141
141
|
if (payload.attributes) {
|
|
142
142
|
this.setAttributesPayload(payload.attributes);
|
|
@@ -146,7 +146,7 @@ export class DOMNode {
|
|
|
146
146
|
if (payload.shadowRoots) {
|
|
147
147
|
for (let i = 0; i < payload.shadowRoots.length; ++i) {
|
|
148
148
|
const root = payload.shadowRoots[i];
|
|
149
|
-
const node = DOMNode.create(this
|
|
149
|
+
const node = DOMNode.create(this.#domModelInternal, this.ownerDocument, true, root);
|
|
150
150
|
this.shadowRootsInternal.push(node);
|
|
151
151
|
node.parentNode = this;
|
|
152
152
|
}
|
|
@@ -154,26 +154,26 @@ export class DOMNode {
|
|
|
154
154
|
|
|
155
155
|
if (payload.templateContent) {
|
|
156
156
|
this.templateContentInternal =
|
|
157
|
-
DOMNode.create(this
|
|
157
|
+
DOMNode.create(this.#domModelInternal, this.ownerDocument, true, payload.templateContent);
|
|
158
158
|
this.templateContentInternal.parentNode = this;
|
|
159
159
|
this.childrenInternal = [];
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
if (payload.contentDocument) {
|
|
163
|
-
this.contentDocumentInternal = new DOMDocument(this
|
|
163
|
+
this.contentDocumentInternal = new DOMDocument(this.#domModelInternal, payload.contentDocument);
|
|
164
164
|
this.contentDocumentInternal.parentNode = this;
|
|
165
165
|
this.childrenInternal = [];
|
|
166
166
|
} else if ((payload.nodeName === 'IFRAME' || payload.nodeName === 'PORTAL') && payload.frameId) {
|
|
167
|
-
// At this point we know we are in an OOPIF, otherwise payload.contentDocument would have been set.
|
|
167
|
+
// At this point we know we are in an OOPIF, otherwise #payload.contentDocument would have been set.
|
|
168
168
|
this.childDocumentPromiseForTesting =
|
|
169
|
-
this.createChildDocumentPromiseForTesting(payload.frameId, this
|
|
169
|
+
this.createChildDocumentPromiseForTesting(payload.frameId, this.#domModelInternal.target());
|
|
170
170
|
this.childrenInternal = [];
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
if (payload.importedDocument) {
|
|
174
|
-
this
|
|
175
|
-
DOMNode.create(this
|
|
176
|
-
this
|
|
174
|
+
this.#importedDocumentInternal =
|
|
175
|
+
DOMNode.create(this.#domModelInternal, this.ownerDocument, true, payload.importedDocument);
|
|
176
|
+
this.#importedDocumentInternal.parentNode = this;
|
|
177
177
|
this.childrenInternal = [];
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -187,19 +187,19 @@ export class DOMNode {
|
|
|
187
187
|
|
|
188
188
|
this.setPseudoElements(payload.pseudoElements);
|
|
189
189
|
|
|
190
|
-
if (this
|
|
190
|
+
if (this.#nodeTypeInternal === Node.ELEMENT_NODE) {
|
|
191
191
|
// HTML and BODY from internal iframes should not overwrite top-level ones.
|
|
192
|
-
if (this.ownerDocument && !this.ownerDocument.documentElement && this
|
|
192
|
+
if (this.ownerDocument && !this.ownerDocument.documentElement && this.#nodeNameInternal === 'HTML') {
|
|
193
193
|
this.ownerDocument.documentElement = this;
|
|
194
194
|
}
|
|
195
|
-
if (this.ownerDocument && !this.ownerDocument.body && this
|
|
195
|
+
if (this.ownerDocument && !this.ownerDocument.body && this.#nodeNameInternal === 'BODY') {
|
|
196
196
|
this.ownerDocument.body = this;
|
|
197
197
|
}
|
|
198
|
-
} else if (this
|
|
198
|
+
} else if (this.#nodeTypeInternal === Node.DOCUMENT_TYPE_NODE) {
|
|
199
199
|
this.publicId = payload.publicId;
|
|
200
200
|
this.systemId = payload.systemId;
|
|
201
201
|
this.internalSubset = payload.internalSubset;
|
|
202
|
-
} else if (this
|
|
202
|
+
} else if (this.#nodeTypeInternal === Node.ATTRIBUTE_NODE) {
|
|
203
203
|
this.name = payload.name;
|
|
204
204
|
this.value = payload.value;
|
|
205
205
|
}
|
|
@@ -216,8 +216,8 @@ export class DOMNode {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
isAdFrameNode(): boolean {
|
|
219
|
-
if (this.isIframe() && this
|
|
220
|
-
const frame = FrameManager.instance().getFrame(this
|
|
219
|
+
if (this.isIframe() && this.#frameOwnerFrameIdInternal) {
|
|
220
|
+
const frame = FrameManager.instance().getFrame(this.#frameOwnerFrameIdInternal);
|
|
221
221
|
if (!frame) {
|
|
222
222
|
return false;
|
|
223
223
|
}
|
|
@@ -227,25 +227,29 @@ export class DOMNode {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
isSVGNode(): boolean {
|
|
230
|
-
return this
|
|
230
|
+
return this.#isSVGNodeInternal;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
creationStackTrace(): Promise<Protocol.Runtime.StackTrace|null> {
|
|
234
|
-
if (this
|
|
235
|
-
return this
|
|
234
|
+
if (this.#creationStackTraceInternal) {
|
|
235
|
+
return this.#creationStackTraceInternal;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
const stackTracesPromise = this
|
|
239
|
-
this
|
|
240
|
-
return this
|
|
238
|
+
const stackTracesPromise = this.#agent.invoke_getNodeStackTraces({nodeId: this.id});
|
|
239
|
+
this.#creationStackTraceInternal = stackTracesPromise.then(res => res.creation || null);
|
|
240
|
+
return this.#creationStackTraceInternal;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
get subtreeMarkerCount(): number {
|
|
244
|
+
return this.#subtreeMarkerCount;
|
|
241
245
|
}
|
|
242
246
|
|
|
243
247
|
domModel(): DOMModel {
|
|
244
|
-
return this
|
|
248
|
+
return this.#domModelInternal;
|
|
245
249
|
}
|
|
246
250
|
|
|
247
251
|
backendNodeId(): Protocol.DOM.BackendNodeId {
|
|
248
|
-
return this
|
|
252
|
+
return this.#backendNodeIdInternal;
|
|
249
253
|
}
|
|
250
254
|
|
|
251
255
|
children(): DOMNode[]|null {
|
|
@@ -257,7 +261,7 @@ export class DOMNode {
|
|
|
257
261
|
}
|
|
258
262
|
|
|
259
263
|
hasAttributes(): boolean {
|
|
260
|
-
return this
|
|
264
|
+
return this.#attributesInternal.size > 0;
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
childNodeCount(): number {
|
|
@@ -289,27 +293,27 @@ export class DOMNode {
|
|
|
289
293
|
}
|
|
290
294
|
|
|
291
295
|
isIframe(): boolean {
|
|
292
|
-
return this
|
|
296
|
+
return this.#nodeNameInternal === 'IFRAME';
|
|
293
297
|
}
|
|
294
298
|
|
|
295
299
|
isPortal(): boolean {
|
|
296
|
-
return this
|
|
300
|
+
return this.#nodeNameInternal === 'PORTAL';
|
|
297
301
|
}
|
|
298
302
|
|
|
299
303
|
importedDocument(): DOMNode|null {
|
|
300
|
-
return this
|
|
304
|
+
return this.#importedDocumentInternal || null;
|
|
301
305
|
}
|
|
302
306
|
|
|
303
307
|
nodeType(): number {
|
|
304
|
-
return this
|
|
308
|
+
return this.#nodeTypeInternal;
|
|
305
309
|
}
|
|
306
310
|
|
|
307
311
|
nodeName(): string {
|
|
308
|
-
return this
|
|
312
|
+
return this.#nodeNameInternal;
|
|
309
313
|
}
|
|
310
314
|
|
|
311
315
|
pseudoType(): string|undefined {
|
|
312
|
-
return this
|
|
316
|
+
return this.#pseudoTypeInternal;
|
|
313
317
|
}
|
|
314
318
|
|
|
315
319
|
hasPseudoElements(): boolean {
|
|
@@ -343,15 +347,16 @@ export class DOMNode {
|
|
|
343
347
|
|
|
344
348
|
isInsertionPoint(): boolean {
|
|
345
349
|
return !this.isXMLNode() &&
|
|
346
|
-
(this
|
|
350
|
+
(this.#nodeNameInternal === 'SHADOW' || this.#nodeNameInternal === 'CONTENT' ||
|
|
351
|
+
this.#nodeNameInternal === 'SLOT');
|
|
347
352
|
}
|
|
348
353
|
|
|
349
354
|
distributedNodes(): DOMNodeShortcut[] {
|
|
350
|
-
return this
|
|
355
|
+
return this.#distributedNodesInternal;
|
|
351
356
|
}
|
|
352
357
|
|
|
353
358
|
isInShadowTree(): boolean {
|
|
354
|
-
return this
|
|
359
|
+
return this.#isInShadowTreeInternal;
|
|
355
360
|
}
|
|
356
361
|
|
|
357
362
|
ancestorShadowHost(): DOMNode|null {
|
|
@@ -360,7 +365,7 @@ export class DOMNode {
|
|
|
360
365
|
}
|
|
361
366
|
|
|
362
367
|
ancestorShadowRoot(): DOMNode|null {
|
|
363
|
-
if (!this
|
|
368
|
+
if (!this.#isInShadowTreeInternal) {
|
|
364
369
|
return null;
|
|
365
370
|
}
|
|
366
371
|
|
|
@@ -380,11 +385,11 @@ export class DOMNode {
|
|
|
380
385
|
}
|
|
381
386
|
|
|
382
387
|
isShadowRoot(): boolean {
|
|
383
|
-
return Boolean(this
|
|
388
|
+
return Boolean(this.#shadowRootTypeInternal);
|
|
384
389
|
}
|
|
385
390
|
|
|
386
391
|
shadowRootType(): string|null {
|
|
387
|
-
return this
|
|
392
|
+
return this.#shadowRootTypeInternal || null;
|
|
388
393
|
}
|
|
389
394
|
|
|
390
395
|
nodeNameInCorrectCase(): string {
|
|
@@ -393,7 +398,7 @@ export class DOMNode {
|
|
|
393
398
|
return '#shadow-root (' + shadowRootType + ')';
|
|
394
399
|
}
|
|
395
400
|
|
|
396
|
-
// If there is no local name, it's case sensitive
|
|
401
|
+
// If there is no local #name, it's case sensitive
|
|
397
402
|
if (!this.localName()) {
|
|
398
403
|
return this.nodeName();
|
|
399
404
|
}
|
|
@@ -412,18 +417,18 @@ export class DOMNode {
|
|
|
412
417
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
413
418
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
414
419
|
callback?: ((arg0: string|null, arg1: DOMNode|null) => any)): void {
|
|
415
|
-
this
|
|
420
|
+
this.#agent.invoke_setNodeName({nodeId: this.id, name}).then(response => {
|
|
416
421
|
if (!response.getError()) {
|
|
417
|
-
this
|
|
422
|
+
this.#domModelInternal.markUndoableState();
|
|
418
423
|
}
|
|
419
424
|
if (callback) {
|
|
420
|
-
callback(response.getError() || null, this
|
|
425
|
+
callback(response.getError() || null, this.#domModelInternal.nodeForId(response.nodeId));
|
|
421
426
|
}
|
|
422
427
|
});
|
|
423
428
|
}
|
|
424
429
|
|
|
425
430
|
localName(): string {
|
|
426
|
-
return this
|
|
431
|
+
return this.#localNameInternal;
|
|
427
432
|
}
|
|
428
433
|
|
|
429
434
|
nodeValue(): string {
|
|
@@ -437,9 +442,9 @@ export class DOMNode {
|
|
|
437
442
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
438
443
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
439
444
|
setNodeValue(value: string, callback?: ((arg0: string|null) => any)): void {
|
|
440
|
-
this
|
|
445
|
+
this.#agent.invoke_setNodeValue({nodeId: this.id, value}).then(response => {
|
|
441
446
|
if (!response.getError()) {
|
|
442
|
-
this
|
|
447
|
+
this.#domModelInternal.markUndoableState();
|
|
443
448
|
}
|
|
444
449
|
if (callback) {
|
|
445
450
|
callback(response.getError() || null);
|
|
@@ -448,7 +453,7 @@ export class DOMNode {
|
|
|
448
453
|
}
|
|
449
454
|
|
|
450
455
|
getAttribute(name: string): string|undefined {
|
|
451
|
-
const attr = this
|
|
456
|
+
const attr = this.#attributesInternal.get(name);
|
|
452
457
|
return attr ? attr.value : undefined;
|
|
453
458
|
}
|
|
454
459
|
|
|
@@ -457,9 +462,9 @@ export class DOMNode {
|
|
|
457
462
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
458
463
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
459
464
|
callback?: ((arg0: string|null) => any)): void {
|
|
460
|
-
this
|
|
465
|
+
this.#agent.invoke_setAttributesAsText({nodeId: this.id, text, name}).then(response => {
|
|
461
466
|
if (!response.getError()) {
|
|
462
|
-
this
|
|
467
|
+
this.#domModelInternal.markUndoableState();
|
|
463
468
|
}
|
|
464
469
|
if (callback) {
|
|
465
470
|
callback(response.getError() || null);
|
|
@@ -472,9 +477,9 @@ export class DOMNode {
|
|
|
472
477
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
473
478
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
474
479
|
callback?: ((arg0: string|null) => any)): void {
|
|
475
|
-
this
|
|
480
|
+
this.#agent.invoke_setAttributeValue({nodeId: this.id, name, value}).then(response => {
|
|
476
481
|
if (!response.getError()) {
|
|
477
|
-
this
|
|
482
|
+
this.#domModelInternal.markUndoableState();
|
|
478
483
|
}
|
|
479
484
|
if (callback) {
|
|
480
485
|
callback(response.getError() || null);
|
|
@@ -487,16 +492,16 @@ export class DOMNode {
|
|
|
487
492
|
}
|
|
488
493
|
|
|
489
494
|
attributes(): Attribute[] {
|
|
490
|
-
return [...this
|
|
495
|
+
return [...this.#attributesInternal.values()];
|
|
491
496
|
}
|
|
492
497
|
|
|
493
498
|
async removeAttribute(name: string): Promise<void> {
|
|
494
|
-
const response = await this
|
|
499
|
+
const response = await this.#agent.invoke_removeAttribute({nodeId: this.id, name});
|
|
495
500
|
if (response.getError()) {
|
|
496
501
|
return;
|
|
497
502
|
}
|
|
498
|
-
this
|
|
499
|
-
this
|
|
503
|
+
this.#attributesInternal.delete(name);
|
|
504
|
+
this.#domModelInternal.markUndoableState();
|
|
500
505
|
}
|
|
501
506
|
|
|
502
507
|
getChildNodes(callback: (arg0: Array<DOMNode>|null) => void): void {
|
|
@@ -504,27 +509,27 @@ export class DOMNode {
|
|
|
504
509
|
callback(this.children());
|
|
505
510
|
return;
|
|
506
511
|
}
|
|
507
|
-
this
|
|
512
|
+
this.#agent.invoke_requestChildNodes({nodeId: this.id}).then(response => {
|
|
508
513
|
callback(response.getError() ? null : this.children());
|
|
509
514
|
});
|
|
510
515
|
}
|
|
511
516
|
|
|
512
517
|
async getSubtree(depth: number, pierce: boolean): Promise<DOMNode[]|null> {
|
|
513
|
-
const response = await this
|
|
518
|
+
const response = await this.#agent.invoke_requestChildNodes({nodeId: this.id, depth: depth, pierce: pierce});
|
|
514
519
|
return response.getError() ? null : this.childrenInternal;
|
|
515
520
|
}
|
|
516
521
|
|
|
517
522
|
async getOuterHTML(): Promise<string|null> {
|
|
518
|
-
const {outerHTML} = await this
|
|
523
|
+
const {outerHTML} = await this.#agent.invoke_getOuterHTML({nodeId: this.id});
|
|
519
524
|
return outerHTML;
|
|
520
525
|
}
|
|
521
526
|
|
|
522
527
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
523
528
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
524
529
|
setOuterHTML(html: string, callback?: ((arg0: string|null) => any)): void {
|
|
525
|
-
this
|
|
530
|
+
this.#agent.invoke_setOuterHTML({nodeId: this.id, outerHTML: html}).then(response => {
|
|
526
531
|
if (!response.getError()) {
|
|
527
|
-
this
|
|
532
|
+
this.#domModelInternal.markUndoableState();
|
|
528
533
|
}
|
|
529
534
|
if (callback) {
|
|
530
535
|
callback(response.getError() || null);
|
|
@@ -536,9 +541,9 @@ export class DOMNode {
|
|
|
536
541
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
537
542
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
538
543
|
(arg0: string|null, arg1?: Protocol.DOM.NodeId|undefined) => any)): Promise<void> {
|
|
539
|
-
return this
|
|
544
|
+
return this.#agent.invoke_removeNode({nodeId: this.id}).then(response => {
|
|
540
545
|
if (!response.getError()) {
|
|
541
|
-
this
|
|
546
|
+
this.#domModelInternal.markUndoableState();
|
|
542
547
|
}
|
|
543
548
|
if (callback) {
|
|
544
549
|
callback(response.getError() || null);
|
|
@@ -547,7 +552,7 @@ export class DOMNode {
|
|
|
547
552
|
}
|
|
548
553
|
|
|
549
554
|
async copyNode(): Promise<string|null> {
|
|
550
|
-
const {outerHTML} = await this
|
|
555
|
+
const {outerHTML} = await this.#agent.invoke_getOuterHTML({nodeId: this.id});
|
|
551
556
|
if (outerHTML !== null) {
|
|
552
557
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(outerHTML);
|
|
553
558
|
}
|
|
@@ -556,7 +561,7 @@ export class DOMNode {
|
|
|
556
561
|
|
|
557
562
|
path(): string {
|
|
558
563
|
function canPush(node: DOMNode): number|false|null {
|
|
559
|
-
return (node.index !== undefined || (node.isShadowRoot() && node.parentNode)) && node
|
|
564
|
+
return (node.index !== undefined || (node.isShadowRoot() && node.parentNode)) && node.#nodeNameInternal.length;
|
|
560
565
|
}
|
|
561
566
|
|
|
562
567
|
const path = [];
|
|
@@ -565,7 +570,7 @@ export class DOMNode {
|
|
|
565
570
|
const index = typeof node.index === 'number' ?
|
|
566
571
|
node.index :
|
|
567
572
|
(node.shadowRootType() === DOMNode.ShadowRootTypes.UserAgent ? 'u' : 'a');
|
|
568
|
-
path.push([index, node
|
|
573
|
+
path.push([index, node.#nodeNameInternal]);
|
|
569
574
|
node = node.parentNode;
|
|
570
575
|
}
|
|
571
576
|
path.reverse();
|
|
@@ -592,22 +597,23 @@ export class DOMNode {
|
|
|
592
597
|
}
|
|
593
598
|
|
|
594
599
|
frameOwnerFrameId(): Protocol.Page.FrameId|null {
|
|
595
|
-
return this
|
|
600
|
+
return this.#frameOwnerFrameIdInternal;
|
|
596
601
|
}
|
|
597
602
|
|
|
598
603
|
frameId(): Protocol.Page.FrameId|null {
|
|
599
604
|
let node: DOMNode = this.parentNode || this;
|
|
600
|
-
while (!node
|
|
605
|
+
while (!node.#frameOwnerFrameIdInternal && node.parentNode) {
|
|
601
606
|
node = node.parentNode;
|
|
602
607
|
}
|
|
603
|
-
return node
|
|
608
|
+
return node.#frameOwnerFrameIdInternal;
|
|
604
609
|
}
|
|
605
610
|
|
|
606
611
|
setAttributesPayload(attrs: string[]): boolean {
|
|
607
|
-
let attributesChanged: true|boolean =
|
|
608
|
-
|
|
612
|
+
let attributesChanged: true|boolean =
|
|
613
|
+
!this.#attributesInternal || attrs.length !== this.#attributesInternal.size * 2;
|
|
614
|
+
const oldAttributesMap = this.#attributesInternal || new Map();
|
|
609
615
|
|
|
610
|
-
this
|
|
616
|
+
this.#attributesInternal = new Map();
|
|
611
617
|
|
|
612
618
|
for (let i = 0; i < attrs.length; i += 2) {
|
|
613
619
|
const name = attrs[i];
|
|
@@ -630,7 +636,7 @@ export class DOMNode {
|
|
|
630
636
|
if (!this.childrenInternal) {
|
|
631
637
|
throw new Error('DOMNode._children is expected to not be null.');
|
|
632
638
|
}
|
|
633
|
-
const node = DOMNode.create(this
|
|
639
|
+
const node = DOMNode.create(this.#domModelInternal, this.ownerDocument, this.#isInShadowTreeInternal, payload);
|
|
634
640
|
this.childrenInternal.splice(prev ? this.childrenInternal.indexOf(prev) + 1 : 0, 0, node);
|
|
635
641
|
this.renumber();
|
|
636
642
|
return node;
|
|
@@ -655,9 +661,9 @@ export class DOMNode {
|
|
|
655
661
|
}
|
|
656
662
|
}
|
|
657
663
|
node.parentNode = null;
|
|
658
|
-
this
|
|
659
|
-
if (node
|
|
660
|
-
this
|
|
664
|
+
this.#subtreeMarkerCount -= node.#subtreeMarkerCount;
|
|
665
|
+
if (node.#subtreeMarkerCount) {
|
|
666
|
+
this.#domModelInternal.dispatchEventToListeners(Events.MarkersChanged, this);
|
|
661
667
|
}
|
|
662
668
|
this.renumber();
|
|
663
669
|
}
|
|
@@ -666,7 +672,7 @@ export class DOMNode {
|
|
|
666
672
|
this.childrenInternal = [];
|
|
667
673
|
for (let i = 0; i < payloads.length; ++i) {
|
|
668
674
|
const payload = payloads[i];
|
|
669
|
-
const node = DOMNode.create(this
|
|
675
|
+
const node = DOMNode.create(this.#domModelInternal, this.ownerDocument, this.#isInShadowTreeInternal, payload);
|
|
670
676
|
this.childrenInternal.push(node);
|
|
671
677
|
}
|
|
672
678
|
this.renumber();
|
|
@@ -678,7 +684,8 @@ export class DOMNode {
|
|
|
678
684
|
}
|
|
679
685
|
|
|
680
686
|
for (let i = 0; i < payloads.length; ++i) {
|
|
681
|
-
const node =
|
|
687
|
+
const node =
|
|
688
|
+
DOMNode.create(this.#domModelInternal, this.ownerDocument, this.#isInShadowTreeInternal, payloads[i]);
|
|
682
689
|
node.parentNode = this;
|
|
683
690
|
const pseudoType = node.pseudoType();
|
|
684
691
|
if (!pseudoType) {
|
|
@@ -689,10 +696,10 @@ export class DOMNode {
|
|
|
689
696
|
}
|
|
690
697
|
|
|
691
698
|
setDistributedNodePayloads(payloads: Protocol.DOM.BackendNode[]): void {
|
|
692
|
-
this
|
|
699
|
+
this.#distributedNodesInternal = [];
|
|
693
700
|
for (const payload of payloads) {
|
|
694
|
-
this
|
|
695
|
-
this
|
|
701
|
+
this.#distributedNodesInternal.push(new DOMNodeShortcut(
|
|
702
|
+
this.#domModelInternal.target(), payload.backendNodeId, payload.nodeType, payload.nodeName));
|
|
696
703
|
}
|
|
697
704
|
}
|
|
698
705
|
|
|
@@ -719,11 +726,11 @@ export class DOMNode {
|
|
|
719
726
|
|
|
720
727
|
private addAttribute(name: string, value: string): void {
|
|
721
728
|
const attr = {name: name, value: value, _node: this};
|
|
722
|
-
this
|
|
729
|
+
this.#attributesInternal.set(name, attr);
|
|
723
730
|
}
|
|
724
731
|
|
|
725
732
|
setAttributeInternal(name: string, value: string): void {
|
|
726
|
-
const attr = this
|
|
733
|
+
const attr = this.#attributesInternal.get(name);
|
|
727
734
|
if (attr) {
|
|
728
735
|
attr.value = value;
|
|
729
736
|
} else {
|
|
@@ -732,7 +739,7 @@ export class DOMNode {
|
|
|
732
739
|
}
|
|
733
740
|
|
|
734
741
|
removeAttributeInternal(name: string): void {
|
|
735
|
-
this
|
|
742
|
+
this.#attributesInternal.delete(name);
|
|
736
743
|
}
|
|
737
744
|
|
|
738
745
|
copyTo(
|
|
@@ -740,15 +747,15 @@ export class DOMNode {
|
|
|
740
747
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
741
748
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
742
749
|
callback?: ((arg0: string|null, arg1: DOMNode|null) => any)): void {
|
|
743
|
-
this
|
|
750
|
+
this.#agent
|
|
744
751
|
.invoke_copyTo(
|
|
745
752
|
{nodeId: this.id, targetNodeId: targetNode.id, insertBeforeNodeId: anchorNode ? anchorNode.id : undefined})
|
|
746
753
|
.then(response => {
|
|
747
754
|
if (!response.getError()) {
|
|
748
|
-
this
|
|
755
|
+
this.#domModelInternal.markUndoableState();
|
|
749
756
|
}
|
|
750
757
|
if (callback) {
|
|
751
|
-
callback(response.getError() || null, this
|
|
758
|
+
callback(response.getError() || null, this.#domModelInternal.nodeForId(response.nodeId));
|
|
752
759
|
}
|
|
753
760
|
});
|
|
754
761
|
}
|
|
@@ -758,62 +765,66 @@ export class DOMNode {
|
|
|
758
765
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
759
766
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
760
767
|
callback?: ((arg0: string|null, arg1: DOMNode|null) => any)): void {
|
|
761
|
-
this
|
|
768
|
+
this.#agent
|
|
762
769
|
.invoke_moveTo(
|
|
763
770
|
{nodeId: this.id, targetNodeId: targetNode.id, insertBeforeNodeId: anchorNode ? anchorNode.id : undefined})
|
|
764
771
|
.then(response => {
|
|
765
772
|
if (!response.getError()) {
|
|
766
|
-
this
|
|
773
|
+
this.#domModelInternal.markUndoableState();
|
|
767
774
|
}
|
|
768
775
|
if (callback) {
|
|
769
|
-
callback(response.getError() || null, this
|
|
776
|
+
callback(response.getError() || null, this.#domModelInternal.nodeForId(response.nodeId));
|
|
770
777
|
}
|
|
771
778
|
});
|
|
772
779
|
}
|
|
773
780
|
|
|
774
781
|
isXMLNode(): boolean {
|
|
775
|
-
return Boolean(this
|
|
782
|
+
return Boolean(this.#xmlVersion);
|
|
776
783
|
}
|
|
777
784
|
|
|
778
785
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
779
786
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
780
787
|
setMarker(name: string, value: any): void {
|
|
781
788
|
if (value === null) {
|
|
782
|
-
if (!this
|
|
789
|
+
if (!this.#markers.has(name)) {
|
|
783
790
|
return;
|
|
784
791
|
}
|
|
785
792
|
|
|
786
|
-
this
|
|
793
|
+
this.#markers.delete(name);
|
|
787
794
|
for (let node: (DOMNode|null) = (this as DOMNode | null); node; node = node.parentNode) {
|
|
788
|
-
--node
|
|
795
|
+
--node.#subtreeMarkerCount;
|
|
789
796
|
}
|
|
790
797
|
for (let node: (DOMNode|null) = (this as DOMNode | null); node; node = node.parentNode) {
|
|
791
|
-
this
|
|
798
|
+
this.#domModelInternal.dispatchEventToListeners(Events.MarkersChanged, node);
|
|
792
799
|
}
|
|
793
800
|
return;
|
|
794
801
|
}
|
|
795
802
|
|
|
796
|
-
if (this.parentNode && !this
|
|
803
|
+
if (this.parentNode && !this.#markers.has(name)) {
|
|
797
804
|
for (let node: (DOMNode|null) = (this as DOMNode | null); node; node = node.parentNode) {
|
|
798
|
-
++node
|
|
805
|
+
++node.#subtreeMarkerCount;
|
|
799
806
|
}
|
|
800
807
|
}
|
|
801
|
-
this
|
|
808
|
+
this.#markers.set(name, value);
|
|
802
809
|
for (let node: (DOMNode|null) = (this as DOMNode | null); node; node = node.parentNode) {
|
|
803
|
-
this
|
|
810
|
+
this.#domModelInternal.dispatchEventToListeners(Events.MarkersChanged, node);
|
|
804
811
|
}
|
|
805
812
|
}
|
|
806
813
|
|
|
807
814
|
marker<T>(name: string): T|null {
|
|
808
|
-
return this
|
|
815
|
+
return this.#markers.get(name) || null;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
getMarkerKeysForTest(): string[] {
|
|
819
|
+
return [...this.#markers.keys()];
|
|
809
820
|
}
|
|
810
821
|
|
|
811
822
|
traverseMarkers(visitor: (arg0: DOMNode, arg1: string) => void): void {
|
|
812
823
|
function traverse(node: DOMNode): void {
|
|
813
|
-
if (!node
|
|
824
|
+
if (!node.#subtreeMarkerCount) {
|
|
814
825
|
return;
|
|
815
826
|
}
|
|
816
|
-
for (const marker of node
|
|
827
|
+
for (const marker of node.#markers.keys()) {
|
|
817
828
|
visitor(node, marker);
|
|
818
829
|
}
|
|
819
830
|
if (!node.childrenInternal) {
|
|
@@ -840,20 +851,20 @@ export class DOMNode {
|
|
|
840
851
|
}
|
|
841
852
|
|
|
842
853
|
highlight(mode?: string): void {
|
|
843
|
-
this
|
|
854
|
+
this.#domModelInternal.overlayModel().highlightInOverlay({node: this, selectorList: undefined}, mode);
|
|
844
855
|
}
|
|
845
856
|
|
|
846
857
|
highlightForTwoSeconds(): void {
|
|
847
|
-
this
|
|
858
|
+
this.#domModelInternal.overlayModel().highlightInOverlayForTwoSeconds({node: this, selectorList: undefined});
|
|
848
859
|
}
|
|
849
860
|
|
|
850
861
|
async resolveToObject(objectGroup?: string): Promise<RemoteObject|null> {
|
|
851
|
-
const {object} = await this
|
|
852
|
-
return object && this
|
|
862
|
+
const {object} = await this.#agent.invoke_resolveNode({nodeId: this.id, backendNodeId: undefined, objectGroup});
|
|
863
|
+
return object && this.#domModelInternal.runtimeModelInternal.createRemoteObject(object) || null;
|
|
853
864
|
}
|
|
854
865
|
|
|
855
866
|
async boxModel(): Promise<Protocol.DOM.BoxModel|null> {
|
|
856
|
-
const {model} = await this
|
|
867
|
+
const {model} = await this.#agent.invoke_getBoxModel({nodeId: this.id});
|
|
857
868
|
return model;
|
|
858
869
|
}
|
|
859
870
|
|
|
@@ -871,13 +882,13 @@ export class DOMNode {
|
|
|
871
882
|
if (!ancestor) {
|
|
872
883
|
break;
|
|
873
884
|
}
|
|
874
|
-
// User agent shadow root, keep climbing up.
|
|
885
|
+
// User #agent shadow root, keep climbing up.
|
|
875
886
|
node = ancestor;
|
|
876
887
|
}
|
|
877
888
|
if (!node) {
|
|
878
889
|
throw new Error('In DOMNode.setAsInspectedNode: node is expected to not be null.');
|
|
879
890
|
}
|
|
880
|
-
await this
|
|
891
|
+
await this.#agent.invoke_setInspectedNode({nodeId: node.id});
|
|
881
892
|
}
|
|
882
893
|
|
|
883
894
|
enclosingElementOrSelf(): DOMNode|null {
|
|
@@ -926,7 +937,7 @@ export class DOMNode {
|
|
|
926
937
|
await object.callFunction(focusInPage);
|
|
927
938
|
object.release();
|
|
928
939
|
node.highlightForTwoSeconds();
|
|
929
|
-
await this
|
|
940
|
+
await this.#domModelInternal.target().pageAgent().invoke_bringToFront();
|
|
930
941
|
|
|
931
942
|
function focusInPage(this: HTMLElement): void {
|
|
932
943
|
this.focus();
|
|
@@ -975,12 +986,12 @@ export namespace DOMNode {
|
|
|
975
986
|
}
|
|
976
987
|
|
|
977
988
|
export class DeferredDOMNode {
|
|
978
|
-
|
|
979
|
-
|
|
989
|
+
readonly #domModelInternal: DOMModel;
|
|
990
|
+
readonly #backendNodeIdInternal: Protocol.DOM.BackendNodeId;
|
|
980
991
|
|
|
981
992
|
constructor(target: Target, backendNodeId: Protocol.DOM.BackendNodeId) {
|
|
982
|
-
this
|
|
983
|
-
this
|
|
993
|
+
this.#domModelInternal = (target.model(DOMModel) as DOMModel);
|
|
994
|
+
this.#backendNodeIdInternal = backendNodeId;
|
|
984
995
|
}
|
|
985
996
|
|
|
986
997
|
resolve(callback: (arg0: DOMNode|null) => void): void {
|
|
@@ -988,20 +999,21 @@ export class DeferredDOMNode {
|
|
|
988
999
|
}
|
|
989
1000
|
|
|
990
1001
|
async resolvePromise(): Promise<DOMNode|null> {
|
|
991
|
-
const nodeIds =
|
|
992
|
-
|
|
1002
|
+
const nodeIds =
|
|
1003
|
+
await this.#domModelInternal.pushNodesByBackendIdsToFrontend(new Set([this.#backendNodeIdInternal]));
|
|
1004
|
+
return nodeIds && nodeIds.get(this.#backendNodeIdInternal) || null;
|
|
993
1005
|
}
|
|
994
1006
|
|
|
995
1007
|
backendNodeId(): Protocol.DOM.BackendNodeId {
|
|
996
|
-
return this
|
|
1008
|
+
return this.#backendNodeIdInternal;
|
|
997
1009
|
}
|
|
998
1010
|
|
|
999
1011
|
domModel(): DOMModel {
|
|
1000
|
-
return this
|
|
1012
|
+
return this.#domModelInternal;
|
|
1001
1013
|
}
|
|
1002
1014
|
|
|
1003
1015
|
highlight(): void {
|
|
1004
|
-
this
|
|
1016
|
+
this.#domModelInternal.overlayModel().highlightInOverlay({deferredNode: this, selectorList: undefined});
|
|
1005
1017
|
}
|
|
1006
1018
|
}
|
|
1007
1019
|
|
|
@@ -1034,25 +1046,25 @@ export class DOMDocument extends DOMNode {
|
|
|
1034
1046
|
export class DOMModel extends SDKModel<EventTypes> {
|
|
1035
1047
|
agent: ProtocolProxyApi.DOMApi;
|
|
1036
1048
|
idToDOMNode: Map<Protocol.DOM.NodeId, DOMNode> = new Map();
|
|
1037
|
-
|
|
1038
|
-
|
|
1049
|
+
#document: DOMDocument|null;
|
|
1050
|
+
readonly #attributeLoadNodeIds: Set<Protocol.DOM.NodeId>;
|
|
1039
1051
|
readonly runtimeModelInternal: RuntimeModel;
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1052
|
+
#lastMutationId!: number;
|
|
1053
|
+
#pendingDocumentRequestPromise: Promise<DOMDocument|null>|null;
|
|
1054
|
+
#frameOwnerNode?: DOMNode|null;
|
|
1055
|
+
#loadNodeAttributesTimeout?: number;
|
|
1056
|
+
#searchId?: string;
|
|
1045
1057
|
constructor(target: Target) {
|
|
1046
1058
|
super(target);
|
|
1047
1059
|
|
|
1048
1060
|
this.agent = target.domAgent();
|
|
1049
1061
|
|
|
1050
|
-
this
|
|
1051
|
-
this
|
|
1062
|
+
this.#document = null;
|
|
1063
|
+
this.#attributeLoadNodeIds = new Set();
|
|
1052
1064
|
target.registerDOMDispatcher(new DOMDispatcher(this));
|
|
1053
1065
|
this.runtimeModelInternal = (target.model(RuntimeModel) as RuntimeModel);
|
|
1054
1066
|
|
|
1055
|
-
this
|
|
1067
|
+
this.#pendingDocumentRequestPromise = null;
|
|
1056
1068
|
|
|
1057
1069
|
if (!target.suspended()) {
|
|
1058
1070
|
this.agent.invoke_enable();
|
|
@@ -1086,11 +1098,11 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1086
1098
|
return;
|
|
1087
1099
|
}
|
|
1088
1100
|
|
|
1089
|
-
this
|
|
1090
|
-
Promise.resolve().then(callObserve.bind(this, node, this
|
|
1101
|
+
this.#lastMutationId = (this.#lastMutationId || 0) + 1;
|
|
1102
|
+
Promise.resolve().then(callObserve.bind(this, node, this.#lastMutationId));
|
|
1091
1103
|
|
|
1092
1104
|
function callObserve(this: DOMModel, node: DOMNode, mutationId: number): void {
|
|
1093
|
-
if (!this.hasEventListeners(Events.DOMMutated) || this
|
|
1105
|
+
if (!this.hasEventListeners(Events.DOMMutated) || this.#lastMutationId !== mutationId) {
|
|
1094
1106
|
return;
|
|
1095
1107
|
}
|
|
1096
1108
|
|
|
@@ -1099,13 +1111,13 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1099
1111
|
}
|
|
1100
1112
|
|
|
1101
1113
|
requestDocument(): Promise<DOMDocument|null> {
|
|
1102
|
-
if (this
|
|
1103
|
-
return Promise.resolve(this
|
|
1114
|
+
if (this.#document) {
|
|
1115
|
+
return Promise.resolve(this.#document);
|
|
1104
1116
|
}
|
|
1105
|
-
if (!this
|
|
1106
|
-
this
|
|
1117
|
+
if (!this.#pendingDocumentRequestPromise) {
|
|
1118
|
+
this.#pendingDocumentRequestPromise = this.requestDocumentInternal();
|
|
1107
1119
|
}
|
|
1108
|
-
return this
|
|
1120
|
+
return this.#pendingDocumentRequestPromise;
|
|
1109
1121
|
}
|
|
1110
1122
|
|
|
1111
1123
|
async getOwnerNodeForFrame(frameId: Protocol.Page.FrameId): Promise<DeferredDOMNode|null> {
|
|
@@ -1124,45 +1136,45 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1124
1136
|
return null;
|
|
1125
1137
|
}
|
|
1126
1138
|
const {root: documentPayload} = response;
|
|
1127
|
-
this
|
|
1139
|
+
this.#pendingDocumentRequestPromise = null;
|
|
1128
1140
|
|
|
1129
1141
|
if (documentPayload) {
|
|
1130
1142
|
this.setDocument(documentPayload);
|
|
1131
1143
|
}
|
|
1132
|
-
if (!this
|
|
1144
|
+
if (!this.#document) {
|
|
1133
1145
|
console.error('No document');
|
|
1134
1146
|
return null;
|
|
1135
1147
|
}
|
|
1136
1148
|
|
|
1137
1149
|
const parentModel = this.parentModel();
|
|
1138
|
-
if (parentModel && !this
|
|
1150
|
+
if (parentModel && !this.#frameOwnerNode) {
|
|
1139
1151
|
await parentModel.requestDocument();
|
|
1140
1152
|
const mainFrame = this.target().model(ResourceTreeModel)?.mainFrame;
|
|
1141
1153
|
if (mainFrame) {
|
|
1142
1154
|
const response = await parentModel.agent.invoke_getFrameOwner({frameId: mainFrame.id});
|
|
1143
1155
|
if (!response.getError() && response.nodeId) {
|
|
1144
|
-
this
|
|
1156
|
+
this.#frameOwnerNode = parentModel.nodeForId(response.nodeId);
|
|
1145
1157
|
}
|
|
1146
1158
|
}
|
|
1147
1159
|
}
|
|
1148
1160
|
|
|
1149
1161
|
// Document could have been cleared by now.
|
|
1150
|
-
if (this
|
|
1151
|
-
const oldDocument = this
|
|
1152
|
-
this
|
|
1153
|
-
this
|
|
1154
|
-
if (this
|
|
1155
|
-
this
|
|
1156
|
-
this.dispatchEventToListeners(Events.NodeInserted, this
|
|
1162
|
+
if (this.#frameOwnerNode) {
|
|
1163
|
+
const oldDocument = this.#frameOwnerNode.contentDocument();
|
|
1164
|
+
this.#frameOwnerNode.setContentDocument(this.#document);
|
|
1165
|
+
this.#frameOwnerNode.setChildren([]);
|
|
1166
|
+
if (this.#document) {
|
|
1167
|
+
this.#document.parentNode = this.#frameOwnerNode;
|
|
1168
|
+
this.dispatchEventToListeners(Events.NodeInserted, this.#document);
|
|
1157
1169
|
} else if (oldDocument) {
|
|
1158
|
-
this.dispatchEventToListeners(Events.NodeRemoved, {node: oldDocument, parent: this
|
|
1170
|
+
this.dispatchEventToListeners(Events.NodeRemoved, {node: oldDocument, parent: this.#frameOwnerNode});
|
|
1159
1171
|
}
|
|
1160
1172
|
}
|
|
1161
|
-
return this
|
|
1173
|
+
return this.#document;
|
|
1162
1174
|
}
|
|
1163
1175
|
|
|
1164
1176
|
existingDocument(): DOMDocument|null {
|
|
1165
|
-
return this
|
|
1177
|
+
return this.#document;
|
|
1166
1178
|
}
|
|
1167
1179
|
|
|
1168
1180
|
async pushNodeToFrontend(objectId: Protocol.Runtime.RemoteObjectId): Promise<DOMNode|null> {
|
|
@@ -1216,15 +1228,15 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1216
1228
|
}
|
|
1217
1229
|
|
|
1218
1230
|
inlineStyleInvalidated(nodeIds: number[]): void {
|
|
1219
|
-
Platform.SetUtilities.addAll(this
|
|
1220
|
-
if (!this
|
|
1221
|
-
this
|
|
1231
|
+
Platform.SetUtilities.addAll(this.#attributeLoadNodeIds, nodeIds);
|
|
1232
|
+
if (!this.#loadNodeAttributesTimeout) {
|
|
1233
|
+
this.#loadNodeAttributesTimeout = window.setTimeout(this.loadNodeAttributes.bind(this), 20);
|
|
1222
1234
|
}
|
|
1223
1235
|
}
|
|
1224
1236
|
|
|
1225
1237
|
private loadNodeAttributes(): void {
|
|
1226
|
-
|
|
1227
|
-
for (const nodeId of this
|
|
1238
|
+
this.#loadNodeAttributesTimeout = undefined;
|
|
1239
|
+
for (const nodeId of this.#attributeLoadNodeIds) {
|
|
1228
1240
|
this.agent.invoke_getAttributes({nodeId}).then(({attributes}) => {
|
|
1229
1241
|
if (!attributes) {
|
|
1230
1242
|
// We are calling loadNodeAttributes asynchronously, it is ok if node is not found.
|
|
@@ -1240,7 +1252,7 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1240
1252
|
}
|
|
1241
1253
|
});
|
|
1242
1254
|
}
|
|
1243
|
-
this
|
|
1255
|
+
this.#attributeLoadNodeIds.clear();
|
|
1244
1256
|
}
|
|
1245
1257
|
|
|
1246
1258
|
characterDataModified(nodeId: Protocol.DOM.NodeId, newValue: string): void {
|
|
@@ -1259,9 +1271,9 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1259
1271
|
}
|
|
1260
1272
|
|
|
1261
1273
|
documentUpdated(): void {
|
|
1262
|
-
// If we have this
|
|
1263
|
-
// if it hits backend post document update, it will contain most recent result.
|
|
1264
|
-
const documentWasRequested = this
|
|
1274
|
+
// If we have this.#pendingDocumentRequestPromise in flight,
|
|
1275
|
+
// if it hits backend post #document update, it will contain most recent result.
|
|
1276
|
+
const documentWasRequested = this.#document || this.#pendingDocumentRequestPromise;
|
|
1265
1277
|
this.setDocument(null);
|
|
1266
1278
|
if (this.parentModel() && documentWasRequested) {
|
|
1267
1279
|
this.requestDocument();
|
|
@@ -1271,9 +1283,9 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1271
1283
|
private setDocument(payload: Protocol.DOM.Node|null): void {
|
|
1272
1284
|
this.idToDOMNode = new Map();
|
|
1273
1285
|
if (payload && 'nodeId' in payload) {
|
|
1274
|
-
this
|
|
1286
|
+
this.#document = new DOMDocument(this, payload);
|
|
1275
1287
|
} else {
|
|
1276
|
-
this
|
|
1288
|
+
this.#document = null;
|
|
1277
1289
|
}
|
|
1278
1290
|
DOMModelUndoStack.instance().dispose(this);
|
|
1279
1291
|
|
|
@@ -1437,11 +1449,11 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1437
1449
|
}[],
|
|
1438
1450
|
pierce: boolean = false): Promise<Protocol.DOM.NodeId[]> {
|
|
1439
1451
|
await this.requestDocument();
|
|
1440
|
-
if (!this
|
|
1452
|
+
if (!this.#document) {
|
|
1441
1453
|
throw new Error('DOMModel.getNodesByStyle expects to have a document.');
|
|
1442
1454
|
}
|
|
1443
1455
|
const response =
|
|
1444
|
-
await this.agent.invoke_getNodesForSubtreeByStyle({nodeId: this
|
|
1456
|
+
await this.agent.invoke_getNodesForSubtreeByStyle({nodeId: this.#document.id, computedStyles, pierce});
|
|
1445
1457
|
if (response.getError()) {
|
|
1446
1458
|
throw response.getError();
|
|
1447
1459
|
}
|
|
@@ -1451,26 +1463,26 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1451
1463
|
async performSearch(query: string, includeUserAgentShadowDOM: boolean): Promise<number> {
|
|
1452
1464
|
const response = await this.agent.invoke_performSearch({query, includeUserAgentShadowDOM});
|
|
1453
1465
|
if (!response.getError()) {
|
|
1454
|
-
this
|
|
1466
|
+
this.#searchId = response.searchId;
|
|
1455
1467
|
}
|
|
1456
1468
|
return response.getError() ? 0 : response.resultCount;
|
|
1457
1469
|
}
|
|
1458
1470
|
|
|
1459
1471
|
async searchResult(index: number): Promise<DOMNode|null> {
|
|
1460
|
-
if (!this
|
|
1472
|
+
if (!this.#searchId) {
|
|
1461
1473
|
return null;
|
|
1462
1474
|
}
|
|
1463
1475
|
const {nodeIds} =
|
|
1464
|
-
await this.agent.invoke_getSearchResults({searchId: this
|
|
1476
|
+
await this.agent.invoke_getSearchResults({searchId: this.#searchId, fromIndex: index, toIndex: index + 1});
|
|
1465
1477
|
return nodeIds && nodeIds.length === 1 ? this.nodeForId(nodeIds[0]) : null;
|
|
1466
1478
|
}
|
|
1467
1479
|
|
|
1468
1480
|
private cancelSearch(): void {
|
|
1469
|
-
if (!this
|
|
1481
|
+
if (!this.#searchId) {
|
|
1470
1482
|
return;
|
|
1471
1483
|
}
|
|
1472
|
-
this.agent.invoke_discardSearchResults({searchId: this
|
|
1473
|
-
|
|
1484
|
+
this.agent.invoke_discardSearchResults({searchId: this.#searchId});
|
|
1485
|
+
this.#searchId = undefined;
|
|
1474
1486
|
}
|
|
1475
1487
|
|
|
1476
1488
|
classNamesPromise(nodeId: Protocol.DOM.NodeId): Promise<string[]> {
|
|
@@ -1564,65 +1576,65 @@ export type EventTypes = {
|
|
|
1564
1576
|
};
|
|
1565
1577
|
|
|
1566
1578
|
class DOMDispatcher implements ProtocolProxyApi.DOMDispatcher {
|
|
1567
|
-
|
|
1579
|
+
readonly #domModel: DOMModel;
|
|
1568
1580
|
constructor(domModel: DOMModel) {
|
|
1569
|
-
this
|
|
1581
|
+
this.#domModel = domModel;
|
|
1570
1582
|
}
|
|
1571
1583
|
|
|
1572
1584
|
documentUpdated(): void {
|
|
1573
|
-
this
|
|
1585
|
+
this.#domModel.documentUpdated();
|
|
1574
1586
|
}
|
|
1575
1587
|
|
|
1576
1588
|
attributeModified({nodeId, name, value}: Protocol.DOM.AttributeModifiedEvent): void {
|
|
1577
|
-
this
|
|
1589
|
+
this.#domModel.attributeModified(nodeId, name, value);
|
|
1578
1590
|
}
|
|
1579
1591
|
|
|
1580
1592
|
attributeRemoved({nodeId, name}: Protocol.DOM.AttributeRemovedEvent): void {
|
|
1581
|
-
this
|
|
1593
|
+
this.#domModel.attributeRemoved(nodeId, name);
|
|
1582
1594
|
}
|
|
1583
1595
|
|
|
1584
1596
|
inlineStyleInvalidated({nodeIds}: Protocol.DOM.InlineStyleInvalidatedEvent): void {
|
|
1585
|
-
this
|
|
1597
|
+
this.#domModel.inlineStyleInvalidated(nodeIds);
|
|
1586
1598
|
}
|
|
1587
1599
|
|
|
1588
1600
|
characterDataModified({nodeId, characterData}: Protocol.DOM.CharacterDataModifiedEvent): void {
|
|
1589
|
-
this
|
|
1601
|
+
this.#domModel.characterDataModified(nodeId, characterData);
|
|
1590
1602
|
}
|
|
1591
1603
|
|
|
1592
1604
|
setChildNodes({parentId, nodes}: Protocol.DOM.SetChildNodesEvent): void {
|
|
1593
|
-
this
|
|
1605
|
+
this.#domModel.setChildNodes(parentId, nodes);
|
|
1594
1606
|
}
|
|
1595
1607
|
|
|
1596
1608
|
childNodeCountUpdated({nodeId, childNodeCount}: Protocol.DOM.ChildNodeCountUpdatedEvent): void {
|
|
1597
|
-
this
|
|
1609
|
+
this.#domModel.childNodeCountUpdated(nodeId, childNodeCount);
|
|
1598
1610
|
}
|
|
1599
1611
|
|
|
1600
1612
|
childNodeInserted({parentNodeId, previousNodeId, node}: Protocol.DOM.ChildNodeInsertedEvent): void {
|
|
1601
|
-
this
|
|
1613
|
+
this.#domModel.childNodeInserted(parentNodeId, previousNodeId, node);
|
|
1602
1614
|
}
|
|
1603
1615
|
|
|
1604
1616
|
childNodeRemoved({parentNodeId, nodeId}: Protocol.DOM.ChildNodeRemovedEvent): void {
|
|
1605
|
-
this
|
|
1617
|
+
this.#domModel.childNodeRemoved(parentNodeId, nodeId);
|
|
1606
1618
|
}
|
|
1607
1619
|
|
|
1608
1620
|
shadowRootPushed({hostId, root}: Protocol.DOM.ShadowRootPushedEvent): void {
|
|
1609
|
-
this
|
|
1621
|
+
this.#domModel.shadowRootPushed(hostId, root);
|
|
1610
1622
|
}
|
|
1611
1623
|
|
|
1612
1624
|
shadowRootPopped({hostId, rootId}: Protocol.DOM.ShadowRootPoppedEvent): void {
|
|
1613
|
-
this
|
|
1625
|
+
this.#domModel.shadowRootPopped(hostId, rootId);
|
|
1614
1626
|
}
|
|
1615
1627
|
|
|
1616
1628
|
pseudoElementAdded({parentId, pseudoElement}: Protocol.DOM.PseudoElementAddedEvent): void {
|
|
1617
|
-
this
|
|
1629
|
+
this.#domModel.pseudoElementAdded(parentId, pseudoElement);
|
|
1618
1630
|
}
|
|
1619
1631
|
|
|
1620
1632
|
pseudoElementRemoved({parentId, pseudoElementId}: Protocol.DOM.PseudoElementRemovedEvent): void {
|
|
1621
|
-
this
|
|
1633
|
+
this.#domModel.pseudoElementRemoved(parentId, pseudoElementId);
|
|
1622
1634
|
}
|
|
1623
1635
|
|
|
1624
1636
|
distributedNodesUpdated({insertionPointId, distributedNodes}: Protocol.DOM.DistributedNodesUpdatedEvent): void {
|
|
1625
|
-
this
|
|
1637
|
+
this.#domModel.distributedNodesUpdated(insertionPointId, distributedNodes);
|
|
1626
1638
|
}
|
|
1627
1639
|
}
|
|
1628
1640
|
|
|
@@ -1631,13 +1643,13 @@ class DOMDispatcher implements ProtocolProxyApi.DOMDispatcher {
|
|
|
1631
1643
|
let DOMModelUndoStackInstance: DOMModelUndoStack|null;
|
|
1632
1644
|
|
|
1633
1645
|
export class DOMModelUndoStack {
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1646
|
+
#stack: DOMModel[];
|
|
1647
|
+
#index: number;
|
|
1648
|
+
#lastModelWithMinorChange: DOMModel|null;
|
|
1637
1649
|
constructor() {
|
|
1638
|
-
this
|
|
1639
|
-
this
|
|
1640
|
-
this
|
|
1650
|
+
this.#stack = [];
|
|
1651
|
+
this.#index = 0;
|
|
1652
|
+
this.#lastModelWithMinorChange = null;
|
|
1641
1653
|
}
|
|
1642
1654
|
|
|
1643
1655
|
static instance(opts: {
|
|
@@ -1652,61 +1664,61 @@ export class DOMModelUndoStack {
|
|
|
1652
1664
|
}
|
|
1653
1665
|
|
|
1654
1666
|
async markUndoableState(model: DOMModel, minorChange: boolean): Promise<void> {
|
|
1655
|
-
// Both minor and major changes get into the stack, but minor updates are coalesced.
|
|
1667
|
+
// Both minor and major changes get into the #stack, but minor updates are coalesced.
|
|
1656
1668
|
// Commit major undoable state in the old model upon model switch.
|
|
1657
|
-
if (this
|
|
1658
|
-
this
|
|
1659
|
-
this
|
|
1669
|
+
if (this.#lastModelWithMinorChange && model !== this.#lastModelWithMinorChange) {
|
|
1670
|
+
this.#lastModelWithMinorChange.markUndoableState();
|
|
1671
|
+
this.#lastModelWithMinorChange = null;
|
|
1660
1672
|
}
|
|
1661
1673
|
|
|
1662
|
-
// Previous minor change is already in the stack.
|
|
1663
|
-
if (minorChange && this
|
|
1674
|
+
// Previous minor change is already in the #stack.
|
|
1675
|
+
if (minorChange && this.#lastModelWithMinorChange === model) {
|
|
1664
1676
|
return;
|
|
1665
1677
|
}
|
|
1666
1678
|
|
|
1667
|
-
this
|
|
1668
|
-
this
|
|
1669
|
-
this
|
|
1679
|
+
this.#stack = this.#stack.slice(0, this.#index);
|
|
1680
|
+
this.#stack.push(model);
|
|
1681
|
+
this.#index = this.#stack.length;
|
|
1670
1682
|
|
|
1671
1683
|
// Delay marking as major undoable states in case of minor operations until the
|
|
1672
1684
|
// major or model switch.
|
|
1673
1685
|
if (minorChange) {
|
|
1674
|
-
this
|
|
1686
|
+
this.#lastModelWithMinorChange = model;
|
|
1675
1687
|
} else {
|
|
1676
1688
|
await model.getAgent().invoke_markUndoableState();
|
|
1677
|
-
this
|
|
1689
|
+
this.#lastModelWithMinorChange = null;
|
|
1678
1690
|
}
|
|
1679
1691
|
}
|
|
1680
1692
|
|
|
1681
1693
|
async undo(): Promise<void> {
|
|
1682
|
-
if (this
|
|
1694
|
+
if (this.#index === 0) {
|
|
1683
1695
|
return Promise.resolve();
|
|
1684
1696
|
}
|
|
1685
|
-
--this
|
|
1686
|
-
this
|
|
1687
|
-
await this
|
|
1697
|
+
--this.#index;
|
|
1698
|
+
this.#lastModelWithMinorChange = null;
|
|
1699
|
+
await this.#stack[this.#index].getAgent().invoke_undo();
|
|
1688
1700
|
}
|
|
1689
1701
|
|
|
1690
1702
|
async redo(): Promise<void> {
|
|
1691
|
-
if (this
|
|
1703
|
+
if (this.#index >= this.#stack.length) {
|
|
1692
1704
|
return Promise.resolve();
|
|
1693
1705
|
}
|
|
1694
|
-
++this
|
|
1695
|
-
this
|
|
1696
|
-
await this
|
|
1706
|
+
++this.#index;
|
|
1707
|
+
this.#lastModelWithMinorChange = null;
|
|
1708
|
+
await this.#stack[this.#index - 1].getAgent().invoke_redo();
|
|
1697
1709
|
}
|
|
1698
1710
|
|
|
1699
1711
|
dispose(model: DOMModel): void {
|
|
1700
1712
|
let shift = 0;
|
|
1701
|
-
for (let i = 0; i < this
|
|
1702
|
-
if (this
|
|
1713
|
+
for (let i = 0; i < this.#index; ++i) {
|
|
1714
|
+
if (this.#stack[i] === model) {
|
|
1703
1715
|
++shift;
|
|
1704
1716
|
}
|
|
1705
1717
|
}
|
|
1706
|
-
Platform.ArrayUtilities.removeElement(this
|
|
1707
|
-
this
|
|
1708
|
-
if (this
|
|
1709
|
-
this
|
|
1718
|
+
Platform.ArrayUtilities.removeElement(this.#stack, model);
|
|
1719
|
+
this.#index -= shift;
|
|
1720
|
+
if (this.#lastModelWithMinorChange === model) {
|
|
1721
|
+
this.#lastModelWithMinorChange = null;
|
|
1710
1722
|
}
|
|
1711
1723
|
}
|
|
1712
1724
|
}
|