chrome-devtools-frontend 1.0.1700561 → 1.0.1702515
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/front_end/core/host/UserMetricsEnums.ts +2 -1
- package/front_end/core/root/ExperimentNames.ts +1 -0
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +10 -10
- package/front_end/core/sdk/NetworkManager.ts +7 -0
- package/front_end/core/sdk/SecurityOrigin.ts +1 -0
- package/front_end/core/sdk/SourceMap.ts +12 -1
- package/front_end/core/sdk/SourceMapCache.ts +12 -0
- package/front_end/core/sdk/SourceMapManager.ts +17 -8
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +2 -19
- package/front_end/core/sdk/SourceMapScopesInfo.ts +21 -0
- package/front_end/devtools_compatibility.js +2 -1
- package/front_end/entrypoints/formatter_worker/ScopeParser.ts +7 -3
- package/front_end/entrypoints/formatter_worker/Substitute.ts +90 -26
- package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +1 -1
- package/front_end/entrypoints/main/ExecutionContextSelector.ts +17 -4
- package/front_end/entrypoints/main/MainImpl.ts +8 -0
- package/front_end/generated/InspectorBackendCommands.ts +4 -6
- package/front_end/generated/protocol-mapping.d.ts +0 -8
- package/front_end/generated/protocol-proxy-api.d.ts +0 -6
- package/front_end/generated/protocol.ts +4 -25
- package/front_end/models/ai_assistance/AiAgent2.ts +13 -1
- package/front_end/models/ai_assistance/AiConversation.ts +1 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +13 -19
- package/front_end/models/ai_assistance/debug.ts +10 -2
- package/front_end/models/change_tracker/ChangeTracker.ts +5 -64
- package/front_end/models/comment_manager/CD4ABridge.ts +2 -2
- package/front_end/models/comment_manager/CommentManager.ts +6 -5
- package/front_end/models/comment_manager/CommentThread.ts +30 -13
- package/front_end/models/formatter/FormatterWorkerPool.ts +2 -2
- package/front_end/models/issues_manager/CookieDeprecationMetadataIssue.ts +6 -7
- package/front_end/models/issues_manager/DeprecationIssue.ts +1 -1
- package/front_end/models/issues_manager/MarkdownIssueDescription.ts +14 -5
- package/front_end/models/issues_manager/SRIMessageSignatureIssue.ts +2 -4
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantRead.md +0 -1
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantReadOptOut.md +5 -0
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantSet.md +0 -1
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantSetOptOut.md +5 -0
- package/front_end/models/issues_manager/descriptions/deprecation.md +1 -1
- package/front_end/models/issues_manager/descriptions/sriValidationFailedIntegrityMismatch.md +2 -0
- package/front_end/models/javascript_metadata/NativeFunctions.ts +7 -2
- package/front_end/models/persistence/NetworkPersistenceManager.ts +14 -2
- package/front_end/models/source_map_scopes/NamesResolver.ts +42 -39
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +70 -1
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +1 -1
- package/front_end/panels/common/CommentThreadWidget.ts +29 -10
- package/front_end/panels/common/CommentsOverlayWidget.ts +77 -14
- package/front_end/panels/common/ExtensionServer.ts +18 -8
- package/front_end/panels/common/commentThreadWidget.css +11 -0
- package/front_end/panels/console/ConsolePrompt.ts +1 -1
- package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
- package/front_end/panels/elements/ClassesPaneWidget.ts +2 -1
- package/front_end/panels/elements/DOMTreeContextMenu.ts +1 -1
- package/front_end/panels/elements/{ElementsTreeOutline.ts → DOMTreeWidget.ts} +34 -24
- package/front_end/panels/elements/ElementsPanel.ts +1 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
- package/front_end/panels/elements/ShortcutTreeElement.ts +1 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +10 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +105 -55
- package/front_end/panels/elements/TopLayerContainer.ts +1 -1
- package/front_end/panels/elements/components/CSSQuery.ts +1 -1
- package/front_end/panels/elements/components/cssQuery.css +4 -0
- package/front_end/panels/elements/elements.ts +3 -3
- package/front_end/panels/elements/stylesSidebarPane.css +6 -0
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +1 -1
- package/front_end/panels/profiler/HeapProfileView.ts +8 -6
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +8 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +6 -4
- package/front_end/panels/security/SecurityPanel.ts +87 -99
- package/front_end/panels/sensors/SensorsView.ts +87 -0
- package/front_end/panels/sensors/sensors-meta.ts +69 -1
- package/front_end/panels/settings/keybindsSettingsTab.css +1 -1
- package/front_end/panels/sources/ResourceOriginPlugin.ts +8 -3
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +3 -4
- package/front_end/panels/sources/TabbedEditorContainer.ts +339 -126
- package/front_end/panels/sources/UISourceCodeFrame.ts +9 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/chromium/client-variations/ClientVariations.js +25 -96
- package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/package.json +4 -1
- package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
- package/front_end/ui/comments/CommentOverlayManager.ts +11 -10
- package/front_end/ui/components/markdown_view/MarkdownPlaceholderLitRenderer.ts +117 -0
- package/front_end/ui/components/markdown_view/markdown_view.ts +2 -0
- package/front_end/ui/legacy/Treeoutline.ts +30 -20
- package/front_end/ui/legacy/UIUtils.ts +1 -1
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +228 -343
- package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +2 -27
- package/front_end/ui/legacy/treeoutline.css +2 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +7 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
|
@@ -31,6 +31,7 @@ export interface ViewInput {
|
|
|
31
31
|
activePin: Comments.CommentOverlayManager.PinPositionData|null;
|
|
32
32
|
title: Title;
|
|
33
33
|
onAddComment: (text: string) => void;
|
|
34
|
+
onCloseCommentThread: () => void;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export type View = (
|
|
@@ -43,6 +44,7 @@ const POPUP_MARGIN = 8;
|
|
|
43
44
|
const PIN_HEIGHT = 30;
|
|
44
45
|
const POPUP_WIDTH = 288;
|
|
45
46
|
const POPUP_HEIGHT = 220;
|
|
47
|
+
const AUTO_CLOSE_DELAY_MS = 2000;
|
|
46
48
|
|
|
47
49
|
const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
|
|
48
50
|
// clang-format off
|
|
@@ -102,6 +104,7 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
|
|
|
102
104
|
title: input.title,
|
|
103
105
|
comments: [...item.thread.comments],
|
|
104
106
|
onAddComment: input.onAddComment,
|
|
107
|
+
onClose: input.onCloseCommentThread,
|
|
105
108
|
})}
|
|
106
109
|
</div>
|
|
107
110
|
`,
|
|
@@ -119,9 +122,22 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
119
122
|
readonly #commentManager: CommentManager.CommentManager.CommentManager;
|
|
120
123
|
#commentOverlayManager: Comments.CommentOverlayManager.CommentOverlayManager;
|
|
121
124
|
#activeThreadId: string|null = null;
|
|
125
|
+
#closeTimeoutId: number|null = null;
|
|
122
126
|
#cachedTitle: Title = {text: ''};
|
|
123
127
|
#cachedTitleAnchor: CommentManager.CommentManager.CommentAnchorSignature|null = null;
|
|
124
128
|
|
|
129
|
+
#setActiveThreadId(threadId: string|null): void {
|
|
130
|
+
if (this.#activeThreadId !== threadId) {
|
|
131
|
+
this.#clearCloseTimeout();
|
|
132
|
+
this.#activeThreadId = threadId;
|
|
133
|
+
if (threadId && this.isShowing()) {
|
|
134
|
+
document.documentElement.addEventListener('keydown', this.#onKeyDown);
|
|
135
|
+
} else {
|
|
136
|
+
document.documentElement.removeEventListener('keydown', this.#onKeyDown);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
125
141
|
constructor(
|
|
126
142
|
element: HTMLElement|undefined,
|
|
127
143
|
[commentManager]: UI.Widget.WidgetDependencies<typeof CommentsOverlayWidget>,
|
|
@@ -168,11 +184,16 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
168
184
|
this.#onAgentAttachedChanged,
|
|
169
185
|
this,
|
|
170
186
|
);
|
|
187
|
+
if (this.#activeThreadId) {
|
|
188
|
+
document.documentElement.addEventListener('keydown', this.#onKeyDown);
|
|
189
|
+
}
|
|
171
190
|
|
|
172
191
|
this.requestUpdate();
|
|
173
192
|
}
|
|
174
193
|
|
|
175
194
|
override willHide(): void {
|
|
195
|
+
this.#clearCloseTimeout();
|
|
196
|
+
document.documentElement.removeEventListener('keydown', this.#onKeyDown);
|
|
176
197
|
this.#commentOverlayManager.stop();
|
|
177
198
|
this.#commentOverlayManager.removeEventListener(
|
|
178
199
|
Comments.CommentOverlayManager.Events.POSITIONS_UPDATED,
|
|
@@ -204,12 +225,19 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
204
225
|
super.willHide();
|
|
205
226
|
}
|
|
206
227
|
|
|
228
|
+
#clearCloseTimeout(): void {
|
|
229
|
+
if (this.#closeTimeoutId !== null) {
|
|
230
|
+
window.clearTimeout(this.#closeTimeoutId);
|
|
231
|
+
this.#closeTimeoutId = null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
207
235
|
#onAgentAttachedChanged(
|
|
208
236
|
event: Common.EventTarget.EventTargetEvent<
|
|
209
237
|
CommentManager.CommentManager.EventTypes[CommentManager.CommentManager.Events.AGENT_ATTACHED_CHANGED]>,
|
|
210
238
|
): void {
|
|
211
239
|
if (!event.data) {
|
|
212
|
-
this.#
|
|
240
|
+
this.#setActiveThreadId(null);
|
|
213
241
|
}
|
|
214
242
|
this.requestUpdate();
|
|
215
243
|
}
|
|
@@ -220,7 +248,7 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
220
248
|
): void {
|
|
221
249
|
const isModeActive = event.data;
|
|
222
250
|
if (!isModeActive) {
|
|
223
|
-
this.#
|
|
251
|
+
this.#setActiveThreadId(null);
|
|
224
252
|
}
|
|
225
253
|
const action = UI.ActionRegistry.ActionRegistry.instance().getAction(
|
|
226
254
|
'comments.toggle-comment-mode',
|
|
@@ -232,9 +260,9 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
232
260
|
#onStateChanged(): void {
|
|
233
261
|
const draftThread = this.#commentManager.getCommentThreads().find(t => t.status === 'DRAFT');
|
|
234
262
|
if (draftThread) {
|
|
235
|
-
this.#
|
|
263
|
+
this.#setActiveThreadId(draftThread.id);
|
|
236
264
|
} else if (this.#activeThreadId && !this.#commentManager.getCommentThread(this.#activeThreadId)) {
|
|
237
|
-
this.#
|
|
265
|
+
this.#setActiveThreadId(null);
|
|
238
266
|
}
|
|
239
267
|
this.requestUpdate();
|
|
240
268
|
}
|
|
@@ -262,7 +290,6 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
262
290
|
return {node};
|
|
263
291
|
}
|
|
264
292
|
}
|
|
265
|
-
return {text: ''};
|
|
266
293
|
}
|
|
267
294
|
|
|
268
295
|
if (anchor.networkRequestId) {
|
|
@@ -277,19 +304,35 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
277
304
|
}
|
|
278
305
|
|
|
279
306
|
#handlePinClick = (threadId: string): void => {
|
|
280
|
-
const thread = this.#commentManager.getCommentThread(threadId);
|
|
281
307
|
if (this.#activeThreadId === threadId) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
308
|
+
this.#handleCloseCommentThread();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
this.#commentOverlayManager.clearDraftThreads();
|
|
313
|
+
this.#setActiveThreadId(threadId);
|
|
314
|
+
this.requestUpdate();
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
#handleCloseCommentThread = (): void => {
|
|
318
|
+
if (!this.#activeThreadId) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const thread = this.#commentManager.getCommentThread(this.#activeThreadId);
|
|
322
|
+
if (thread?.status === 'DRAFT') {
|
|
287
323
|
this.#commentOverlayManager.clearDraftThreads();
|
|
288
|
-
this.#activeThreadId = threadId;
|
|
289
324
|
}
|
|
325
|
+
this.#setActiveThreadId(null);
|
|
290
326
|
this.requestUpdate();
|
|
291
327
|
};
|
|
292
328
|
|
|
329
|
+
#onKeyDown = (event: KeyboardEvent): void => {
|
|
330
|
+
if (this.#activeThreadId && event.key === 'Escape' && !event.isComposing) {
|
|
331
|
+
event.consume(true);
|
|
332
|
+
this.#handleCloseCommentThread();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
293
336
|
override async performUpdate(signal?: AbortSignal): Promise<void> {
|
|
294
337
|
if (!this.#commentManager.isAgentAttached()) {
|
|
295
338
|
this.#view(
|
|
@@ -303,6 +346,7 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
303
346
|
activePin: null,
|
|
304
347
|
title: {text: ''},
|
|
305
348
|
onAddComment: () => {},
|
|
349
|
+
onCloseCommentThread: this.#handleCloseCommentThread,
|
|
306
350
|
},
|
|
307
351
|
undefined,
|
|
308
352
|
this.contentElement,
|
|
@@ -329,8 +373,21 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
329
373
|
activePin,
|
|
330
374
|
title,
|
|
331
375
|
onAddComment: (text: string) => {
|
|
332
|
-
activeThread
|
|
376
|
+
if (!activeThread) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
activeThread.sendToAgent(text);
|
|
380
|
+
const threadId = activeThread.id;
|
|
381
|
+
this.#clearCloseTimeout();
|
|
382
|
+
this.#closeTimeoutId = window.setTimeout(() => {
|
|
383
|
+
this.#closeTimeoutId = null;
|
|
384
|
+
if (this.#activeThreadId === threadId) {
|
|
385
|
+
this.#setActiveThreadId(null);
|
|
386
|
+
this.requestUpdate();
|
|
387
|
+
}
|
|
388
|
+
}, AUTO_CLOSE_DELAY_MS);
|
|
333
389
|
},
|
|
390
|
+
onCloseCommentThread: this.#handleCloseCommentThread,
|
|
334
391
|
};
|
|
335
392
|
this.#view(viewInput, undefined, this.contentElement);
|
|
336
393
|
}
|
|
@@ -350,6 +407,9 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
|
350
407
|
|
|
351
408
|
handleAction(_context: UI.Context.Context, actionId: string): boolean {
|
|
352
409
|
if (actionId === 'comments.toggle-comment-mode') {
|
|
410
|
+
if (!this.#commentManager.isAgentAttached()) {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
353
413
|
if (!widgetInstance) {
|
|
354
414
|
widgetInstance = new CommentsOverlayWidget(
|
|
355
415
|
undefined,
|
|
@@ -383,11 +443,14 @@ export class ButtonProvider implements UI.Toolbar.Provider {
|
|
|
383
443
|
Root.DevToolsContext.globalInstance().get(
|
|
384
444
|
CommentManager.CommentManager.CommentManager,
|
|
385
445
|
);
|
|
386
|
-
|
|
446
|
+
const action = UI.ActionRegistry.ActionRegistry.instance().getAction('comments.toggle-comment-mode');
|
|
447
|
+
action.setEnabled(this.#commentManager.isAgentAttached());
|
|
448
|
+
this.#button = UI.Toolbar.Toolbar.createActionButton(action);
|
|
387
449
|
this.#button.setVisible(this.#commentManager.isAgentAttached());
|
|
388
450
|
this.#commentManager.addEventListener(
|
|
389
451
|
CommentManager.CommentManager.Events.AGENT_ATTACHED_CHANGED,
|
|
390
452
|
event => {
|
|
453
|
+
action.setEnabled(event.data);
|
|
391
454
|
this.#button.setVisible(event.data);
|
|
392
455
|
},
|
|
393
456
|
);
|
|
@@ -34,6 +34,7 @@ const kForbiddenSchemes = [
|
|
|
34
34
|
'chrome-error:',
|
|
35
35
|
'chrome-search:',
|
|
36
36
|
'devtools:',
|
|
37
|
+
'isolated-app:',
|
|
37
38
|
];
|
|
38
39
|
|
|
39
40
|
declare global {
|
|
@@ -44,6 +45,18 @@ declare global {
|
|
|
44
45
|
|
|
45
46
|
let extensionServerInstance: ExtensionServer|null;
|
|
46
47
|
|
|
48
|
+
function parseCanonicalURL(url: Platform.DevToolsPath.UrlString): URL|null {
|
|
49
|
+
try {
|
|
50
|
+
let parsedURL = new URL(url);
|
|
51
|
+
while (parsedURL.protocol === 'blob:' || parsedURL.protocol === 'filesystem:') {
|
|
52
|
+
parsedURL = new URL(parsedURL.href.slice(parsedURL.protocol.length));
|
|
53
|
+
}
|
|
54
|
+
return parsedURL;
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
47
60
|
export class HostsPolicy {
|
|
48
61
|
static create(policy?: Host.InspectorFrontendHostAPI.ExtensionHostsPolicy): HostsPolicy|null {
|
|
49
62
|
const runtimeAllowedHosts = [];
|
|
@@ -98,12 +111,11 @@ class RegisteredExtension {
|
|
|
98
111
|
return false;
|
|
99
112
|
}
|
|
100
113
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
parsedURL = new URL(inspectedURL);
|
|
104
|
-
} catch {
|
|
114
|
+
const parsedURL = parseCanonicalURL(inspectedURL);
|
|
115
|
+
if (!parsedURL) {
|
|
105
116
|
return false;
|
|
106
117
|
}
|
|
118
|
+
inspectedURL = parsedURL.href as Platform.DevToolsPath.UrlString;
|
|
107
119
|
|
|
108
120
|
if (parsedURL.protocol === 'chrome-extension:') {
|
|
109
121
|
if (parsedURL.origin !== this.origin) {
|
|
@@ -1827,12 +1839,10 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
1827
1839
|
}
|
|
1828
1840
|
|
|
1829
1841
|
static canInspectURL(url: Platform.DevToolsPath.UrlString): boolean {
|
|
1830
|
-
let parsedURL;
|
|
1831
1842
|
// This is only to work around invalid URLs we're occasionally getting from some tests.
|
|
1832
1843
|
// TODO(caseq): make sure tests supply valid URLs or we specifically handle invalid ones.
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
} catch {
|
|
1844
|
+
const parsedURL = parseCanonicalURL(url);
|
|
1845
|
+
if (!parsedURL) {
|
|
1836
1846
|
return false;
|
|
1837
1847
|
}
|
|
1838
1848
|
|
|
@@ -30,6 +30,17 @@
|
|
|
30
30
|
gap: var(--sys-size-4);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
.header-actions {
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
gap: var(--sys-size-3);
|
|
37
|
+
flex-shrink: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.close-button {
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
.sent-status {
|
|
34
45
|
display: flex;
|
|
35
46
|
align-items: center;
|
|
@@ -459,7 +459,7 @@ export class ConsolePrompt extends ConsolePromptBase {
|
|
|
459
459
|
?.evaluateCommandInConsole(executionContext, message, expression, useCommandLineAPI);
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
private async substituteNames(expression: string, mapping: Map<string, string|null
|
|
462
|
+
private async substituteNames(expression: string, mapping: Array<Map<string, string|null>>): Promise<string> {
|
|
463
463
|
try {
|
|
464
464
|
return await Formatter.FormatterWorkerPool.formatterWorkerPool().javaScriptSubstitute(expression, mapping);
|
|
465
465
|
} catch {
|
|
@@ -1030,7 +1030,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
|
|
|
1030
1030
|
result.appendChild(this.formatParameterAsObject(remoteObject, false));
|
|
1031
1031
|
return;
|
|
1032
1032
|
}
|
|
1033
|
-
const treeOutline = new Elements.
|
|
1033
|
+
const treeOutline = new Elements.DOMTreeWidget.ElementsTreeOutline(
|
|
1034
1034
|
/* omitRootDOMNode: */ false, /* selectEnabled: */ true, /* hideGutter: */ true);
|
|
1035
1035
|
treeOutline.rootDOMNode = node;
|
|
1036
1036
|
treeOutline.deindentSingleNode();
|
|
@@ -359,7 +359,8 @@ export class ClassNamePrompt extends UI.TextPrompt.TextPrompt {
|
|
|
359
359
|
|
|
360
360
|
let completions: string[] = await this.classNamesPromise;
|
|
361
361
|
const classesMap = this.nodeClasses((selectedNode));
|
|
362
|
-
|
|
362
|
+
const existingClasses = new Set(expression.split(/[,\s]/).map(className => className.trim()).filter(Boolean));
|
|
363
|
+
completions = completions.filter(value => !classesMap.get(value) && !existingClasses.has(value));
|
|
363
364
|
|
|
364
365
|
if (prefix[0] === '.') {
|
|
365
366
|
completions = completions.map(value => '.' + value);
|
|
@@ -9,9 +9,9 @@ import * as UI from '../../ui/legacy/legacy.js';
|
|
|
9
9
|
import * as Emulation from '../emulation/emulation.js';
|
|
10
10
|
|
|
11
11
|
import {canGetJSPath} from './DOMPath.js';
|
|
12
|
+
import type {DOMTreeWidget} from './DOMTreeWidget.js';
|
|
12
13
|
import {ElementsPanel} from './ElementsPanel.js';
|
|
13
14
|
import {ElementsTreeElement} from './ElementsTreeElement.js';
|
|
14
|
-
import type {DOMTreeWidget} from './ElementsTreeOutline.js';
|
|
15
15
|
|
|
16
16
|
const UIStrings = {
|
|
17
17
|
/**
|
|
@@ -75,7 +75,7 @@ import {ImagePreviewPopover} from './ImagePreviewPopover.js';
|
|
|
75
75
|
import {ShortcutTreeElement} from './ShortcutTreeElement.js';
|
|
76
76
|
import {TopLayerContainer} from './TopLayerContainer.js';
|
|
77
77
|
|
|
78
|
-
const {html, nothing, render, Directives: {classMap, repeat, styleMap}} = Lit;
|
|
78
|
+
const {html, nothing, render, Directives: {classMap, ifDefined, repeat, styleMap}} = Lit;
|
|
79
79
|
|
|
80
80
|
const UIStrings = {
|
|
81
81
|
/**
|
|
@@ -101,7 +101,7 @@ const UIStrings = {
|
|
|
101
101
|
*/
|
|
102
102
|
reveal: 'reveal',
|
|
103
103
|
} as const;
|
|
104
|
-
const str_ = i18n.i18n.registerUIStrings('panels/elements/
|
|
104
|
+
const str_ = i18n.i18n.registerUIStrings('panels/elements/DOMTreeWidget.ts', UIStrings);
|
|
105
105
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
106
106
|
const elementsTreeOutlineByDOMModel = new WeakMap<SDK.DOMModel.DOMModel, ElementsTreeOutline>();
|
|
107
107
|
|
|
@@ -919,6 +919,8 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
|
|
|
919
919
|
// clang-format off
|
|
920
920
|
return html`
|
|
921
921
|
<li role="treeitem"
|
|
922
|
+
data-backend-node-id=${ifDefined(node.backendNodeId())}
|
|
923
|
+
data-target-id=${ifDefined(node.domModel().target().id())}
|
|
922
924
|
selectable=${input.selectEnabled ? 'true' : 'false'}
|
|
923
925
|
?selected=${isSelected && !input.selectedClosingTag}
|
|
924
926
|
class=${classes}
|
|
@@ -997,6 +999,8 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
|
|
|
997
999
|
${node instanceof SDK.DOMModel.DOMDocument ? renderTopLayerContainer(node, depth + 1) : nothing}
|
|
998
1000
|
${needsClosingTag ? html`
|
|
999
1001
|
<li role="treeitem"
|
|
1002
|
+
data-backend-node-id=${ifDefined(node.backendNodeId())}
|
|
1003
|
+
data-target-id=${ifDefined(node.domModel().target().id())}
|
|
1000
1004
|
selectable=${input.selectEnabled ? 'true' : 'false'}
|
|
1001
1005
|
?selected=${isSelected && Boolean(input.selectedClosingTag)}
|
|
1002
1006
|
class=${classMap({
|
|
@@ -1348,7 +1352,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
1348
1352
|
element?: HTMLElement,
|
|
1349
1353
|
[changeTracker]:
|
|
1350
1354
|
UI.Widget.WidgetDependencies<typeof DOMTreeWidget>|[ChangeTracker.ChangeTracker.ChangeTracker?] = [],
|
|
1351
|
-
view: View =
|
|
1355
|
+
view: View = DECLARATIVE_VIEW,
|
|
1352
1356
|
) {
|
|
1353
1357
|
super(element, {
|
|
1354
1358
|
useShadowDom: false,
|
|
@@ -1358,12 +1362,12 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
1358
1362
|
this.#changeTracker = changeTracker;
|
|
1359
1363
|
this.#showHTMLCommentsSetting.addChangeListener(this.#onShowHTMLCommentsChange, this);
|
|
1360
1364
|
if (Common.Settings.Settings.instance().moduleSetting('highlight-node-on-hover-in-overlay').get()) {
|
|
1361
|
-
SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
SDK.TargetManager.TargetManager.instance().addModelListener(
|
|
1365
|
-
|
|
1366
|
-
|
|
1365
|
+
SDK.TargetManager.TargetManager.instance().addModelListener(SDK.OverlayModel.OverlayModel,
|
|
1366
|
+
SDK.OverlayModel.Events.HIGHLIGHT_NODE_REQUESTED,
|
|
1367
|
+
this.#highlightNode, this, {scoped: true});
|
|
1368
|
+
SDK.TargetManager.TargetManager.instance().addModelListener(SDK.OverlayModel.OverlayModel,
|
|
1369
|
+
SDK.OverlayModel.Events.INSPECT_MODE_WILL_BE_TOGGLED,
|
|
1370
|
+
this.#clearHighlightedNode, this, {scoped: true});
|
|
1367
1371
|
}
|
|
1368
1372
|
this.#setupPopovers();
|
|
1369
1373
|
}
|
|
@@ -2245,7 +2249,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
2245
2249
|
this.onDocumentUpdated(domModel);
|
|
2246
2250
|
} else {
|
|
2247
2251
|
void domModel.requestDocument().then(document => {
|
|
2248
|
-
if (document && this.isShowing()) {
|
|
2252
|
+
if (document && this.isShowing() && this.#wiredDOMModels.has(domModel)) {
|
|
2249
2253
|
this.rootDOMNode = document;
|
|
2250
2254
|
this.onDocumentUpdated(domModel);
|
|
2251
2255
|
}
|
|
@@ -2269,6 +2273,12 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
2269
2273
|
this.#wiredDOMModels.delete(domModel);
|
|
2270
2274
|
this.#unwireDOMModel(domModel);
|
|
2271
2275
|
}
|
|
2276
|
+
if (this.#rootDOMNode?.domModel() === domModel) {
|
|
2277
|
+
this.#rootDOMNode = null;
|
|
2278
|
+
this.#selectedDOMNode = null;
|
|
2279
|
+
this.#expandedNodes.clear();
|
|
2280
|
+
this.#updateRecords.clear();
|
|
2281
|
+
}
|
|
2272
2282
|
this.performUpdate();
|
|
2273
2283
|
return;
|
|
2274
2284
|
}
|
|
@@ -3141,7 +3151,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
3141
3151
|
this.onDocumentUpdated(domModel);
|
|
3142
3152
|
} else if (this.#view === DECLARATIVE_VIEW) {
|
|
3143
3153
|
void domModel.requestDocument().then(document => {
|
|
3144
|
-
if (document && this.isShowing()) {
|
|
3154
|
+
if (document && this.isShowing() && this.#wiredDOMModels.has(domModel)) {
|
|
3145
3155
|
this.rootDOMNode = document;
|
|
3146
3156
|
this.onDocumentUpdated(domModel);
|
|
3147
3157
|
}
|
|
@@ -3472,8 +3482,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
3472
3482
|
}
|
|
3473
3483
|
|
|
3474
3484
|
selectedNodeChanged(focus: boolean): void {
|
|
3475
|
-
this.dispatchEventToListeners(
|
|
3476
|
-
|
|
3485
|
+
this.dispatchEventToListeners(ElementsTreeOutline.Events.SelectedNodeChanged,
|
|
3486
|
+
{node: this.selectedDOMNodeInternal, focus});
|
|
3477
3487
|
}
|
|
3478
3488
|
|
|
3479
3489
|
private fireElementsTreeUpdated(nodes: SDK.DOMModel.DOMNode[]): void {
|
|
@@ -3787,8 +3797,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
3787
3797
|
domModel.addEventListener(SDK.DOMModel.Events.DocumentURLChanged, this.documentURLChanged, this);
|
|
3788
3798
|
domModel.addEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
|
|
3789
3799
|
domModel.addEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
|
|
3790
|
-
domModel.addEventListener(
|
|
3791
|
-
|
|
3800
|
+
domModel.addEventListener(SDK.DOMModel.Events.AffectedByStartingStylesFlagUpdated,
|
|
3801
|
+
this.affectedByStartingStylesFlagUpdated, this);
|
|
3792
3802
|
domModel.addEventListener(SDK.DOMModel.Events.AdoptedStyleSheetsModified, this.adoptedStyleSheetsModified, this);
|
|
3793
3803
|
}
|
|
3794
3804
|
|
|
@@ -3803,8 +3813,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
3803
3813
|
domModel.removeEventListener(SDK.DOMModel.Events.DocumentURLChanged, this.documentURLChanged, this);
|
|
3804
3814
|
domModel.removeEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
|
|
3805
3815
|
domModel.removeEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
|
|
3806
|
-
domModel.removeEventListener(
|
|
3807
|
-
|
|
3816
|
+
domModel.removeEventListener(SDK.DOMModel.Events.AffectedByStartingStylesFlagUpdated,
|
|
3817
|
+
this.affectedByStartingStylesFlagUpdated, this);
|
|
3808
3818
|
domModel.removeEventListener(SDK.DOMModel.Events.AdoptedStyleSheetsModified, this.adoptedStyleSheetsModified, this);
|
|
3809
3819
|
elementsTreeOutlineByDOMModel.delete(domModel);
|
|
3810
3820
|
}
|
|
@@ -4026,8 +4036,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
4026
4036
|
return false;
|
|
4027
4037
|
}
|
|
4028
4038
|
|
|
4029
|
-
private createElementTreeElement(node: SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[],
|
|
4030
|
-
|
|
4039
|
+
private createElementTreeElement(node: SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[],
|
|
4040
|
+
isClosingTag?: boolean): UI.TreeOutline.TreeElement {
|
|
4031
4041
|
if (node instanceof Array) {
|
|
4032
4042
|
return new AdoptedStyleSheetSetTreeElement(node);
|
|
4033
4043
|
}
|
|
@@ -4202,9 +4212,9 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
4202
4212
|
this.#updateChildren(treeElement);
|
|
4203
4213
|
}
|
|
4204
4214
|
|
|
4205
|
-
insertChildElement(
|
|
4206
|
-
|
|
4207
|
-
|
|
4215
|
+
insertChildElement(treeElement: ElementsTreeElement|TopLayerContainer,
|
|
4216
|
+
child: SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[], index: number,
|
|
4217
|
+
isClosingTag?: boolean): UI.TreeOutline.TreeElement {
|
|
4208
4218
|
const newElement = this.createElementTreeElement(child, isClosingTag);
|
|
4209
4219
|
treeElement.insertChild(newElement, index);
|
|
4210
4220
|
return newElement;
|
|
@@ -4237,8 +4247,8 @@ export class ElementsTreeOutline extends ElementsTreeOutlineBase {
|
|
|
4237
4247
|
|
|
4238
4248
|
// Remove any tree elements that no longer have this node as their parent and save
|
|
4239
4249
|
// all existing elements that could be reused. This also removes closing tag element.
|
|
4240
|
-
const existingTreeElements = new Map<
|
|
4241
|
-
|
|
4250
|
+
const existingTreeElements = new Map<SDK.DOMModel.DOMNode|SDK.DOMModel.AdoptedStyleSheet[],
|
|
4251
|
+
UI.TreeOutline.TreeElement&ElementsTreeElement>();
|
|
4242
4252
|
for (let i = treeElement.childCount() - 1; i >= 0; --i) {
|
|
4243
4253
|
const existingTreeElement = treeElement.childAt(i);
|
|
4244
4254
|
if (!(existingTreeElement instanceof ElementsTreeElement)) {
|
|
@@ -51,8 +51,8 @@ import {AccessibilityTreeView} from './AccessibilityTreeView.js';
|
|
|
51
51
|
import {ColorSwatchPopoverIcon} from './ColorSwatchPopoverIcon.js';
|
|
52
52
|
import * as ElementsComponents from './components/components.js';
|
|
53
53
|
import {ComputedStyleWidget} from './ComputedStyleWidget.js';
|
|
54
|
+
import {DOMTreeWidget, type ElementsTreeOutline} from './DOMTreeWidget.js';
|
|
54
55
|
import elementsPanelStyles from './elementsPanel.css.js';
|
|
55
|
-
import {DOMTreeWidget, type ElementsTreeOutline} from './ElementsTreeOutline.js';
|
|
56
56
|
import {LayoutPane} from './LayoutPane.js';
|
|
57
57
|
import type {MarkerDecorator} from './MarkerDecorator.js';
|
|
58
58
|
import {MetricsSidebarPane} from './MetricsSidebarPane.js';
|
|
@@ -67,10 +67,10 @@ import * as Media from '../media/media.js';
|
|
|
67
67
|
|
|
68
68
|
import * as ElementsComponents from './components/components.js';
|
|
69
69
|
import {cssPath} from './DOMPath.js';
|
|
70
|
+
import {type ElementsTreeOutline, MappedCharToEntity} from './DOMTreeWidget.js';
|
|
70
71
|
import {getElementIssueDetails} from './ElementIssueUtils.js';
|
|
71
72
|
import {ElementsPanel} from './ElementsPanel.js';
|
|
72
73
|
import * as ElementStatePaneWidget from './ElementStatePaneWidget.js';
|
|
73
|
-
import {type ElementsTreeOutline, MappedCharToEntity} from './ElementsTreeOutline.js';
|
|
74
74
|
import {ImagePreviewPopover} from './ImagePreviewPopover.js';
|
|
75
75
|
import {getRegisteredDecorators, type MarkerDecorator, type MarkerDecoratorRegistration} from './MarkerDecorator.js';
|
|
76
76
|
|
|
@@ -40,8 +40,8 @@ import * as Lit from '../../ui/lit/lit.js';
|
|
|
40
40
|
import * as VisualElements from '../../ui/visual_logging/visual_logging.js';
|
|
41
41
|
|
|
42
42
|
import * as ElementsComponents from './components/components.js';
|
|
43
|
+
import {ElementsTreeOutline} from './DOMTreeWidget.js';
|
|
43
44
|
import {adornerRef, ElementsTreeElement, handleAdornerKeydown} from './ElementsTreeElement.js';
|
|
44
|
-
import {ElementsTreeOutline} from './ElementsTreeOutline.js';
|
|
45
45
|
|
|
46
46
|
const {html, render} = Lit;
|
|
47
47
|
|
|
@@ -304,6 +304,7 @@ export class StylePropertiesSection {
|
|
|
304
304
|
closeBrace.createChild('span').textContent = '}';
|
|
305
305
|
} else {
|
|
306
306
|
this.titleElement.classList.add('hidden');
|
|
307
|
+
this.updateAncestorRuleList();
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
if (rule) {
|
|
@@ -425,6 +426,7 @@ export class StylePropertiesSection {
|
|
|
425
426
|
this.computedStyleExtraFields = computedStyleExtraFields;
|
|
426
427
|
this.#lastInheritedNode = matchedStyles.isInherited(style) ? matchedStyles.nodeForStyle(style) : null;
|
|
427
428
|
this.update(true);
|
|
429
|
+
this.updateCollapsedState();
|
|
428
430
|
}
|
|
429
431
|
|
|
430
432
|
inheritedNode(): SDK.DOMModel.DOMNode|null {
|
|
@@ -1250,6 +1252,14 @@ export class StylePropertiesSection {
|
|
|
1250
1252
|
this.#ancestorClosingBracesElement.removeChildren();
|
|
1251
1253
|
this.maybeCreateAncestorRules(this.styleInternal);
|
|
1252
1254
|
this.#styleRuleElement.style.paddingLeft = `${this.nestingLevel}ch`;
|
|
1255
|
+
if (this.headerText().length === 0 && (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule)) {
|
|
1256
|
+
const lastAncestor = this.#ancestorRuleListElement.lastElementChild;
|
|
1257
|
+
if (lastAncestor && this.#collapseIcon && this.#statusElement) {
|
|
1258
|
+
this.#collapseIcon.slot = 'indent';
|
|
1259
|
+
lastAncestor.append(this.#collapseIcon, this.#statusElement);
|
|
1260
|
+
}
|
|
1261
|
+
this.#ancestorClosingBracesElement.firstElementChild?.classList.add('sidebar-pane-closing-brace');
|
|
1262
|
+
}
|
|
1253
1263
|
}
|
|
1254
1264
|
|
|
1255
1265
|
isPropertyInherited(propertyName: string): boolean {
|