chrome-devtools-frontend 1.0.1016605 → 1.0.1017938

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/config/gni/devtools_grd_files.gni +2 -0
  2. package/front_end/core/i18n/locales/en-US.json +6 -6
  3. package/front_end/core/i18n/locales/en-XL.json +6 -6
  4. package/front_end/core/sdk/DOMModel.ts +11 -0
  5. package/front_end/core/sdk/DebuggerModel.ts +4 -0
  6. package/front_end/core/sdk/FrameManager.ts +36 -15
  7. package/front_end/core/sdk/ResourceTreeModel.ts +88 -6
  8. package/front_end/core/sdk/Script.ts +1 -1
  9. package/front_end/core/sdk/SecurityOriginManager.ts +1 -1
  10. package/front_end/core/sdk/StorageKeyManager.ts +71 -0
  11. package/front_end/core/sdk/sdk.ts +2 -0
  12. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +4 -2
  13. package/front_end/models/issues_manager/DeprecationIssue.ts +5 -2
  14. package/front_end/models/timeline_model/TimelineModel.ts +8 -6
  15. package/front_end/panels/application/ApplicationPanelSidebar.ts +5 -1
  16. package/front_end/panels/application/DOMStorageModel.ts +138 -10
  17. package/front_end/panels/application/StorageView.ts +64 -5
  18. package/front_end/panels/application/components/FrameDetailsView.ts +31 -5
  19. package/front_end/panels/elements/ElementsTreeElement.ts +25 -37
  20. package/front_end/panels/elements/ElementsTreeOutline.ts +44 -8
  21. package/front_end/panels/elements/TopLayerContainer.ts +97 -0
  22. package/front_end/panels/elements/components/AdornerManager.ts +7 -0
  23. package/front_end/panels/elements/elements.ts +4 -0
  24. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +7 -0
  25. package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
  26. package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +5 -6
  27. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +5 -3
  28. package/package.json +1 -1
@@ -603,6 +603,7 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
603
603
 
604
604
  private addDOMStorage(domStorage: DOMStorage): void {
605
605
  console.assert(!this.domStorageTreeElements.get(domStorage));
606
+ console.assert(Boolean(domStorage.storageKey) || Boolean(domStorage.securityOrigin));
606
607
 
607
608
  const domStorageTreeElement = new DOMStorageTreeElement(this.panel, domStorage);
608
609
  this.domStorageTreeElements.set(domStorage, domStorageTreeElement);
@@ -1422,7 +1423,10 @@ export class DOMStorageTreeElement extends ApplicationPanelTreeElement {
1422
1423
  private readonly domStorage: DOMStorage;
1423
1424
  constructor(storagePanel: ResourcesPanel, domStorage: DOMStorage) {
1424
1425
  super(
1425
- storagePanel, domStorage.securityOrigin ? domStorage.securityOrigin : i18nString(UIStrings.localFiles), false);
1426
+ storagePanel,
1427
+ domStorage.securityOrigin ? domStorage.securityOrigin :
1428
+ (domStorage.storageKey ? domStorage.storageKey : i18nString(UIStrings.localFiles)),
1429
+ false);
1426
1430
  this.domStorage = domStorage;
1427
1431
  const icon = UI.Icon.Icon.create('mediumicon-table', 'resource-tree-item');
1428
1432
  this.setLeadingIcons([icon]);
@@ -38,13 +38,15 @@ import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
38
38
 
39
39
  export class DOMStorage extends Common.ObjectWrapper.ObjectWrapper<DOMStorage.EventTypes> {
40
40
  private readonly model: DOMStorageModel;
41
- private readonly securityOriginInternal: string;
41
+ private readonly securityOriginInternal: string|null;
42
+ private readonly storageKeyInternal: string|null;
42
43
  private readonly isLocalStorageInternal: boolean;
43
44
 
44
- constructor(model: DOMStorageModel, securityOrigin: string, isLocalStorage: boolean) {
45
+ constructor(model: DOMStorageModel, securityOrigin: string, storageKey: string, isLocalStorage: boolean) {
45
46
  super();
46
47
  this.model = model;
47
48
  this.securityOriginInternal = securityOrigin;
49
+ this.storageKeyInternal = storageKey;
48
50
  this.isLocalStorageInternal = isLocalStorage;
49
51
  }
50
52
 
@@ -52,14 +54,46 @@ export class DOMStorage extends Common.ObjectWrapper.ObjectWrapper<DOMStorage.Ev
52
54
  return {securityOrigin: securityOrigin, isLocalStorage: isLocalStorage};
53
55
  }
54
56
 
57
+ static storageIdWithSecurityOrigin(securityOrigin: string, isLocalStorage: boolean): Protocol.DOMStorage.StorageId {
58
+ return {securityOrigin: securityOrigin, isLocalStorage: isLocalStorage};
59
+ }
60
+
61
+ static storageIdWithStorageKey(storageKey: string, isLocalStorage: boolean): Protocol.DOMStorage.StorageId {
62
+ return {storageKey: storageKey, isLocalStorage: isLocalStorage};
63
+ }
64
+
65
+ get idWithSecurityOrigin(): Protocol.DOMStorage.StorageId {
66
+ let securityOrigin = '';
67
+ if (this.securityOriginInternal) {
68
+ securityOrigin = this.securityOriginInternal;
69
+ }
70
+ return DOMStorage.storageIdWithSecurityOrigin(securityOrigin, this.isLocalStorageInternal);
71
+ }
72
+
73
+ get idWithStorageKey(): Protocol.DOMStorage.StorageId {
74
+ let storageKey = '';
75
+ if (this.storageKeyInternal) {
76
+ storageKey = this.storageKeyInternal;
77
+ }
78
+ return DOMStorage.storageIdWithStorageKey(storageKey, this.isLocalStorageInternal);
79
+ }
80
+
55
81
  get id(): Protocol.DOMStorage.StorageId {
56
- return DOMStorage.storageId(this.securityOriginInternal, this.isLocalStorageInternal);
82
+ // TODO(crbug.com/1313434) Prioritize storageKey once everything is ready
83
+ if (this.securityOriginInternal) {
84
+ return this.idWithSecurityOrigin;
85
+ }
86
+ return this.idWithStorageKey;
57
87
  }
58
88
 
59
- get securityOrigin(): string {
89
+ get securityOrigin(): string|null {
60
90
  return this.securityOriginInternal;
61
91
  }
62
92
 
93
+ get storageKey(): string|null {
94
+ return this.storageKeyInternal;
95
+ }
96
+
63
97
  get isLocalStorage(): boolean {
64
98
  return this.isLocalStorageInternal;
65
99
  }
@@ -116,6 +150,7 @@ export namespace DOMStorage {
116
150
 
117
151
  export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
118
152
  private readonly securityOriginManager: SDK.SecurityOriginManager.SecurityOriginManager|null;
153
+ private readonly storageKeyManagerInternal: SDK.StorageKeyManager.StorageKeyManager|null;
119
154
  private storagesInternal: {
120
155
  [x: string]: DOMStorage,
121
156
  };
@@ -126,10 +161,15 @@ export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
126
161
  super(target);
127
162
 
128
163
  this.securityOriginManager = target.model(SDK.SecurityOriginManager.SecurityOriginManager);
164
+ this.storageKeyManagerInternal = target.model(SDK.StorageKeyManager.StorageKeyManager);
129
165
  this.storagesInternal = {};
130
166
  this.agent = target.domstorageAgent();
131
167
  }
132
168
 
169
+ get storageKeyManagerForTest(): SDK.StorageKeyManager.StorageKeyManager|null {
170
+ return this.storageKeyManagerInternal;
171
+ }
172
+
133
173
  enable(): void {
134
174
  if (this.enabled) {
135
175
  return;
@@ -146,6 +186,16 @@ export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
146
186
  this.addOrigin(securityOrigin);
147
187
  }
148
188
  }
189
+ if (this.storageKeyManagerInternal) {
190
+ this.storageKeyManagerInternal.addEventListener(
191
+ SDK.StorageKeyManager.Events.StorageKeyAdded, this.storageKeyAdded, this);
192
+ this.storageKeyManagerInternal.addEventListener(
193
+ SDK.StorageKeyManager.Events.StorageKeyRemoved, this.storageKeyRemoved, this);
194
+
195
+ for (const storageKey of this.storageKeyManagerInternal.storageKeys()) {
196
+ this.addStorageKey(storageKey);
197
+ }
198
+ }
149
199
  void this.agent.invoke_enable();
150
200
 
151
201
  this.enabled = true;
@@ -156,7 +206,7 @@ export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
156
206
  return;
157
207
  }
158
208
  for (const isLocal of [true, false]) {
159
- const key = this.storageKey(origin, isLocal);
209
+ const key = this.keyForSecurityOrigin(origin, isLocal);
160
210
  const storage = this.storagesInternal[key];
161
211
  if (!storage) {
162
212
  return;
@@ -167,10 +217,30 @@ export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
167
217
  this.addOrigin(origin);
168
218
  }
169
219
 
220
+ clearForStorageKey(storageKey: string): void {
221
+ if (!this.enabled) {
222
+ return;
223
+ }
224
+ for (const isLocal of [true, false]) {
225
+ const key = this.keyForStorageKey(storageKey, isLocal);
226
+ const storage = this.storagesInternal[key];
227
+ if (!storage) {
228
+ return;
229
+ }
230
+ storage.clear();
231
+ }
232
+ this.removeStorageKey(storageKey);
233
+ this.addStorageKey(storageKey);
234
+ }
235
+
170
236
  private securityOriginAdded(event: Common.EventTarget.EventTargetEvent<string>): void {
171
237
  this.addOrigin(event.data);
172
238
  }
173
239
 
240
+ private storageKeyAdded(event: Common.EventTarget.EventTargetEvent<string>): void {
241
+ this.addStorageKey(event.data);
242
+ }
243
+
174
244
  private addOrigin(securityOrigin: string): void {
175
245
  const parsed = new Common.ParsedURL.ParsedURL(securityOrigin);
176
246
  // These are "opaque" origins which are not supposed to support DOM storage.
@@ -179,21 +249,67 @@ export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
179
249
  }
180
250
 
181
251
  for (const isLocal of [true, false]) {
182
- const key = this.storageKey(securityOrigin, isLocal);
252
+ const key = this.keyForSecurityOrigin(securityOrigin, isLocal);
183
253
  console.assert(!this.storagesInternal[key]);
184
- const storage = new DOMStorage(this, securityOrigin, isLocal);
254
+ if (this.duplicateExists(key)) {
255
+ continue;
256
+ }
257
+ const storage = new DOMStorage(this, securityOrigin, '', isLocal);
258
+ this.storagesInternal[key] = storage;
259
+ this.dispatchEventToListeners(Events.DOMStorageAdded, storage);
260
+ }
261
+ }
262
+
263
+ private addStorageKey(storageKey: string): void {
264
+ for (const isLocal of [true, false]) {
265
+ const key = this.keyForStorageKey(storageKey, isLocal);
266
+ console.assert(!this.storagesInternal[key]);
267
+ if (this.duplicateExists(key)) {
268
+ continue;
269
+ }
270
+ const storage = new DOMStorage(this, '', storageKey, isLocal);
185
271
  this.storagesInternal[key] = storage;
186
272
  this.dispatchEventToListeners(Events.DOMStorageAdded, storage);
187
273
  }
188
274
  }
189
275
 
276
+ private duplicateExists(key: string): boolean {
277
+ const parsedKey = JSON.parse(key);
278
+ for (const storageInternal in this.storagesInternal) {
279
+ const parsedStorageInternalKey = JSON.parse(storageInternal);
280
+ if (parsedKey.isLocalStorage === parsedStorageInternalKey.isLocalStorage) {
281
+ if (parsedKey.storageKey?.slice(0, -1) === parsedStorageInternalKey.securityOrigin ||
282
+ parsedKey.securityOrigin === parsedStorageInternalKey.storageKey?.slice(0, -1)) {
283
+ return true;
284
+ }
285
+ }
286
+ }
287
+ return false;
288
+ }
289
+
190
290
  private securityOriginRemoved(event: Common.EventTarget.EventTargetEvent<string>): void {
191
291
  this.removeOrigin(event.data);
192
292
  }
193
293
 
294
+ private storageKeyRemoved(event: Common.EventTarget.EventTargetEvent<string>): void {
295
+ this.removeStorageKey(event.data);
296
+ }
297
+
194
298
  private removeOrigin(securityOrigin: string): void {
195
299
  for (const isLocal of [true, false]) {
196
- const key = this.storageKey(securityOrigin, isLocal);
300
+ const key = this.keyForSecurityOrigin(securityOrigin, isLocal);
301
+ const storage = this.storagesInternal[key];
302
+ if (!storage) {
303
+ continue;
304
+ }
305
+ delete this.storagesInternal[key];
306
+ this.dispatchEventToListeners(Events.DOMStorageRemoved, storage);
307
+ }
308
+ }
309
+
310
+ private removeStorageKey(storageKey: string): void {
311
+ for (const isLocal of [true, false]) {
312
+ const key = this.keyForStorageKey(storageKey, isLocal);
197
313
  const storage = this.storagesInternal[key];
198
314
  if (!storage) {
199
315
  continue;
@@ -203,8 +319,20 @@ export class DOMStorageModel extends SDK.SDKModel.SDKModel<EventTypes> {
203
319
  }
204
320
  }
205
321
 
206
- private storageKey(securityOrigin: string, isLocalStorage: boolean): string {
207
- return JSON.stringify(DOMStorage.storageId(securityOrigin, isLocalStorage));
322
+ private storageKey(securityOrigin: string, storageKey: string, isLocalStorage: boolean): string {
323
+ // TODO(crbug.com/1313434) Prioritize storageKey once everything is ready
324
+ if (securityOrigin) {
325
+ return JSON.stringify(DOMStorage.storageIdWithSecurityOrigin(securityOrigin, isLocalStorage));
326
+ }
327
+ return JSON.stringify(DOMStorage.storageIdWithStorageKey(storageKey, isLocalStorage));
328
+ }
329
+
330
+ private keyForSecurityOrigin(securityOrigin: string, isLocalStorage: boolean): string {
331
+ return this.storageKey(securityOrigin, '', isLocalStorage);
332
+ }
333
+
334
+ private keyForStorageKey(storageKey: string, isLocalStorage: boolean): string {
335
+ return this.storageKey('', storageKey, isLocalStorage);
208
336
  }
209
337
 
210
338
  domStorageItemsCleared(storageId: Protocol.DOMStorage.StorageId): void {
@@ -147,6 +147,7 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
147
147
  private reportView: UI.ReportView.ReportView;
148
148
  private target: SDK.Target.Target|null;
149
149
  private securityOrigin: string|null;
150
+ private storageKey: string|null;
150
151
  private settings: Map<Protocol.Storage.StorageType, Common.Settings.Setting<boolean>>;
151
152
  private includeThirdPartyCookiesSetting: Common.Settings.Setting<boolean>;
152
153
  private quotaRow: HTMLElement;
@@ -180,6 +181,7 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
180
181
  this.reportView.show(this.contentElement);
181
182
  this.target = null;
182
183
  this.securityOrigin = null;
184
+ this.storageKey = null;
183
185
 
184
186
  this.settings = new Map();
185
187
  for (const type of AllStorageTypes) {
@@ -277,6 +279,11 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
277
279
  securityOriginManager.mainSecurityOrigin(), securityOriginManager.unreachableMainSecurityOrigin());
278
280
  securityOriginManager.addEventListener(
279
281
  SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, this.originChanged, this);
282
+ const storageKeyManager =
283
+ target.model(SDK.StorageKeyManager.StorageKeyManager) as SDK.StorageKeyManager.StorageKeyManager;
284
+ this.updateStorageKey(storageKeyManager.mainStorageKey());
285
+ storageKeyManager.addEventListener(
286
+ SDK.StorageKeyManager.Events.MainStorageKeyChanged, this.storageKeyChanged, this);
280
287
  }
281
288
 
282
289
  targetRemoved(target: SDK.Target.Target): void {
@@ -287,6 +294,10 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
287
294
  SDK.SecurityOriginManager.SecurityOriginManager;
288
295
  securityOriginManager.removeEventListener(
289
296
  SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, this.originChanged, this);
297
+ const storageKeyManager =
298
+ target.model(SDK.StorageKeyManager.StorageKeyManager) as SDK.StorageKeyManager.StorageKeyManager;
299
+ storageKeyManager.removeEventListener(
300
+ SDK.StorageKeyManager.Events.MainStorageKeyChanged, this.storageKeyChanged, this);
290
301
  }
291
302
 
292
303
  private originChanged(
@@ -295,6 +306,12 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
295
306
  this.updateOrigin(mainSecurityOrigin, unreachableMainSecurityOrigin);
296
307
  }
297
308
 
309
+ private storageKeyChanged(
310
+ event: Common.EventTarget.EventTargetEvent<SDK.StorageKeyManager.MainStorageKeyChangedEvent>): void {
311
+ const {mainStorageKey} = event.data;
312
+ this.updateStorageKey(mainStorageKey);
313
+ }
314
+
298
315
  private updateOrigin(mainOrigin: string, unreachableMainOrigin: string|null): void {
299
316
  const oldOrigin = this.securityOrigin;
300
317
  if (unreachableMainOrigin) {
@@ -313,6 +330,20 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
313
330
  void this.doUpdate();
314
331
  }
315
332
 
333
+ private updateStorageKey(mainStorageKey: string): void {
334
+ const oldStorageKey = this.storageKey;
335
+
336
+ this.storageKey = mainStorageKey;
337
+ this.reportView.setSubtitle(mainStorageKey);
338
+
339
+ if (oldStorageKey !== this.storageKey) {
340
+ this.quotaOverrideControlRow.classList.add('hidden');
341
+ this.quotaOverrideCheckbox.checkboxElement.checked = false;
342
+ this.quotaOverrideErrorMessage.textContent = '';
343
+ }
344
+ void this.doUpdate();
345
+ }
346
+
316
347
  private async applyQuotaOverrideFromInputField(): Promise<void> {
317
348
  if (!this.target || !this.securityOrigin) {
318
349
  this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.internalError);
@@ -375,7 +406,12 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
375
406
 
376
407
  if (this.target) {
377
408
  const includeThirdPartyCookies = this.includeThirdPartyCookiesSetting.get();
378
- StorageView.clear(this.target, this.securityOrigin, selectedStorageTypes, includeThirdPartyCookies);
409
+ // TODO(crbug.com/1313434) Prioritize storageKey once everything is ready
410
+ if (this.securityOrigin) {
411
+ StorageView.clear(this.target, this.securityOrigin, selectedStorageTypes, includeThirdPartyCookies);
412
+ } else if (this.storageKey) {
413
+ StorageView.clearByStorageKey(this.target, this.storageKey, selectedStorageTypes);
414
+ }
379
415
  }
380
416
 
381
417
  this.clearButton.disabled = true;
@@ -436,6 +472,20 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
436
472
  }
437
473
  }
438
474
 
475
+ static clearByStorageKey(target: SDK.Target.Target, storageKey: string, selectedStorageTypes: string[]): void {
476
+ // TODO(crbug.com/1313434) Invoke protocol `clear` once it ready for storageKey
477
+
478
+ const set = new Set(selectedStorageTypes);
479
+ const hasAll = set.has(Protocol.Storage.StorageType.All);
480
+
481
+ if (set.has(Protocol.Storage.StorageType.Local_storage) || hasAll) {
482
+ const storageModel = target.model(DOMStorageModel);
483
+ if (storageModel) {
484
+ storageModel.clearForStorageKey(storageKey);
485
+ }
486
+ }
487
+ }
488
+
439
489
  async doUpdate(): Promise<void> {
440
490
  if (!this.securityOrigin || !this.target) {
441
491
  this.quotaRow.textContent = '';
@@ -556,6 +606,14 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
556
606
  return false;
557
607
  }
558
608
 
609
+ private async clear(target: SDK.Target.Target, resourceTreeModel: SDK.ResourceTreeModel.ResourceTreeModel):
610
+ Promise<void> {
611
+ const storageKey = await resourceTreeModel.getMainStorageKey();
612
+ if (storageKey) {
613
+ StorageView.clearByStorageKey(target, storageKey, AllStorageTypes);
614
+ }
615
+ }
616
+
559
617
  private handleClear(includeThirdPartyCookies: boolean): boolean {
560
618
  const target = SDK.TargetManager.TargetManager.instance().mainTarget();
561
619
  if (!target) {
@@ -566,11 +624,12 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
566
624
  return false;
567
625
  }
568
626
  const securityOrigin = resourceTreeModel.getMainSecurityOrigin();
569
- if (!securityOrigin) {
570
- return false;
627
+ // TODO(crbug.com/1313434) Prioritize storageKey functionality once everything is ready
628
+ if (securityOrigin) {
629
+ StorageView.clear(target, securityOrigin, AllStorageTypes, includeThirdPartyCookies);
630
+ return true;
571
631
  }
572
-
573
- StorageView.clear(target, securityOrigin, AllStorageTypes, includeThirdPartyCookies);
632
+ void this.clear(target, resourceTreeModel);
574
633
  return true;
575
634
  }
576
635
  }
@@ -10,7 +10,7 @@ import * as Bindings from '../../../models/bindings/bindings.js';
10
10
  import * as Common from '../../../core/common/common.js';
11
11
  import * as i18n from '../../../core/i18n/i18n.js';
12
12
  import * as NetworkForward from '../../../panels/network/forward/forward.js';
13
- import type * as Platform from '../../../core/platform/platform.js';
13
+ import * as Platform from '../../../core/platform/platform.js';
14
14
  import * as Root from '../../../core/root/root.js';
15
15
  import * as SDK from '../../../core/sdk/sdk.js';
16
16
  import * as LitHtml from '../../../ui/lit-html/lit-html.js';
@@ -248,6 +248,10 @@ const UIStrings = {
248
248
  *@description Label for subtitle of frame details view
249
249
  */
250
250
  prerenderingStatus: 'Prerendering Status',
251
+ /**
252
+ *@description Label for a link to an ad script, which created the current iframe.
253
+ */
254
+ creatorAdScript: 'Creator Ad Script',
251
255
  };
252
256
  const str_ = i18n.i18n.registerUIStrings('panels/application/components/FrameDetailsView.ts', UIStrings);
253
257
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -266,7 +270,10 @@ export class FrameDetailsView extends UI.ThrottledWidget.ThrottledWidget {
266
270
  }
267
271
 
268
272
  async doUpdate(): Promise<void> {
269
- this.#reportView.data = {frame: this.#frame};
273
+ const debuggerId = this.#frame?.getDebuggerId();
274
+ const debuggerModel = debuggerId ? await SDK.DebuggerModel.DebuggerModel.modelForDebuggerId(debuggerId) : null;
275
+ const target = debuggerModel?.target();
276
+ this.#reportView.data = {frame: this.#frame, target};
270
277
  }
271
278
  }
272
279
 
@@ -274,16 +281,19 @@ const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
274
281
 
275
282
  export interface FrameDetailsReportViewData {
276
283
  frame: SDK.ResourceTreeModel.ResourceTreeFrame;
284
+ target?: SDK.Target.Target;
277
285
  }
278
286
 
279
287
  export class FrameDetailsReportView extends HTMLElement {
280
288
  static readonly litTagName = LitHtml.literal`devtools-resources-frame-details-view`;
281
289
  readonly #shadow = this.attachShadow({mode: 'open'});
282
290
  #frame?: SDK.ResourceTreeModel.ResourceTreeFrame;
291
+ #target?: SDK.Target.Target;
283
292
  #protocolMonitorExperimentEnabled = false;
284
293
  #permissionsPolicies: Promise<Protocol.Page.PermissionsPolicyFeatureState[]|null>|null = null;
285
294
  #permissionsPolicySectionData: PermissionsPolicySectionData = {policies: [], showDetails: false};
286
295
  #originTrialTreeView: OriginTrialTreeView = new OriginTrialTreeView();
296
+ #linkifier = new Components.Linkifier.Linkifier();
287
297
 
288
298
  connectedCallback(): void {
289
299
  this.#protocolMonitorExperimentEnabled = Root.Runtime.experiments.isEnabled('protocolMonitor');
@@ -292,6 +302,7 @@ export class FrameDetailsReportView extends HTMLElement {
292
302
 
293
303
  set data(data: FrameDetailsReportViewData) {
294
304
  this.#frame = data.frame;
305
+ this.#target = data.target;
295
306
  if (!this.#permissionsPolicies && this.#frame) {
296
307
  this.#permissionsPolicies = this.#frame.getPermissionsPolicyState();
297
308
  }
@@ -573,14 +584,29 @@ export class FrameDetailsReportView extends HTMLElement {
573
584
  for (const explanation of this.#frame.adFrameStatus()?.explanations || []) {
574
585
  rows.push(LitHtml.html`<div>${this.#getAdFrameExplanationString(explanation)}</div>`);
575
586
  }
587
+
588
+ const adScriptLinkElement = this.#target ?
589
+ this.#linkifier.linkifyScriptLocation(
590
+ this.#target, this.#frame.getAdScriptId(), Platform.DevToolsPath.EmptyUrlString, undefined, undefined) :
591
+ null;
592
+
593
+ // Disabled until https://crbug.com/1079231 is fixed.
594
+ // clang-format off
576
595
  return LitHtml.html`
577
596
  <${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.adStatus)}</${
578
597
  ReportView.ReportView.ReportKey.litTagName}>
579
598
  <${ReportView.ReportView.ReportValue.litTagName}>
580
- <${ExpandableList.ExpandableList.ExpandableList.litTagName} .data=${
581
- {rows} as ExpandableList.ExpandableList.ExpandableListData}></${
599
+ <${ExpandableList.ExpandableList.ExpandableList.litTagName} .data=${
600
+ {rows} as ExpandableList.ExpandableList.ExpandableListData}></${
582
601
  ExpandableList.ExpandableList.ExpandableList.litTagName}></${ReportView.ReportView.ReportValue.litTagName}>
583
- `;
602
+ ${this.#target ? LitHtml.html`
603
+ <${ReportView.ReportView.ReportKey.litTagName}>${i18nString(UIStrings.creatorAdScript)}</${
604
+ ReportView.ReportView.ReportKey.litTagName}>
605
+ <${ReportView.ReportView.ReportValue.litTagName} class="ad-script-link">${adScriptLinkElement}</${
606
+ ReportView.ReportView.ReportValue.litTagName}>
607
+ ` : LitHtml.nothing}
608
+ `;
609
+ // clang-format on
584
610
  }
585
611
 
586
612
  #renderIsolationSection(): LitHtml.LitTemplate {
@@ -88,14 +88,6 @@ const UIStrings = {
88
88
  */
89
89
  scrollIntoView: 'Scroll into view',
90
90
  /**
91
- *@description Text to enter Isolation Mode, a mode with focus on a single element and interactive resizing
92
- */
93
- enterIsolationMode: 'Enter Isolation Mode',
94
- /**
95
- *@description Text to exit Isolation Mode, a mode with focus on a single element and interactive resizing
96
- */
97
- exitIsolationMode: 'Exit Isolation Mode',
98
- /**
99
91
  *@description A context menu item in the Elements Tree Element of the Elements panel
100
92
  */
101
93
  editText: 'Edit text',
@@ -294,7 +286,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
294
286
  if (node.isAdFrameNode()) {
295
287
  const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
296
288
  ElementsComponents.AdornerManager.RegisteredAdorners.AD);
297
- const adorner = this.adorn(config, this.tagTypeContext);
289
+ const adorner = this.adorn(config);
298
290
  UI.Tooltip.Tooltip.install(adorner, i18nString(UIStrings.thisFrameWasIdentifiedAsAnAd));
299
291
  }
300
292
  }
@@ -682,17 +674,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
682
674
  contextMenu.viewSection().appendItem(i18nString(UIStrings.focus), async () => {
683
675
  await this.nodeInternal.focus();
684
676
  });
685
-
686
- const overlayModel = this.nodeInternal.domModel().overlayModel();
687
- if (overlayModel.isHighlightedIsolatedElementInPersistentOverlay(this.nodeInternal.id)) {
688
- contextMenu.viewSection().appendItem(i18nString(UIStrings.exitIsolationMode), () => {
689
- overlayModel.hideIsolatedElementInPersistentOverlay(this.nodeInternal.id);
690
- });
691
- } else {
692
- contextMenu.viewSection().appendItem(i18nString(UIStrings.enterIsolationMode), () => {
693
- overlayModel.highlightIsolatedElementInPersistentOverlay(this.nodeInternal.id);
694
- });
695
- }
696
677
  }
697
678
 
698
679
  populateScrollIntoView(contextMenu: UI.ContextMenu.ContextMenu): void {
@@ -1962,17 +1943,22 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1962
1943
  }
1963
1944
 
1964
1945
  // TODO: add unit tests for adorner-related methods after component and TypeScript works are done
1965
- adorn({name}: {name: string}, context: OpeningTagContext): Adorners.Adorner.Adorner {
1966
- const adornerContent = document.createElement('span');
1967
- adornerContent.textContent = name;
1946
+ adorn({name}: {name: string}, content?: HTMLElement): Adorners.Adorner.Adorner {
1947
+ let adornerContent = content;
1948
+ if (!adornerContent) {
1949
+ adornerContent = document.createElement('span');
1950
+ adornerContent.textContent = name;
1951
+ }
1968
1952
  const adorner = new Adorners.Adorner.Adorner();
1969
1953
  adorner.data = {
1970
1954
  name,
1971
1955
  content: adornerContent,
1972
1956
  };
1973
- context.adorners.push(adorner);
1974
- ElementsPanel.instance().registerAdorner(adorner);
1975
- this.updateAdorners(context);
1957
+ if (isOpeningTag(this.tagTypeContext)) {
1958
+ this.tagTypeContext.adorners.push(adorner);
1959
+ ElementsPanel.instance().registerAdorner(adorner);
1960
+ this.updateAdorners(this.tagTypeContext);
1961
+ }
1976
1962
  return adorner;
1977
1963
  }
1978
1964
 
@@ -2010,14 +1996,16 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2010
1996
  }
2011
1997
  }
2012
1998
 
2013
- removeAllAdorners(context: OpeningTagContext): void {
2014
- for (const adorner of context.adorners) {
2015
- ElementsPanel.instance().deregisterAdorner(adorner);
2016
- adorner.remove();
2017
- }
1999
+ removeAllAdorners(): void {
2000
+ if (isOpeningTag(this.tagTypeContext)) {
2001
+ for (const adorner of this.tagTypeContext.adorners) {
2002
+ ElementsPanel.instance().deregisterAdorner(adorner);
2003
+ adorner.remove();
2004
+ }
2018
2005
 
2019
- context.adorners = [];
2020
- this.updateAdorners(context);
2006
+ this.tagTypeContext.adorners = [];
2007
+ this.updateAdorners(this.tagTypeContext);
2008
+ }
2021
2009
  }
2022
2010
 
2023
2011
  private updateAdorners(context: OpeningTagContext): void {
@@ -2098,7 +2086,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2098
2086
 
2099
2087
  const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
2100
2088
  ElementsComponents.AdornerManager.RegisteredAdorners.GRID);
2101
- const adorner = this.adorn(config, context);
2089
+ const adorner = this.adorn(config);
2102
2090
  adorner.classList.add('grid');
2103
2091
 
2104
2092
  const onClick = (((): void => {
@@ -2135,7 +2123,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2135
2123
  }
2136
2124
  const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
2137
2125
  ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL_SNAP);
2138
- const adorner = this.adorn(config, context);
2126
+ const adorner = this.adorn(config);
2139
2127
  adorner.classList.add('scroll-snap');
2140
2128
 
2141
2129
  const onClick = (((): void => {
@@ -2174,7 +2162,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2174
2162
  }
2175
2163
  const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
2176
2164
  ElementsComponents.AdornerManager.RegisteredAdorners.FLEX);
2177
- const adorner = this.adorn(config, context);
2165
+ const adorner = this.adorn(config);
2178
2166
  adorner.classList.add('flex');
2179
2167
 
2180
2168
  const onClick = (((): void => {
@@ -2213,7 +2201,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
2213
2201
  }
2214
2202
  const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
2215
2203
  ElementsComponents.AdornerManager.RegisteredAdorners.CONTAINER);
2216
- const adorner = this.adorn(config, context);
2204
+ const adorner = this.adorn(config);
2217
2205
  adorner.classList.add('container');
2218
2206
 
2219
2207
  const onClick = (((): void => {