chrome-devtools-frontend 1.0.1016075 → 1.0.1017408

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.
@@ -0,0 +1,97 @@
1
+ // Copyright 2022 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ import * as i18n from '../../core/i18n/i18n.js';
5
+ import * as SDK from '../../core/sdk/sdk.js';
6
+ import * as UI from '../../ui/legacy/legacy.js';
7
+
8
+ import * as ElementsComponents from './components/components.js';
9
+ import * as ElementsTreeOutline from './ElementsTreeOutline.js';
10
+
11
+ import type {ElementsTreeElement} from './ElementsTreeElement.js';
12
+
13
+ const UIStrings = {
14
+ /**
15
+ * @description Top layer is rendered closest to the user within a viewport, therefore its elements always appear on top of all other content
16
+ */
17
+ topLayer: 'top-layer',
18
+ };
19
+
20
+ const str_ = i18n.i18n.registerUIStrings('panels/elements/TopLayerContainer.ts', UIStrings);
21
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
22
+
23
+ export class TopLayerContainer extends UI.TreeOutline.TreeElement {
24
+ treeOutline: ElementsTreeOutline.ElementsTreeOutline|null;
25
+ domModel: SDK.DOMModel.DOMModel;
26
+ currentTopLayerElements: Set<ElementsTreeElement>;
27
+ bodyElement: ElementsTreeElement;
28
+
29
+ constructor(bodyElement: ElementsTreeElement) {
30
+ super('#top-layer');
31
+ this.bodyElement = bodyElement;
32
+ this.domModel = bodyElement.node().domModel();
33
+ this.treeOutline = null;
34
+ this.currentTopLayerElements = new Set();
35
+ }
36
+
37
+ updateBody(bodyElement: ElementsTreeElement): void {
38
+ this.bodyElement = bodyElement;
39
+ }
40
+
41
+ async addTopLayerElementsAsChildren(): Promise<boolean> {
42
+ this.removeCurrentTopLayerElementsAdorners();
43
+ this.currentTopLayerElements = new Set();
44
+ const newTopLayerElementsIDs = await this.domModel.getTopLayerElements();
45
+ if (newTopLayerElementsIDs === null) {
46
+ return false;
47
+ }
48
+ let topLayerElementIndex = 0;
49
+ if (newTopLayerElementsIDs) {
50
+ for (const elementID of newTopLayerElementsIDs) {
51
+ const topLayerDOMNode = this.domModel.idToDOMNode.get(elementID);
52
+ // Will need to add support for backdrop in the future.
53
+ if (topLayerDOMNode && topLayerDOMNode.nodeName() !== '::backdrop') {
54
+ topLayerElementIndex++;
55
+ const topLayerElementShortcut = new SDK.DOMModel.DOMNodeShortcut(
56
+ this.domModel.target(), topLayerDOMNode.backendNodeId(), 0, topLayerDOMNode.nodeName());
57
+ const topLayerTreeElement = this.treeOutline?.treeElementByNode.get(topLayerDOMNode);
58
+ const topLayerElementRepresentation = new ElementsTreeOutline.ShortcutTreeElement(topLayerElementShortcut);
59
+ if (topLayerTreeElement && !this.currentTopLayerElements.has(topLayerTreeElement)) {
60
+ this.appendChild(topLayerElementRepresentation);
61
+ this.addTopLayerAdorner(topLayerTreeElement, topLayerElementRepresentation, topLayerElementIndex);
62
+ this.currentTopLayerElements.add(topLayerTreeElement);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ return topLayerElementIndex > 0;
68
+ }
69
+
70
+ private removeCurrentTopLayerElementsAdorners(): void {
71
+ for (const topLayerElement of this.currentTopLayerElements) {
72
+ topLayerElement.removeAllAdorners();
73
+ }
74
+ }
75
+
76
+ private addTopLayerAdorner(
77
+ element: ElementsTreeElement, topLayerElementRepresentation: ElementsTreeOutline.ShortcutTreeElement,
78
+ topLayerElementIndex: number): void {
79
+ const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
80
+ ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER);
81
+ const adornerContent = document.createElement('span');
82
+ adornerContent.textContent = ` top-layer (${topLayerElementIndex}) `;
83
+ const adorner = element?.adorn(config, adornerContent);
84
+ if (adorner) {
85
+ const onClick = (((): void => {
86
+ topLayerElementRepresentation.revealAndSelect();
87
+ }) as EventListener);
88
+ adorner.addInteraction(onClick, {
89
+ isToggle: false,
90
+ shouldPropagateOnKeydown: false,
91
+ ariaLabelDefault: i18nString(UIStrings.topLayer),
92
+ ariaLabelActive: i18nString(UIStrings.topLayer),
93
+ });
94
+ adorner.addEventListener('mousedown', e => e.consume(), false);
95
+ }
96
+ }
97
+ }
@@ -30,6 +30,7 @@ export enum RegisteredAdorners {
30
30
  SCROLL_SNAP = 'scroll-snap',
31
31
  CONTAINER = 'container',
32
32
  SLOT = 'slot',
33
+ TOP_LAYER = 'top-layer',
33
34
  }
34
35
 
35
36
  // This enum-like const object serves as the authoritative registry for all the
@@ -72,6 +73,12 @@ export function getRegisteredAdorner(which: RegisteredAdorners): RegisteredAdorn
72
73
  category: AdornerCategories.LAYOUT,
73
74
  enabledByDefault: true,
74
75
  };
76
+ case RegisteredAdorners.TOP_LAYER:
77
+ return {
78
+ name: 'top-layer',
79
+ category: AdornerCategories.LAYOUT,
80
+ enabledByDefault: true,
81
+ };
75
82
  }
76
83
  }
77
84
 
@@ -9,6 +9,7 @@ import './DOMLinkifier.js';
9
9
  import './DOMPath.js';
10
10
  import './ElementsSidebarPane.js';
11
11
  import './ElementsTreeElement.js';
12
+ import './TopLayerContainer.js';
12
13
  import './ElementsTreeOutline.js';
13
14
  import './EventListenersWidget.js';
14
15
  import './MarkerDecorator.js';
@@ -25,6 +26,7 @@ import './ElementsPanel.js';
25
26
  import './ClassesPaneWidget.js';
26
27
  import './ElementStatePaneWidget.js';
27
28
  import './ElementsTreeElementHighlighter.js';
29
+ import './TopLayerContainer.js';
28
30
 
29
31
  import * as ClassesPaneWidget from './ClassesPaneWidget.js';
30
32
  import * as ColorSwatchPopoverIcon from './ColorSwatchPopoverIcon.js';
@@ -53,6 +55,7 @@ import * as StylePropertyHighlighter from './StylePropertyHighlighter.js';
53
55
  import * as StylePropertyTreeElement from './StylePropertyTreeElement.js';
54
56
  import * as StylePropertyUtils from './StylePropertyUtils.js';
55
57
  import * as StylesSidebarPane from './StylesSidebarPane.js';
58
+ import * as TopLayerContainer from './TopLayerContainer.js';
56
59
 
57
60
  export {
58
61
  ClassesPaneWidget,
@@ -82,4 +85,5 @@ export {
82
85
  StylePropertyTreeElement,
83
86
  StylePropertyUtils,
84
87
  StylesSidebarPane,
88
+ TopLayerContainer,
85
89
  };
@@ -81,7 +81,15 @@ export class LighthousePanel extends UI.Panel.Panel {
81
81
  private rightToolbar!: UI.Toolbar.Toolbar;
82
82
  private showSettingsPaneSetting!: Common.Settings.Setting<boolean>;
83
83
  private stateBefore?: {
84
- emulation: {enabled: boolean, outlineEnabled: boolean, toolbarControlsEnabled: boolean},
84
+ emulation: {
85
+ type: EmulationModel.DeviceModeModel.Type,
86
+ enabled: boolean,
87
+ outlineEnabled: boolean,
88
+ toolbarControlsEnabled: boolean,
89
+ scale: number,
90
+ device: EmulationModel.EmulatedDevices.EmulatedDevice|null,
91
+ mode: EmulationModel.EmulatedDevices.Mode|null,
92
+ },
85
93
  network: {conditions: SDK.NetworkManager.Conditions},
86
94
  };
87
95
  private isLHAttached?: boolean;
@@ -385,7 +393,7 @@ export class LighthousePanel extends UI.Panel.Panel {
385
393
  }
386
394
 
387
395
  } catch (err) {
388
- await this.resetEmulationAndProtocolConnection();
396
+ await this.restoreEmulationAndProtocolConnection();
389
397
  if (err instanceof Error) {
390
398
  this.statusView.renderBugReport(err);
391
399
  }
@@ -413,12 +421,12 @@ export class LighthousePanel extends UI.Panel.Panel {
413
421
 
414
422
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.LighthouseFinished);
415
423
 
416
- await this.resetEmulationAndProtocolConnection();
424
+ await this.restoreEmulationAndProtocolConnection();
417
425
  this.buildReportUI(lighthouseResponse.lhr, lighthouseResponse.artifacts);
418
426
  // Give focus to the new audit button when completed
419
427
  this.newButton.element.focus();
420
428
  } catch (err) {
421
- await this.resetEmulationAndProtocolConnection();
429
+ await this.restoreEmulationAndProtocolConnection();
422
430
  if (err instanceof Error) {
423
431
  this.statusView.renderBugReport(err);
424
432
  }
@@ -430,7 +438,7 @@ export class LighthousePanel extends UI.Panel.Panel {
430
438
  private async cancelLighthouse(): Promise<void> {
431
439
  this.currentLighthouseRun = undefined;
432
440
  this.statusView.updateStatus(i18nString(UIStrings.cancelling));
433
- await this.resetEmulationAndProtocolConnection();
441
+ await this.restoreEmulationAndProtocolConnection();
434
442
  this.renderStartView();
435
443
  }
436
444
 
@@ -447,9 +455,13 @@ export class LighthousePanel extends UI.Panel.Panel {
447
455
  const emulationModel = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
448
456
  this.stateBefore = {
449
457
  emulation: {
458
+ type: emulationModel.type(),
450
459
  enabled: emulationModel.enabledSetting().get(),
451
460
  outlineEnabled: emulationModel.deviceOutlineSetting().get(),
452
461
  toolbarControlsEnabled: emulationModel.toolbarControlsEnabledSetting().get(),
462
+ scale: emulationModel.scaleSetting().get(),
463
+ device: emulationModel.device(),
464
+ mode: emulationModel.mode(),
453
465
  },
454
466
  network: {conditions: SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions()},
455
467
  };
@@ -473,7 +485,7 @@ export class LighthousePanel extends UI.Panel.Panel {
473
485
  this.isLHAttached = true;
474
486
  }
475
487
 
476
- private async resetEmulationAndProtocolConnection(): Promise<void> {
488
+ private async restoreEmulationAndProtocolConnection(): Promise<void> {
477
489
  if (!this.isLHAttached) {
478
490
  return;
479
491
  }
@@ -483,9 +495,25 @@ export class LighthousePanel extends UI.Panel.Panel {
483
495
 
484
496
  if (this.stateBefore) {
485
497
  const emulationModel = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
486
- emulationModel.enabledSetting().set(this.stateBefore.emulation.enabled);
487
- emulationModel.deviceOutlineSetting().set(this.stateBefore.emulation.outlineEnabled);
488
- emulationModel.toolbarControlsEnabledSetting().set(this.stateBefore.emulation.toolbarControlsEnabled);
498
+
499
+ // Detaching a session after overriding device metrics will prevent other sessions from overriding device metrics in the future.
500
+ // A workaround is to call "Emulation.clearDeviceMetricOverride" which is the result of the next line.
501
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=1337089
502
+ emulationModel.emulate(EmulationModel.DeviceModeModel.Type.None, null, null);
503
+
504
+ const {type, enabled, outlineEnabled, toolbarControlsEnabled, scale, device, mode} = this.stateBefore.emulation;
505
+ emulationModel.enabledSetting().set(enabled);
506
+ emulationModel.deviceOutlineSetting().set(outlineEnabled);
507
+ emulationModel.toolbarControlsEnabledSetting().set(toolbarControlsEnabled);
508
+
509
+ // `emulate` will ignore the `scale` parameter for responsive emulation.
510
+ // In this case we can just set it here.
511
+ if (type === EmulationModel.DeviceModeModel.Type.Responsive) {
512
+ emulationModel.scaleSetting().set(scale);
513
+ }
514
+
515
+ emulationModel.emulate(type, device, mode, scale);
516
+
489
517
  SDK.NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(this.stateBefore.network.conditions);
490
518
  delete this.stateBefore;
491
519
  }
@@ -319,6 +319,6 @@ export class OpenLinearMemoryInspector extends UI.Widget.VBox implements UI.Cont
319
319
  private async openMemoryInspector(obj: SDK.RemoteObject.RemoteObject): Promise<void> {
320
320
  const controller = LinearMemoryInspector.LinearMemoryInspectorController.LinearMemoryInspectorController.instance();
321
321
  Host.userMetrics.linearMemoryInspectorRevealedFrom(Host.UserMetrics.LinearMemoryInspectorRevealedFrom.ContextMenu);
322
- void controller.openInspectorView(obj, 0);
322
+ void controller.openInspectorView(obj);
323
323
  }
324
324
  }
@@ -77,17 +77,16 @@ async function getBufferFromObject(obj: SDK.RemoteObject.RemoteObject): Promise<
77
77
  return new SDK.RemoteObject.RemoteArrayBuffer(obj);
78
78
  }
79
79
 
80
+ export function isDWARFMemoryObject(obj: SDK.RemoteObject.RemoteObject): boolean {
81
+ return obj instanceof Bindings.DebuggerLanguagePlugins.ValueNode && obj.inspectableAddress !== undefined;
82
+ }
83
+
80
84
  export function isMemoryObjectProperty(obj: SDK.RemoteObject.RemoteObject): boolean {
81
85
  const isWasmOrBuffer = obj.type === 'object' && obj.subtype && ACCEPTED_MEMORY_TYPES.includes(obj.subtype);
82
- if (isWasmOrBuffer) {
86
+ if (isWasmOrBuffer || isDWARFMemoryObject(obj)) {
83
87
  return true;
84
88
  }
85
89
 
86
- const isWasmDWARF = obj instanceof Bindings.DebuggerLanguagePlugins.ValueNode;
87
- if (isWasmDWARF) {
88
- return obj.inspectableAddress !== undefined;
89
- }
90
-
91
90
  return false;
92
91
  }
93
92
 
@@ -388,11 +388,13 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
388
388
  }
389
389
 
390
390
  static appendMemoryIcon(element: Element, obj: SDK.RemoteObject.RemoteObject): void {
391
- // We show the memory icon only on ArrayBuffer and WebAssembly.Memory instances.
391
+ // We show the memory icon only on ArrayBuffer, WebAssembly.Memory and DWARF memory instances.
392
392
  // TypedArrays DataViews are also supported, but showing the icon next to their
393
393
  // previews is quite a significant visual overhead, and users can easily get to
394
394
  // their buffers and open the memory inspector from there.
395
- if (!LinearMemoryInspector.LinearMemoryInspectorController.isMemoryObjectProperty(obj)) {
395
+ const arrayBufferOrWasmMemory =
396
+ (obj.type === 'object' && (obj.subtype === 'arraybuffer' || obj.subtype === 'webassemblymemory'));
397
+ if (!arrayBufferOrWasmMemory && !LinearMemoryInspector.LinearMemoryInspectorController.isDWARFMemoryObject(obj)) {
396
398
  return;
397
399
  }
398
400
  const memoryIcon = new IconButton.Icon.Icon();
@@ -408,7 +410,7 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
408
410
  const controller =
409
411
  LinearMemoryInspector.LinearMemoryInspectorController.LinearMemoryInspectorController.instance();
410
412
  Host.userMetrics.linearMemoryInspectorRevealedFrom(Host.UserMetrics.LinearMemoryInspectorRevealedFrom.MemoryIcon);
411
- void controller.openInspectorView(obj, 0);
413
+ void controller.openInspectorView(obj);
412
414
  };
413
415
 
414
416
  UI.Tooltip.Tooltip.install(memoryIcon, 'Reveal in Memory Inspector panel');
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.1016075"
58
+ "version": "1.0.1017408"
59
59
  }