chrome-devtools-frontend 1.0.1697998 → 1.0.1698733

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 (102) hide show
  1. package/.agents/skills/version-control/SKILL.md +21 -9
  2. package/front_end/core/platform/HostRuntime.ts +12 -0
  3. package/front_end/core/platform/api/HostRuntime.ts +13 -0
  4. package/front_end/core/platform/browser/HostRuntime.ts +34 -0
  5. package/front_end/core/platform/node/HostRuntime.ts +40 -0
  6. package/front_end/core/sdk/AnimationModel.ts +12 -98
  7. package/front_end/core/sdk/CSSModel.ts +4 -2
  8. package/front_end/core/sdk/CSSPropertyParser.ts +4 -4
  9. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +4 -44
  10. package/front_end/core/sdk/Connections.ts +6 -1
  11. package/front_end/core/sdk/ConsoleModel.ts +1 -12
  12. package/front_end/core/sdk/DOMModel.ts +3 -51
  13. package/front_end/core/sdk/DebuggerModel.ts +9 -8
  14. package/front_end/core/sdk/NetworkRequest.ts +1 -1
  15. package/front_end/core/sdk/PageFunctions.ts +187 -0
  16. package/front_end/core/sdk/Resource.ts +1 -1
  17. package/front_end/core/sdk/RuntimeModel.ts +1 -20
  18. package/front_end/core/sdk/Script.ts +21 -0
  19. package/front_end/core/sdk/SourceMap.ts +15 -2
  20. package/front_end/core/sdk/SourceMapCache.ts +13 -10
  21. package/front_end/core/sdk/SourceMapManager.ts +11 -9
  22. package/front_end/core/sdk/SourceMapScopeChainEntry.ts +59 -17
  23. package/front_end/core/sdk/SourceMapScopesInfo.ts +8 -2
  24. package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +635 -0
  25. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +26 -12
  26. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +16 -2
  27. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +4 -4
  28. package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker.ts +2 -0
  29. package/front_end/entrypoints/shell/shell.ts +1 -1
  30. package/front_end/models/ai_assistance/DOMHelpers.ts +95 -0
  31. package/front_end/models/ai_assistance/EvaluateAction.ts +5 -42
  32. package/front_end/models/ai_assistance/ExtensionScope.ts +2 -31
  33. package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -1
  34. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +3 -4
  35. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  36. package/front_end/models/ai_assistance/contexts/DOMNodeContext.ts +10 -7
  37. package/front_end/models/ai_assistance/contexts/FileContext.ts +2 -10
  38. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +3 -2
  39. package/front_end/models/ai_assistance/tools/ListSources.ts +21 -14
  40. package/front_end/models/bindings/CompilerScriptMapping.ts +3 -10
  41. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +48 -17
  42. package/front_end/models/bindings/ResourceScriptMapping.ts +2 -2
  43. package/front_end/models/bindings/StylesSourceMapping.ts +1 -1
  44. package/front_end/models/comment_manager/CD4ABridge.ts +55 -12
  45. package/front_end/models/comment_manager/CommentManager.ts +46 -91
  46. package/front_end/models/comment_manager/CommentThread.ts +145 -0
  47. package/front_end/models/comment_manager/comment_manager.ts +2 -0
  48. package/front_end/models/emulation/DeviceModeModel.ts +53 -0
  49. package/front_end/models/extensions/ExtensionAPI.ts +8 -6
  50. package/front_end/models/extensions/ExtensionEndpoint.ts +11 -8
  51. package/front_end/models/extensions/HostUrlPattern.ts +4 -3
  52. package/front_end/models/extensions/LanguageExtensionEndpoint.ts +3 -2
  53. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +2 -1
  54. package/front_end/models/formatter/FormatterWorkerPool.ts +4 -6
  55. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +55 -0
  56. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +18 -14
  57. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  58. package/front_end/models/issues_manager/WebInstallIssue.ts +63 -0
  59. package/front_end/models/issues_manager/descriptions/webInstallManifestMissingId.md +3 -0
  60. package/front_end/models/issues_manager/descriptions/webInstallManifestMissingNameOrShortName.md +3 -0
  61. package/front_end/models/issues_manager/descriptions/webInstallManifestParsingOrNetworkError.md +3 -0
  62. package/front_end/models/issues_manager/descriptions/webInstallNoManifest.md +3 -0
  63. package/front_end/models/issues_manager/descriptions/webInstallStartUrlInvalid.md +3 -0
  64. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  65. package/front_end/models/workspace/UISourceCode.ts +20 -0
  66. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +4 -6
  67. package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +4 -10
  68. package/front_end/{ui/comments → panels/common}/CommentThreadWidget.ts +4 -4
  69. package/front_end/{ui/comments → panels/common}/CommentsOverlayWidget.ts +39 -62
  70. package/front_end/{ui/comments → panels/common}/CommentsStatusBarPill.ts +5 -5
  71. package/front_end/panels/common/ExtensionServer.ts +2 -1
  72. package/front_end/{ui/comments → panels/common}/commentsOverlay.css +2 -1
  73. package/front_end/{ui/comments/comments-meta.ts → panels/common/common-meta.ts} +11 -11
  74. package/front_end/panels/common/common.ts +3 -0
  75. package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +3 -3
  76. package/front_end/panels/elements/ElementsPanel.ts +5 -1
  77. package/front_end/panels/elements/ElementsTreeElement.ts +4 -1
  78. package/front_end/panels/elements/ElementsTreeOutline.ts +58 -51
  79. package/front_end/panels/elements/PropertiesWidget.ts +11 -10
  80. package/front_end/panels/elements/PropertyRenderer.ts +29 -25
  81. package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -6
  82. package/front_end/panels/elements/elementsTreeOutline.css +7 -1
  83. package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -3
  84. package/front_end/panels/event_listeners/EventListenersView.ts +33 -44
  85. package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorController.ts +6 -7
  86. package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +5 -1
  87. package/front_end/panels/linear_memory_inspector/linear_memory_inspector-meta.ts +1 -1
  88. package/front_end/panels/recorder/stepView.css +1 -0
  89. package/front_end/panels/security/SecurityPanel.ts +5 -5
  90. package/front_end/panels/security/SecurityPanelSidebar.ts +2 -11
  91. package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
  92. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +11 -16
  93. package/front_end/panels/sources/sources-meta.ts +1 -1
  94. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +0 -3
  95. package/front_end/third_party/chromium/README.chromium +1 -1
  96. package/front_end/ui/comments/CommentOverlayManager.ts +28 -110
  97. package/front_end/ui/comments/comments.ts +0 -6
  98. package/front_end/ui/legacy/Treeoutline.ts +4 -0
  99. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
  100. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  101. package/package.json +1 -1
  102. /package/front_end/{ui/comments → panels/common}/commentThreadWidget.css +0 -0
@@ -354,6 +354,7 @@ export interface ViewInput {
354
354
  descendantDecorations: Decoration[];
355
355
  decorationsTooltip: string;
356
356
  indent: number;
357
+ renderSelection?: boolean;
357
358
 
358
359
  editorState: CodeMirror.EditorState|null;
359
360
  editorWidth: number|null;
@@ -906,7 +907,7 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
906
907
  input.onExpand,
907
908
  input.issues,
908
909
  )}</span>` : nothing}
909
- <div class="selection fill ${input.editorState ? 'hidden' : ''}" style=${`margin-left: ${-input.indent}px`}></div>
910
+ ${input.renderSelection !== false ? html`<div class="selection fill ${input.editorState ? 'hidden' : ''}" style=${`margin-left: ${-input.indent}px`}></div>` : nothing}
910
911
  <div class=${classMap(gutterContainerClasses)}
911
912
  style="left: ${-input.indent}px"
912
913
  @click=${input.onGutterClick}>
@@ -1171,6 +1172,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1171
1172
  isXMLMimeType = false;
1172
1173
  disableEdits = false;
1173
1174
  showAIButton = false;
1175
+ renderSelection = true;
1174
1176
  isDOMNodeSelected = false;
1175
1177
  initialEdit?: InitialEditState|null;
1176
1178
  onInitialEditCompleted?: () => void;
@@ -1584,6 +1586,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1584
1586
  descendantDecorations: this.#expanded ? [] : this.#descendantDecorations,
1585
1587
  decorationsTooltip: this.#decorationsTooltip,
1586
1588
  indent: this.#getLeftIndent(),
1589
+ renderSelection: this.renderSelection,
1587
1590
  showScrollSnapAdorner: Boolean(this.#layout?.hasScroll) && !isClosingTag,
1588
1591
  scrollSnapAdornerActive: this.#scrollSnapAdornerActive,
1589
1592
  showSlotAdorner: Boolean(this.node.assignedSlot) && !isClosingTag,
@@ -150,7 +150,7 @@ interface ViewInput {
150
150
  onClearMaxRows?: () => void;
151
151
  onHoverNode?: (node: SDK.DOMModel.DOMNode|null, showInfo?: boolean, isClosingTag?: boolean) => void;
152
152
  onLeave?: () => void;
153
- onToggleHideElement?: (node: SDK.DOMModel.DOMNode) => void;
153
+ onToggleHideElement?: (node: SDK.DOMModel.DOMNode) => Promise<void>;
154
154
  onKeyDown?: (event: KeyboardEvent) => void;
155
155
  isToggledToHidden?: (node: SDK.DOMModel.DOMNode) => boolean;
156
156
  onDuplicateNode?: (node: SDK.DOMModel.DOMNode) => void;
@@ -523,6 +523,13 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
523
523
  }
524
524
 
525
525
  const on = Lit.Directive.directive(Lit.CustomDirectives.InterceptBindingDirective);
526
+ const treeItemJslog = (context?: string, drag?: boolean): ReturnType<typeof VisualLogging.treeItem> =>
527
+ VisualLogging.treeItem(context).parent('elementsTreeOutline').track({
528
+ keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Backspace|Delete|Enter|Space|Home|End',
529
+ resize: true,
530
+ ...(drag ? {drag: true} : {}),
531
+ click: true,
532
+ });
526
533
 
527
534
  const renderShortcut = (shortcut: SDK.DOMModel.DOMNodeShortcut, shortcutDepth: number): Lit.LitTemplate => {
528
535
  const hasShortcutChildren = shortcut.childShortcuts.length > 0;
@@ -558,12 +565,11 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
558
565
  ?open=${isShortcutExpanded}
559
566
  class="elements-tree-shortcut"
560
567
  style=${styleMap({'--indent': `${computeLeftIndent(shortcutDepth, hasShortcutChildren)}px`})}
561
- @select=${onShortcutSelect}
562
- @expand=${onShortcutExpand}
568
+ @select=${on(onShortcutSelect)}
569
+ @expand=${on(onShortcutExpand)}
563
570
  @mousemove=${on(onShortcutMouseMove)}
564
571
  @mouseleave=${on(onShortcutMouseLeave)}
565
- jslog=${VisualLogging.treeItem().parent('elementsTreeOutline')}>
566
- <div class="selection fill"></div>
572
+ jslog=${treeItemJslog()}>
567
573
  <span class="elements-tree-shortcut-title">\u21AA ${title}</span>
568
574
  <devtools-adorner
569
575
  .name=${ElementsComponents.AdornerManager.RegisteredAdorners.REVEAL}
@@ -583,9 +589,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
583
589
  </devtools-adorner>
584
590
  ${hasShortcutChildren ? html`
585
591
  <ul role="group">
586
- ${UI.TreeOutline.ifExpanded(html`
587
- ${shortcut.childShortcuts.map(child => renderShortcut(child, shortcutDepth + 1))}
588
- `)}
592
+ ${shortcut.childShortcuts.map(child => renderShortcut(child, shortcutDepth + 1))}
589
593
  </ul>
590
594
  ` : nothing}
591
595
  </li>
@@ -613,15 +617,12 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
613
617
  ?open=${isTopLayerExpanded}
614
618
  class="elements-tree-top-layer-container"
615
619
  style=${styleMap({'--indent': `${computeLeftIndent(containerDepth, true)}px`})}
616
- @select=${onTopLayerSelect}
617
- @expand=${onTopLayerExpand}
618
- jslog=${VisualLogging.treeItem().parent('elementsTreeOutline')}>
619
- <div class="selection fill"></div>
620
+ @select=${on(onTopLayerSelect)}
621
+ @expand=${on(onTopLayerExpand)}
622
+ jslog=${treeItemJslog()}>
620
623
  <span class="elements-tree-shortcut-title">#top-layer</span>
621
624
  <ul role="group">
622
- ${UI.TreeOutline.ifExpanded(html`
623
- ${shortcuts.map(sc => renderShortcut(sc, containerDepth + 1))}
624
- `)}
625
+ ${shortcuts.map(sc => renderShortcut(sc, containerDepth + 1))}
625
626
  </ul>
626
627
  </li>
627
628
  `;
@@ -647,10 +648,9 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
647
648
  ?open=${isExpanded}
648
649
  class="elements-tree-adopted-style-sheet"
649
650
  style=${styleMap({'--indent': `${computeLeftIndent(depth, true)}px`})}
650
- @select=${onSelect}
651
- @expand=${onExpand}
652
- jslog=${VisualLogging.treeItem('adopted-style-sheet').parent('elementsTreeOutline')}>
653
- <div class="selection fill"></div>
651
+ @select=${on(onSelect)}
652
+ @expand=${on(onExpand)}
653
+ jslog=${treeItemJslog('adopted-style-sheet')}>
654
654
  <span class="elements-tree-shortcut-title">#adopted-style-sheet${linkText ? html` (${UIComponentUtils.Linkifier.Linkifier.linkifyURL(linkText, {
655
655
  text: linkText,
656
656
  preventClick: true,
@@ -662,8 +662,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
662
662
  <li role="treeitem"
663
663
  class="elements-tree-adopted-style-sheet-contents"
664
664
  style=${styleMap({'--indent': `${computeLeftIndent(depth + 1, false)}px`})}
665
- jslog=${VisualLogging.treeItem('adopted-style-sheet-contents').parent('elementsTreeOutline')}>
666
- <div class="selection fill"></div>
665
+ jslog=${treeItemJslog('adopted-style-sheet-contents')}>
667
666
  ${UI.Widget.widget(AdoptedStyleSheetContentsWidget, {styleSheetHeader: header})}
668
667
  </li>
669
668
  ` : nothing}
@@ -693,10 +692,9 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
693
692
  ?open=${isExpanded}
694
693
  class="elements-tree-adopted-style-sheets"
695
694
  style=${styleMap({'--indent': `${computeLeftIndent(depth, true)}px`})}
696
- @select=${onSelect}
697
- @expand=${onExpand}
698
- jslog=${VisualLogging.treeItem('adopted-style-sheets').parent('elementsTreeOutline')}>
699
- <div class="selection fill"></div>
695
+ @select=${on(onSelect)}
696
+ @expand=${on(onExpand)}
697
+ jslog=${treeItemJslog('adopted-style-sheets')}>
700
698
  <span class="elements-tree-shortcut-title">#adopted-style-sheets</span>
701
699
  <ul role="group">
702
700
  ${UI.TreeOutline.ifExpanded(html`
@@ -811,7 +809,8 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
811
809
  };
812
810
 
813
811
  const renderNode = (node: SDK.DOMModel.DOMNode, depth = 0): Lit.LitTemplate => {
814
- const isSelected = input.selectedNode === node;
812
+ const isDOMNodeSelected = input.selectedNode === node;
813
+ const isSelected = Boolean(input.selectEnabled) && isDOMNodeSelected;
815
814
  const isOpeningHovered =
816
815
  (input.currentHighlightedNode === node) || (input.hoveredNode === node && !input.hoveredClosingTag);
817
816
  const isClosingHovered = input.hoveredNode === node && Boolean(input.hoveredClosingTag);
@@ -923,7 +922,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
923
922
  ?selected=${isSelected && !input.selectedClosingTag}
924
923
  class=${classes}
925
924
  style=${styleMap({'--indent': `${computeLeftIndent(depth, isExpandable)}px`})}
926
- ?open=${isExpanded && !isEditingAsHTML}
925
+ ?open=${hasChildren && isExpanded && !isEditingAsHTML}
927
926
  draggable=${isDraggable ? 'true' : 'false'}
928
927
  @select=${on((event: UI.TreeOutline.TreeViewElement.SelectEvent) => onSelect(false, Boolean(event.detail?.selectedByUser)))}
929
928
  @expand=${on(onExpand)}
@@ -934,19 +933,15 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
934
933
  @dragleave=${on(onDragLeave)}
935
934
  @drop=${on(onDrop)}
936
935
  @dragend=${on(onDragEnd)}
937
- jslog=${VisualLogging.treeItem().parent('elementsTreeOutline').track({
938
- keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Backspace|Delete|Enter|Space|Home|End',
939
- resize: true,
940
- drag: true,
941
- click: true,
942
- })}>
936
+ jslog=${treeItemJslog(undefined, true)}>
943
937
  ${UI.Widget.widget(ElementsTreeWidget, {
944
938
  node,
945
939
  isClosingTag: false,
940
+ renderSelection: false,
946
941
  expanded: isExpanded && !isEditingAsHTML,
947
942
  isExpandable: hasChildren,
948
943
  selected: isSelected && !input.selectedClosingTag,
949
- isDOMNodeSelected: isSelected,
944
+ isDOMNodeSelected,
950
945
  hovered: isOpeningHovered,
951
946
  searchQuery: input.searchMatchNode === node ? (input.searchMatchQuery ?? null) : null,
952
947
  inClipboard: input.isNodeInClipboard?.(node) ?? false,
@@ -972,8 +967,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
972
967
  input.onSelectNodeAfterEdit?.(wasExpanded, error, newNode, moveDirection);
973
968
  },
974
969
  toggleHideElement: (n: SDK.DOMModel.DOMNode) => {
975
- input.onToggleHideElement?.(n);
976
- return Promise.resolve();
970
+ return input.onToggleHideElement?.(n) ?? Promise.resolve();
977
971
  },
978
972
  isToggledToHidden: (n: SDK.DOMModel.DOMNode) => input.isToggledToHidden?.(n) ?? false,
979
973
  showContextMenu: (event: Event) => {
@@ -992,7 +986,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
992
986
  <li role="treeitem"
993
987
  class="elements-tree-expand-all"
994
988
  style=${styleMap({'--indent': `${computeLeftIndent(depth + 1, false)}px`})}
995
- jslog=${VisualLogging.treeItem('show-all-nodes').parent('elementsTreeOutline')}>
989
+ jslog=${treeItemJslog('show-all-nodes')}>
996
990
  <devtools-button
997
991
  .variant=${Buttons.Button.Variant.OUTLINED}
998
992
  title=${i18nString(UIStrings.showAllNodesDMore, {PH1: remainingChildrenCount})}
@@ -1016,7 +1010,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
1016
1010
  })}
1017
1011
  style=${styleMap({'--indent': `${computeLeftIndent(depth + 1, false)}px`})}
1018
1012
  draggable=${isDraggable ? 'true' : 'false'}
1019
- jslog=${VisualLogging.treeItem().parent('elementsTreeOutline')}
1013
+ jslog=${treeItemJslog(undefined, true)}
1020
1014
  @select=${on((event: UI.TreeOutline.TreeViewElement.SelectEvent) => onSelect(true, Boolean(event.detail?.selectedByUser)))}
1021
1015
  @contextmenu=${on(onContextMenu)}
1022
1016
  @mousemove=${on(onClosingMouseMove)}
@@ -1028,10 +1022,11 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
1028
1022
  ${UI.Widget.widget(ElementsTreeWidget, {
1029
1023
  node,
1030
1024
  isClosingTag: true,
1025
+ renderSelection: false,
1031
1026
  expanded: false,
1032
1027
  isExpandable: false,
1033
1028
  selected: isSelected && Boolean(input.selectedClosingTag),
1034
- isDOMNodeSelected: isSelected,
1029
+ isDOMNodeSelected,
1035
1030
  hovered: isClosingHovered,
1036
1031
  computeLeftIndent: computeLeftIndent(depth + 1, false),
1037
1032
  disableEdits: input.disableEdits ?? false,
@@ -1103,7 +1098,7 @@ export const DECLARATIVE_VIEW: View = (input: ViewInput, _output: ViewOutput, ta
1103
1098
  <li role="treeitem"
1104
1099
  class="elements-tree-expand-all"
1105
1100
  style=${styleMap({'--indent': `${computeLeftIndent(0, false)}px`})}
1106
- jslog=${VisualLogging.treeItem('show-all-nodes').parent('elementsTreeOutline')}>
1101
+ jslog=${treeItemJslog('show-all-nodes')}>
1107
1102
  <devtools-button
1108
1103
  .variant=${Buttons.Button.Variant.OUTLINED}
1109
1104
  title=${i18nString(UIStrings.showAllNodesDMore, {PH1: remaining})}
@@ -1728,6 +1723,12 @@ export class DOMTreeWidget extends UI.Widget.Widget {
1728
1723
  }
1729
1724
  return;
1730
1725
  }
1726
+ if (isClosingTag && node) {
1727
+ const rootTreeElement = this.#viewOutput?.elementsTreeOutline?.findTreeElement(node);
1728
+ const closingTreeElement = rootTreeElement?.childAt(rootTreeElement.childCount() - 1);
1729
+ closingTreeElement?.select(!focus, true);
1730
+ return;
1731
+ }
1731
1732
  this.#viewOutput?.elementsTreeOutline?.selectDOMNode(node, focus);
1732
1733
  }
1733
1734
 
@@ -1826,16 +1827,19 @@ export class DOMTreeWidget extends UI.Widget.Widget {
1826
1827
 
1827
1828
  async expandRecursively(node: SDK.DOMModel.DOMNode, maxDepth: number = Number.MAX_VALUE): Promise<void> {
1828
1829
  if (this.#view === DECLARATIVE_VIEW) {
1829
- await node.getSubtree(100, true);
1830
1830
  const expand = async(n: SDK.DOMModel.DOMNode, depth: number): Promise<void> => {
1831
1831
  if (depth > maxDepth) {
1832
1832
  return;
1833
1833
  }
1834
- this.#expandedNodes.add(n);
1835
- if (!n.children() && (n.childNodeCount() || n.isIframe() || n.nodeType() === Node.DOCUMENT_NODE)) {
1836
- await new Promise<void>(resolve => {
1837
- void n.getChildNodes(() => resolve());
1838
- });
1834
+ if (n.childDocumentPromiseForTesting) {
1835
+ await n.childDocumentPromiseForTesting;
1836
+ }
1837
+ if (!n.children() && !n.contentDocument() &&
1838
+ (n === node || n.childNodeCount() || n.isIframe() || n.nodeType() === Node.DOCUMENT_NODE)) {
1839
+ await n.getSubtree(100, true);
1840
+ }
1841
+ if (nodeHasVisibleChildren(n, this.rootDOMNode, this.maxTreeDepth, this.omitRootDOMNode)) {
1842
+ this.#expandedNodes.add(n);
1839
1843
  }
1840
1844
  const visibleChildren = getVisibleChildren(n, this.#showComments);
1841
1845
  if (visibleChildren.length) {
@@ -1957,7 +1961,10 @@ export class DOMTreeWidget extends UI.Widget.Widget {
1957
1961
  if (this.#view === DECLARATIVE_VIEW) {
1958
1962
  this.performUpdate();
1959
1963
  } else {
1960
- const treeElement = node ? this.treeElementForNode(node) : null;
1964
+ let treeElement = node ? this.treeElementForNode(node) : null;
1965
+ if (isClosingTag && treeElement) {
1966
+ treeElement = treeElement.childAt(treeElement.childCount() - 1) as ElementsTreeElement | null;
1967
+ }
1961
1968
  this.#viewOutput.elementsTreeOutline?.setHoverEffect(treeElement);
1962
1969
  }
1963
1970
  }
@@ -2093,7 +2100,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
2093
2100
  void this.showContextMenu(node, event);
2094
2101
  },
2095
2102
  onToggleHideElement: (node: SDK.DOMModel.DOMNode) => {
2096
- this.toggleHideElement(node);
2103
+ return this.toggleHideElement(node);
2097
2104
  },
2098
2105
  onKeyDown: (event: KeyboardEvent) => {
2099
2106
  this.onKeyDown(event);
@@ -2332,11 +2339,11 @@ export class DOMTreeWidget extends UI.Widget.Widget {
2332
2339
  }
2333
2340
  }
2334
2341
 
2335
- toggleHideElement(node: SDK.DOMModel.DOMNode): void {
2342
+ async toggleHideElement(node: SDK.DOMModel.DOMNode): Promise<void> {
2336
2343
  const changeTracker = this.changeTracker;
2337
2344
  Elements.DOMChanges.trackVisibilityToggle(changeTracker, node, buildChangeSelector(changeTracker, node),
2338
2345
  !this.isToggledToHidden(node));
2339
- void node.toggleHideElement();
2346
+ await node.toggleHideElement();
2340
2347
  }
2341
2348
 
2342
2349
  async removeNode(node: SDK.DOMModel.DOMNode): Promise<void> {
@@ -2850,7 +2857,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
2850
2857
  }
2851
2858
 
2852
2859
  if (event.key === 'h' || event.key === 'H') {
2853
- this.toggleHideElement(node);
2860
+ void this.toggleHideElement(node);
2854
2861
  event.consume(true);
2855
2862
  return true;
2856
2863
  }
@@ -40,7 +40,7 @@ import * as Platform from '../../core/platform/platform.js';
40
40
  import * as SDK from '../../core/sdk/sdk.js';
41
41
  import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
42
42
  import * as UI from '../../ui/legacy/legacy.js';
43
- import {Directives, html, nothing, render} from '../../ui/lit/lit.js';
43
+ import {html, nothing, render} from '../../ui/lit/lit.js';
44
44
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
45
45
 
46
46
  import propertiesWidgetStyles from './propertiesWidget.css.js';
@@ -48,7 +48,7 @@ import propertiesWidgetStyles from './propertiesWidget.css.js';
48
48
  const OBJECT_GROUP_NAME = 'properties-sidebar-pane';
49
49
 
50
50
  const {bindToSetting} = UI.UIUtils;
51
- const {repeat} = Directives;
51
+ const {widget, widgetRef} = UI.Widget;
52
52
 
53
53
  const UIStrings = {
54
54
  /**
@@ -104,14 +104,14 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
104
104
  <div class="gray-info-message">${i18nString(UIStrings.noMatchingProperty)}</div>
105
105
  ` : nothing}
106
106
  <devtools-tree show-selection-on-keyboard-focus @treeelementexpand=${onExpand} .template=${html`
107
- <ul role=tree class="source-code object-properties-section">
108
- <style>${ObjectUI.ObjectPropertiesSection.objectValueStyles}</style>;
109
- <style>${ObjectUI.ObjectPropertiesSection.objectPropertiesSectionStyles}</style>;
110
- ${repeat(ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createPropertyNodes(
111
- input.objectTree?.children ?? {},
112
- true /* skipProto */,
113
- true /* skipGettersAndSetters */),
114
- node => html`<devtools-tree-wrapper .treeElement=${node}></devtools-tree-wrapper>`)}
107
+ <style>${ObjectUI.ObjectPropertiesSection.objectValueStyles}</style>
108
+ <style>${ObjectUI.ObjectPropertiesSection.objectPropertiesSectionStyles}</style>
109
+ <ul role=tree open class="source-code object-properties-section" ${
110
+ widget(ObjectUI.ObjectPropertiesSection.ObjectTreeWidget, {
111
+ objectTree: input.objectTree ?? undefined,
112
+ skipProto: true,
113
+ skipGettersAndSetters: true,
114
+ })} ${widgetRef(ObjectUI.ObjectPropertiesSection.ObjectTreeWidget, () => {})}>
115
115
  </ul>
116
116
  `}></devtools-tree>
117
117
  </div>`, target);
@@ -223,6 +223,7 @@ export class PropertiesWidget extends UI.Widget.VBox {
223
223
  propertiesMode: ObjectUI.ObjectPropertiesSection.ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
224
224
  readOnly: true,
225
225
  });
226
+ this.#objectTree.expanded = true;
226
227
  this.#updateFilter();
227
228
  }
228
229
 
@@ -348,14 +348,16 @@ export class TracingContext {
348
348
  }
349
349
  }
350
350
 
351
+ export const CSSControlMap: MapConstructor = Map;
352
+ export type CSSControlMap = Map<string, HTMLElement[]>;
353
+
351
354
  export class RenderingContext {
352
355
  constructor(readonly ast: SDK.CSSPropertyParser.SyntaxTree, readonly property: SDK.CSSProperty.CSSProperty|null,
353
356
  readonly renderers: Map<Platform.Constructor.Constructor<SDK.CSSPropertyParser.Match>,
354
357
  MatchRenderer<SDK.CSSPropertyParser.Match>>,
355
358
  readonly matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching,
356
- readonly cssControls?: SDK.CSSPropertyParser.CSSControlMap|undefined,
357
- readonly options: {readonly?: boolean} = {}, readonly tracing?: TracingContext|undefined,
358
- readonly signal?: AbortSignal|undefined) {
359
+ readonly cssControls?: CSSControlMap|undefined, readonly options: {readonly?: boolean} = {},
360
+ readonly tracing?: TracingContext|undefined, readonly signal?: AbortSignal|undefined) {
359
361
  }
360
362
 
361
363
  addControl(cssType: string, control: HTMLElement): void {
@@ -406,11 +408,10 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
406
408
  constructor(
407
409
  ast: SDK.CSSPropertyParser.SyntaxTree,
408
410
  property: SDK.CSSProperty.CSSProperty|null,
409
- renderers:
410
- Map<Platform.Constructor.Constructor<SDK.CSSPropertyParser.Match>,
411
- MatchRenderer<SDK.CSSPropertyParser.Match>>,
411
+ renderers: Map<Platform.Constructor.Constructor<SDK.CSSPropertyParser.Match>,
412
+ MatchRenderer<SDK.CSSPropertyParser.Match>>,
412
413
  matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching,
413
- cssControls: SDK.CSSPropertyParser.CSSControlMap,
414
+ cssControls: CSSControlMap,
414
415
  options: {
415
416
  readonly?: boolean,
416
417
  },
@@ -423,12 +424,12 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
423
424
  new RenderingContext(this.ast, property, renderers, this.#matchedResult, cssControls, options, tracing, signal);
424
425
  }
425
426
 
426
- static render(nodeOrNodes: CodeMirror.SyntaxNode|CodeMirror.SyntaxNode[], context: RenderingContext):
427
- {nodes: Node[], cssControls: SDK.CSSPropertyParser.CSSControlMap} {
427
+ static render(nodeOrNodes: CodeMirror.SyntaxNode|CodeMirror.SyntaxNode[],
428
+ context: RenderingContext): {nodes: Node[], cssControls: CSSControlMap} {
428
429
  if (!Array.isArray(nodeOrNodes)) {
429
430
  return this.render([nodeOrNodes], context);
430
431
  }
431
- const cssControls = new SDK.CSSPropertyParser.CSSControlMap();
432
+ const cssControls = new CSSControlMap();
432
433
  const renderers = nodeOrNodes.map(
433
434
  node => this.walkExcludingSuccessors(
434
435
  context.ast.subtree(node), context.property, context.renderers, context.matchedResult, cssControls,
@@ -437,9 +438,8 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
437
438
  return {nodes, cssControls};
438
439
  }
439
440
 
440
- static renderInto(
441
- nodeOrNodes: CodeMirror.SyntaxNode|CodeMirror.SyntaxNode[], context: RenderingContext,
442
- parent: Node): {nodes: Node[], cssControls: SDK.CSSPropertyParser.CSSControlMap} {
441
+ static renderInto(nodeOrNodes: CodeMirror.SyntaxNode|CodeMirror.SyntaxNode[], context: RenderingContext,
442
+ parent: Node): {nodes: Node[], cssControls: CSSControlMap} {
443
443
  const {nodes, cssControls} = this.render(nodeOrNodes, context);
444
444
  if (parent.lastChild && SDK.CSSPropertyParser.requiresSpace([parent.lastChild], nodes)) {
445
445
  parent.appendChild(document.createTextNode(' '));
@@ -456,8 +456,14 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
456
456
  const renderer = match &&
457
457
  this.#context.renderers.get(match.constructor as Platform.Constructor.Constructor<SDK.CSSPropertyParser.Match>);
458
458
  if (renderer || match instanceof SDK.CSSPropertyParserMatchers.TextMatch) {
459
- const output = renderer ? renderer.render(match, this.#context) :
460
- (match as SDK.CSSPropertyParserMatchers.TextMatch).render();
459
+ let output: Node[];
460
+ if (renderer) {
461
+ output = renderer.render(match, this.#context);
462
+ } else {
463
+ const span = document.createElement('span');
464
+ span.appendChild(document.createTextNode(match.text));
465
+ output = [span];
466
+ }
461
467
  this.#context.tracing?.highlighting.addMatch(match, output);
462
468
  this.renderedMatchForTest(output, match);
463
469
  this.#output = mergeWithSpacing(this.#output, output);
@@ -490,11 +496,10 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
490
496
  //
491
497
  // More general, longer matches take precedence over shorter, more specific matches. Whitespaces are normalized, for
492
498
  // unmatched text and around rendered matching results.
493
- static renderValueElement(
494
- property: SDK.CSSProperty.CSSProperty|{name: string, value: string},
495
- matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching|null,
496
- renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>, tracing?: TracingContext,
497
- signal?: AbortSignal): {valueElement: HTMLElement, cssControls: SDK.CSSPropertyParser.CSSControlMap} {
499
+ static renderValueElement(property: SDK.CSSProperty.CSSProperty|{name: string, value: string},
500
+ matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching|null,
501
+ renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>, tracing?: TracingContext,
502
+ signal?: AbortSignal): {valueElement: HTMLElement, cssControls: CSSControlMap} {
498
503
  const valueElement = document.createElement('span');
499
504
  valueElement.setAttribute(
500
505
  'jslog', `${VisualLogging.value().track({
@@ -510,11 +515,10 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
510
515
  return {valueElement, cssControls};
511
516
  }
512
517
 
513
- static renderValueNodes(
514
- property: SDK.CSSProperty.CSSProperty|{name: string, value: string},
515
- matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching|null,
516
- renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>, tracing?: TracingContext,
517
- signal?: AbortSignal): {nodes: Node[], cssControls: SDK.CSSPropertyParser.CSSControlMap} {
518
+ static renderValueNodes(property: SDK.CSSProperty.CSSProperty|{name: string, value: string},
519
+ matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching|null,
520
+ renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>, tracing?: TracingContext,
521
+ signal?: AbortSignal): {nodes: Node[], cssControls: CSSControlMap} {
518
522
  if (!matchedResult) {
519
523
  return {nodes: [document.createTextNode(property.value)], cssControls: new Map()};
520
524
  }
@@ -35,6 +35,7 @@ import {CSSValueTraceView} from './CSSValueTraceView.js';
35
35
  import {ElementsPanel} from './ElementsPanel.js';
36
36
  import {
37
37
  BinOpRenderer,
38
+ type CSSControlMap,
38
39
  type MatchRenderer,
39
40
  Renderer,
40
41
  rendererBase,
@@ -713,7 +714,7 @@ export class ColorRenderer extends ColorRendererBase {
713
714
 
714
715
  #getValueChild(match: SDK.CSSPropertyParserMatchers.ColorMatch, context: RenderingContext): {
715
716
  valueChild: HTMLSpanElement,
716
- cssControls?: SDK.CSSPropertyParser.CSSControlMap,
717
+ cssControls?: CSSControlMap,
717
718
  childTracingContexts?: TracingContext[],
718
719
  } {
719
720
  const valueChild = document.createElement('span');
@@ -906,11 +907,10 @@ export class LightDarkColorRenderer extends LightDarkColorRendererBase {
906
907
  return [colorSwatch, content];
907
908
  }
908
909
 
909
- async applyColorScheme(
910
- match: SDK.CSSPropertyParserMatchers.LightDarkColorMatch, context: RenderingContext,
911
- colorSwatch: InlineEditor.ColorSwatch.ColorSwatch, light: HTMLSpanElement, dark: HTMLSpanElement,
912
- lightControls: SDK.CSSPropertyParser.CSSControlMap,
913
- darkControls: SDK.CSSPropertyParser.CSSControlMap): Promise<void> {
910
+ async applyColorScheme(match: SDK.CSSPropertyParserMatchers.LightDarkColorMatch, context: RenderingContext,
911
+ colorSwatch: InlineEditor.ColorSwatch.ColorSwatch, light: HTMLSpanElement,
912
+ dark: HTMLSpanElement, lightControls: CSSControlMap,
913
+ darkControls: CSSControlMap): Promise<void> {
914
914
  const activeColor = await this.#activeColor(match);
915
915
  if (context.signal?.aborted) {
916
916
  return;
@@ -56,11 +56,13 @@
56
56
  line-height: normal;
57
57
  }
58
58
 
59
+ :host(.elements-tree-outline),
59
60
  .elements-disclosure devtools-tree {
60
61
  width: 100%;
61
62
  min-width: 100%;
62
63
  min-height: 100%;
63
64
  display: inline-block;
65
+ padding: 0;
64
66
  }
65
67
 
66
68
  .elements-disclosure li {
@@ -570,7 +572,7 @@ li.hovered:not(.always-parent) + ol.children:not(.shadow-root) {
570
572
  .tree-outline-disclosure li .selection {
571
573
  display: none;
572
574
  z-index: -1;
573
- margin-left: 0;
575
+ margin-left: calc(var(--indent, 0px) * -1);
574
576
  }
575
577
 
576
578
  .tree-outline-disclosure li.selected .selection {
@@ -605,6 +607,10 @@ li.hovered:not(.always-parent) + ol.children:not(.shadow-root) {
605
607
  background-color: var(--sys-color-tonal-container);
606
608
  }
607
609
 
610
+ .tree-outline-disclosure .elements-tree-outline li:has(.elements-tree-editor) .selection {
611
+ display: none;
612
+ }
613
+
608
614
  .tree-outline-disclosure ol {
609
615
  list-style-type: none;
610
616
  padding-inline-start: 12px;
@@ -842,9 +842,8 @@ export class DeviceModeToolbar extends UI.Widget.Widget {
842
842
  if (!this.model) {
843
843
  return;
844
844
  }
845
- const scale = this.autoAdjustScaleSetting.get() ? undefined : this.model.scaleSetting().get();
846
- this.model.emulate(
847
- EmulationModel.DeviceModeModel.Type.Device, device, this.lastMode.get(device) || device.modes[0], scale);
845
+ this.model.emulate(EmulationModel.DeviceModeModel.Type.Device, device,
846
+ this.lastMode.get(device) || device.modes[0]);
848
847
  }
849
848
 
850
849
  private switchToResponsive(): void {