chrome-devtools-frontend 1.0.1675430 → 1.0.1678416

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 (308) hide show
  1. package/AUTHORS +1 -0
  2. package/WATCHLISTS +0 -4
  3. package/front_end/core/common/EventTarget.ts +0 -5
  4. package/front_end/core/common/Settings.ts +0 -66
  5. package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
  6. package/front_end/core/host/UserMetrics.ts +5 -0
  7. package/front_end/core/root/Runtime.ts +5 -5
  8. package/front_end/core/sdk/CSSMetadata.ts +5 -9
  9. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +16 -34
  10. package/front_end/core/sdk/DebuggerModel.ts +92 -57
  11. package/front_end/core/sdk/EmulationModel.ts +2 -1
  12. package/front_end/core/sdk/NetworkManager.ts +16 -2
  13. package/front_end/core/sdk/OverlayModel.ts +19 -9
  14. package/front_end/core/sdk/OverlayPersistentHighlighter.ts +10 -4
  15. package/front_end/core/sdk/ResourceTreeModel.ts +20 -1
  16. package/front_end/core/sdk/SDKSettings.ts +117 -0
  17. package/front_end/core/sdk/Script.ts +9 -53
  18. package/front_end/core/sdk/sdk-meta.ts +0 -431
  19. package/front_end/devtools_compatibility.js +1 -0
  20. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +213 -23
  21. package/front_end/entrypoints/inspector_main/InspectorMain.ts +6 -5
  22. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +14 -15
  23. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +157 -0
  24. package/front_end/entrypoints/main/MainImpl.ts +32 -0
  25. package/front_end/entrypoints/shell/shell.ts +0 -1
  26. package/front_end/foundation/Universe.ts +8 -0
  27. package/front_end/generated/InspectorBackendCommands.ts +8 -8
  28. package/front_end/generated/SupportedCSSProperties.ts +53 -4
  29. package/front_end/generated/protocol-mapping.d.ts +27 -21
  30. package/front_end/generated/protocol-proxy-api.d.ts +22 -17
  31. package/front_end/generated/protocol.ts +43 -18
  32. package/front_end/models/ai_assistance/AiAgent2.ts +47 -2
  33. package/front_end/models/ai_assistance/AiConversation.ts +22 -5
  34. package/front_end/models/ai_assistance/README.md +52 -26
  35. package/front_end/models/ai_assistance/agents/AiAgent.ts +54 -8
  36. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
  37. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +7 -194
  38. package/front_end/models/ai_assistance/agents/StorageAgent.ts +21 -87
  39. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -1
  40. package/front_end/models/ai_assistance/ai_assistance.ts +24 -0
  41. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +124 -0
  42. package/front_end/models/ai_assistance/contexts/StorageContext.ts +100 -0
  43. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +69 -1
  44. package/front_end/models/ai_assistance/skills/README.md +63 -1
  45. package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
  46. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +4 -0
  47. package/front_end/models/ai_assistance/skills/accessibility.md +7 -0
  48. package/front_end/models/ai_assistance/skills/performance.md +15 -1
  49. package/front_end/models/ai_assistance/skills/sources.md +16 -0
  50. package/front_end/models/ai_assistance/skills/storage.md +31 -0
  51. package/front_end/models/ai_assistance/tools/GetDetailedCallTree.ts +107 -0
  52. package/front_end/models/ai_assistance/tools/GetFunctionCode.ts +122 -0
  53. package/front_end/models/ai_assistance/tools/GetResourceContent.ts +127 -0
  54. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +101 -0
  55. package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +83 -0
  56. package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +106 -0
  57. package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +104 -0
  58. package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +95 -0
  59. package/front_end/models/ai_assistance/tools/ListSources.ts +116 -0
  60. package/front_end/models/ai_assistance/tools/RunLighthouse.ts +89 -0
  61. package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +90 -0
  62. package/front_end/models/ai_assistance/tools/Tool.ts +26 -1
  63. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +22 -0
  64. package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -0
  65. package/front_end/models/bindings/CompilerScriptMapping.ts +4 -0
  66. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
  67. package/front_end/models/bindings/ResourceScriptMapping.ts +3 -201
  68. package/front_end/models/bindings/SASSSourceMapping.ts +6 -0
  69. package/front_end/models/breakpoints/BreakpointManager.ts +2 -49
  70. package/front_end/models/comment_manager/CommentManager.ts +141 -0
  71. package/front_end/models/comment_manager/comment_manager.ts +9 -0
  72. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +27 -0
  73. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +10 -2
  74. package/front_end/models/issues_manager/descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
  75. package/front_end/models/issues_manager/descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
  76. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
  77. package/front_end/models/javascript_metadata/NativeFunctions.js +6 -6
  78. package/front_end/models/persistence/IsolatedFileSystem.ts +7 -8
  79. package/front_end/models/persistence/IsolatedFileSystemManager.ts +2 -2
  80. package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
  81. package/front_end/models/persistence/persistence-meta.ts +9 -9
  82. package/front_end/models/trace/types/TraceEvents.ts +36 -0
  83. package/front_end/panels/accessibility/ARIAAttributesView.ts +3 -3
  84. package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +25 -0
  85. package/front_end/panels/accessibility/AccessibilityNodeView.ts +36 -36
  86. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +9 -0
  87. package/front_end/panels/accessibility/AccessibilityStrings.ts +168 -168
  88. package/front_end/panels/accessibility/SourceOrderView.ts +7 -7
  89. package/front_end/panels/accessibility/accessibility-meta.ts +2 -2
  90. package/front_end/panels/accessibility/accessibility.ts +2 -0
  91. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -5
  92. package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +2 -3
  93. package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
  94. package/front_end/panels/ai_assistance/components/ChatMessage.ts +92 -12
  95. package/front_end/panels/ai_assistance/components/chatMessage.css +6 -0
  96. package/front_end/panels/application/ApplicationPanelSidebar.ts +10 -4
  97. package/front_end/panels/application/IndexedDBViews.ts +65 -63
  98. package/front_end/panels/application/StorageView.ts +116 -45
  99. package/front_end/panels/application/WebMCPView.ts +16 -7
  100. package/front_end/panels/application/application-meta.ts +11 -0
  101. package/front_end/panels/application/components/AdsView.ts +1 -1
  102. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +5 -5
  103. package/front_end/panels/common/BadgeNotification.ts +8 -8
  104. package/front_end/panels/common/ExtensionPanel.ts +9 -8
  105. package/front_end/panels/common/ExtensionServer.ts +21 -1
  106. package/front_end/panels/common/GdpSignUpDialog.ts +16 -16
  107. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +5 -6
  108. package/front_end/panels/common/PersistenceUtils.ts +2 -2
  109. package/front_end/panels/common/common.ts +0 -97
  110. package/front_end/panels/console/ConsoleInsightTeaser.ts +2 -2
  111. package/front_end/panels/console/ConsolePanel.ts +4 -0
  112. package/front_end/panels/console/ConsolePinPane.ts +2 -2
  113. package/front_end/panels/console/ConsolePrompt.ts +12 -0
  114. package/front_end/panels/console/ConsoleView.ts +31 -20
  115. package/front_end/panels/console/ConsoleViewMessage.ts +37 -13
  116. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -2
  117. package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -1
  118. package/front_end/panels/elements/ElementStatePaneWidget.ts +2 -1
  119. package/front_end/panels/elements/ElementsTreeElement.ts +455 -372
  120. package/front_end/panels/elements/LayoutPane.ts +2 -8
  121. package/front_end/panels/elements/StylePropertyTreeElement.ts +16 -15
  122. package/front_end/panels/elements/elements-meta.ts +152 -10
  123. package/front_end/panels/elements/elements.ts +0 -2
  124. package/front_end/panels/emulation/DeviceModeView.ts +9 -1
  125. package/front_end/panels/event_listeners/EventListenersView.ts +8 -4
  126. package/front_end/panels/issues/AffectedTrackingSitesView.ts +25 -14
  127. package/front_end/panels/lighthouse/LighthouseController.ts +3 -2
  128. package/front_end/panels/media/PlayerMessagesView.ts +149 -68
  129. package/front_end/panels/network/BinaryResourceView.ts +134 -81
  130. package/front_end/panels/network/EventSourceMessagesView.ts +10 -10
  131. package/front_end/panels/network/FetchHeaderCommenting.ts +291 -0
  132. package/front_end/panels/network/NetworkConfigView.ts +10 -10
  133. package/front_end/panels/network/NetworkDataGridNode.ts +14 -14
  134. package/front_end/panels/network/NetworkItemView.ts +27 -28
  135. package/front_end/panels/network/NetworkLogView.ts +137 -38
  136. package/front_end/panels/network/NetworkLogViewColumns.ts +35 -35
  137. package/front_end/panels/network/NetworkManageCustomHeadersView.ts +1 -1
  138. package/front_end/panels/network/NetworkPanel.ts +2 -2
  139. package/front_end/panels/network/RequestConditionsDrawer.ts +5 -5
  140. package/front_end/panels/network/RequestCookiesView.ts +4 -4
  141. package/front_end/panels/network/RequestHeadersView.ts +5 -5
  142. package/front_end/panels/network/RequestPayloadView.ts +4 -3
  143. package/front_end/panels/network/RequestTimingView.ts +8 -8
  144. package/front_end/panels/network/ResourceChunkView.ts +1 -1
  145. package/front_end/panels/network/ResourceDirectSocketChunkView.ts +1 -1
  146. package/front_end/panels/network/ResourceWebSocketFrameView.ts +16 -16
  147. package/front_end/panels/network/binaryResourceView.css +14 -12
  148. package/front_end/panels/network/components/DirectSocketConnectionView.ts +2 -2
  149. package/front_end/panels/network/components/HeaderSectionRow.ts +1 -1
  150. package/front_end/panels/network/components/RequestTrustTokensView.ts +2 -2
  151. package/front_end/panels/network/network-meta.ts +1 -1
  152. package/front_end/panels/network/network.ts +2 -0
  153. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +0 -1
  154. package/front_end/panels/profiler/HeapSnapshotView.ts +0 -2
  155. package/front_end/panels/profiler/heapProfiler.css +0 -9
  156. package/front_end/panels/recorder/RecorderPanel.ts +2 -3
  157. package/front_end/panels/screencast/ScreencastView.ts +148 -138
  158. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -2
  159. package/front_end/panels/sources/BreakpointsView.ts +2 -2
  160. package/front_end/panels/sources/DebuggerPlugin.ts +10 -59
  161. package/front_end/panels/sources/NavigatorView.ts +2 -1
  162. package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
  163. package/front_end/panels/sources/SourcesPanel.ts +23 -73
  164. package/front_end/panels/sources/SourcesView.ts +248 -157
  165. package/front_end/panels/sources/TabbedEditorContainer.ts +118 -23
  166. package/front_end/panels/sources/UISourceCodeFrame.ts +5 -9
  167. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +4 -2
  168. package/front_end/panels/sources/sources-meta.ts +52 -0
  169. package/front_end/panels/timeline/TimelineController.ts +36 -64
  170. package/front_end/panels/timeline/TimelinePanel.ts +11 -8
  171. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -2
  172. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -2
  173. package/front_end/panels/timeline/timelinePanel.css +0 -10
  174. package/front_end/panels/utils/utils.ts +7 -7
  175. package/front_end/services/tracing/PerformanceTracing.ts +5 -17
  176. package/front_end/third_party/chromium/README.chromium +1 -1
  177. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  178. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  179. package/front_end/third_party/codemirror.next/package.json +2 -2
  180. package/front_end/third_party/codemirror.next/rebuild.sh +4 -1
  181. package/front_end/ui/comments/CommentAnchorResolver.ts +430 -35
  182. package/front_end/ui/comments/CommentOverlayManager.ts +635 -0
  183. package/front_end/ui/comments/CommentsOverlayWidget.ts +134 -0
  184. package/front_end/ui/comments/comments.ts +4 -0
  185. package/front_end/ui/comments/commentsOverlay.css +49 -0
  186. package/front_end/{panels/common → ui/components/dialogs}/FreDialog.ts +6 -6
  187. package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +96 -0
  188. package/front_end/ui/components/dialogs/dialogs.ts +4 -0
  189. package/front_end/ui/components/settings/SettingCheckbox.ts +3 -3
  190. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionDisclaimer.ts +13 -13
  191. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +7 -6
  192. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionTeaser.ts +43 -46
  193. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -26
  194. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationTeaser.ts +10 -10
  195. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationUpgradeDialog.ts +5 -5
  196. package/front_end/ui/components/text_editor/text_editor.ts +4 -0
  197. package/front_end/ui/legacy/Toolbar.ts +1 -1
  198. package/front_end/ui/legacy/UIUtils.ts +0 -56
  199. package/front_end/ui/legacy/View.ts +10 -4
  200. package/front_end/ui/legacy/Widget.ts +10 -1
  201. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +2 -1
  202. package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +5 -4
  203. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +11 -3
  204. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +507 -209
  205. package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +5 -0
  206. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -16
  207. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +5 -12
  208. package/front_end/ui/legacy/components/source_frame/BinaryResourceViewFactory.ts +38 -20
  209. package/front_end/ui/legacy/components/source_frame/JSONView.ts +12 -2
  210. package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +3 -3
  211. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +37 -6
  212. package/front_end/ui/legacy/components/source_frame/StreamingContentHexView.ts +22 -4
  213. package/front_end/ui/settings/SettingUIRegistration.ts +55 -6
  214. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  215. package/mcp/mcp.ts +6 -1
  216. package/package.json +6 -6
  217. package/front_end/Images/toolbarResizerVertical.png +0 -0
  218. package/front_end/emulated_devices/MotoG4-landscape.svg +0 -155
  219. package/front_end/emulated_devices/MotoG4-portrait.svg +0 -155
  220. package/front_end/emulated_devices/Nexus5X-landscape.svg +0 -19
  221. package/front_end/emulated_devices/Nexus5X-portrait.svg +0 -19
  222. package/front_end/emulated_devices/Nexus6P-landscape.svg +0 -50
  223. package/front_end/emulated_devices/Nexus6P-portrait.svg +0 -54
  224. package/front_end/emulated_devices/google-nest-hub-horizontal.png +0 -0
  225. package/front_end/emulated_devices/google-nest-hub-max-horizontal.png +0 -0
  226. package/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png +0 -0
  227. package/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png +0 -0
  228. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png +0 -0
  229. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png +0 -0
  230. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png +0 -0
  231. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png +0 -0
  232. package/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png +0 -0
  233. package/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png +0 -0
  234. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png +0 -0
  235. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png +0 -0
  236. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png +0 -0
  237. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png +0 -0
  238. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png +0 -0
  239. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png +0 -0
  240. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png +0 -0
  241. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png +0 -0
  242. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png +0 -0
  243. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png +0 -0
  244. package/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png +0 -0
  245. package/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png +0 -0
  246. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png +0 -0
  247. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png +0 -0
  248. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png +0 -0
  249. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png +0 -0
  250. package/front_end/emulated_devices/iPad-landscape.svg +0 -73
  251. package/front_end/emulated_devices/iPad-portrait.svg +0 -76
  252. package/front_end/emulated_devices/iPhone5-landscape.svg +0 -99
  253. package/front_end/emulated_devices/iPhone5-portrait.svg +0 -83
  254. package/front_end/emulated_devices/iPhone6-landscape.svg +0 -111
  255. package/front_end/emulated_devices/iPhone6-portrait.svg +0 -116
  256. package/front_end/emulated_devices/iPhone6Plus-landscape.svg +0 -118
  257. package/front_end/emulated_devices/iPhone6Plus-portrait.svg +0 -116
  258. package/front_end/emulated_devices/optimized/MotoG4-landscape.avif +0 -0
  259. package/front_end/emulated_devices/optimized/MotoG4-portrait.avif +0 -0
  260. package/front_end/emulated_devices/optimized/Nexus5X-landscape.avif +0 -0
  261. package/front_end/emulated_devices/optimized/Nexus5X-portrait.avif +0 -0
  262. package/front_end/emulated_devices/optimized/Nexus6P-landscape.avif +0 -0
  263. package/front_end/emulated_devices/optimized/Nexus6P-portrait.avif +0 -0
  264. package/front_end/emulated_devices/optimized/README.md +0 -9
  265. package/front_end/emulated_devices/optimized/google-nest-hub-horizontal.avif +0 -0
  266. package/front_end/emulated_devices/optimized/google-nest-hub-max-horizontal.avif +0 -0
  267. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-1x.avif +0 -0
  268. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-2x.avif +0 -0
  269. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-1x.avif +0 -0
  270. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-2x.avif +0 -0
  271. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-1x.avif +0 -0
  272. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-2x.avif +0 -0
  273. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-1x.avif +0 -0
  274. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-2x.avif +0 -0
  275. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-1x.avif +0 -0
  276. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-2x.avif +0 -0
  277. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-1x.avif +0 -0
  278. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-2x.avif +0 -0
  279. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-1x.avif +0 -0
  280. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-2x.avif +0 -0
  281. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-1x.avif +0 -0
  282. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-2x.avif +0 -0
  283. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-1x.avif +0 -0
  284. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-2x.avif +0 -0
  285. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-1x.avif +0 -0
  286. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-2x.avif +0 -0
  287. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-1x.avif +0 -0
  288. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-2x.avif +0 -0
  289. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-1x.avif +0 -0
  290. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-2x.avif +0 -0
  291. package/front_end/emulated_devices/optimized/iPad-landscape.avif +0 -0
  292. package/front_end/emulated_devices/optimized/iPad-portrait.avif +0 -0
  293. package/front_end/emulated_devices/optimized/iPhone5-landscape.avif +0 -0
  294. package/front_end/emulated_devices/optimized/iPhone5-portrait.avif +0 -0
  295. package/front_end/emulated_devices/optimized/iPhone6-landscape.avif +0 -0
  296. package/front_end/emulated_devices/optimized/iPhone6-portrait.avif +0 -0
  297. package/front_end/emulated_devices/optimized/iPhone6Plus-landscape.avif +0 -0
  298. package/front_end/emulated_devices/optimized/iPhone6Plus-portrait.avif +0 -0
  299. package/front_end/emulated_devices/optimized/optimized_images.gni +0 -53
  300. package/front_end/models/ai_assistance/agents/README.md +0 -136
  301. package/front_end/panels/elements/ElementsTreeOutlineRenderer.ts +0 -89
  302. package/front_end/ui/legacy/components/object_ui/object_ui-meta.ts +0 -27
  303. /package/front_end/{panels/common → ui/components/dialogs}/freDialog.css +0 -0
  304. /package/front_end/{panels/common/common.css → ui/components/dialogs/typeToAllowDialog.css} +0 -0
  305. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionDisclaimer.css +0 -0
  306. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionTeaser.css +0 -0
  307. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationTeaser.css +0 -0
  308. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationUpgradeDialog.css +0 -0
@@ -1238,9 +1238,50 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
1238
1238
  // clang-format on
1239
1239
  };
1240
1240
 
1241
+ type View = typeof DEFAULT_VIEW;
1242
+
1241
1243
  export class ElementsTreeWidget extends UI.Widget.Widget {
1242
- treeElement: ElementsTreeElement&{treeOutline: ElementsTreeOutline | null};
1243
- nodeInternal: SDK.DOMModel.DOMNode;
1244
+ #node!: SDK.DOMModel.DOMNode;
1245
+ isClosingTag = false;
1246
+ #expanded = false;
1247
+ #isExpandable = false;
1248
+ #selected = false;
1249
+ isXMLMimeType = false;
1250
+ disableEdits = false;
1251
+ showAIButton = false;
1252
+ isDOMNodeSelected = false;
1253
+
1254
+ expand?: () => void;
1255
+ collapse?: () => void;
1256
+ selectTreeElement?: (omitFocus?: boolean, selectedByUser?: boolean) => boolean | void;
1257
+ expandRecursively?: (maxDepth?: number) => Promise<void>;
1258
+ collapseChildren?: () => void;
1259
+ childCount?: () => number;
1260
+ closingTagElement?: () => Element | null;
1261
+ updateShadowRootDepth?: (depth: number) => void;
1262
+ computeLeftIndent?: () => number;
1263
+ setChildrenListElementVisible?: (visible: boolean) => void;
1264
+
1265
+ findStartTagWidget?: () => ElementsTreeWidget | null;
1266
+ selectDOMNode?: (node: SDK.DOMModel.DOMNode, selectedByUser?: boolean) => void;
1267
+ revealInTopLayer?: (node: SDK.DOMModel.DOMNode) => void;
1268
+ showContextMenu?: (event: Event) => void;
1269
+ populateTreeElement?: () => Promise<void>;
1270
+ updateNodeElementToIssue?: (nodeElement: Element, issues: IssuesManager.Issue.Issue[]) => void;
1271
+ performCopyOrCut?: (isCut: boolean, node: SDK.DOMModel.DOMNode, isElement?: boolean) => void;
1272
+ duplicateNode?: (node: SDK.DOMModel.DOMNode) => void;
1273
+ pasteNode?: (node: SDK.DOMModel.DOMNode) => void;
1274
+ canPaste?: (node: SDK.DOMModel.DOMNode) => boolean;
1275
+ toggleHideElement?: (node: SDK.DOMModel.DOMNode) => Promise<void>;
1276
+ isToggledToHidden?: (node: SDK.DOMModel.DOMNode) => boolean;
1277
+ selectNodeAfterEdit?: (wasExpanded: boolean, error: string|null,
1278
+ newNode: SDK.DOMModel.DOMNode|null) => ElementsTreeWidget | null;
1279
+ runPendingUpdates?: () => void;
1280
+ focusOutline?: () => void;
1281
+ setMultilineEditing?: (multilineEditing: EditorHandles|null) => void;
1282
+ visibleWidth?: () => number;
1283
+
1284
+ #view: View;
1244
1285
 
1245
1286
  private searchQuery: string|null;
1246
1287
  #expandedChildrenLimit: number;
@@ -1279,16 +1320,57 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1279
1320
 
1280
1321
  #updateRecord: Elements.ElementUpdateRecord.ElementUpdateRecord|null = null;
1281
1322
 
1282
- // Used to add the content to TreeElement's title element.
1283
- // Relied on by web tests.
1323
+ get node(): SDK.DOMModel.DOMNode {
1324
+ return this.#node;
1325
+ }
1284
1326
 
1285
- constructor(treeElement: ElementsTreeElement) {
1286
- super();
1287
- this.treeElement = treeElement as ElementsTreeElement & {treeOutline: ElementsTreeOutline | null};
1288
- const node = treeElement.node();
1289
- const isClosingTag = treeElement.isClosingTag();
1290
- this.nodeInternal = node;
1291
- this.treeElement.treeOutline = null;
1327
+ set node(node: SDK.DOMModel.DOMNode) {
1328
+ this.#node = node;
1329
+ if (!this.isClosingTag) {
1330
+ void this.#updateAdorners();
1331
+ }
1332
+ }
1333
+
1334
+ get expanded(): boolean {
1335
+ return this.#expanded;
1336
+ }
1337
+
1338
+ set expanded(expanded: boolean) {
1339
+ this.#expanded = expanded;
1340
+ this.requestUpdate();
1341
+ }
1342
+
1343
+ get isExpandable(): boolean {
1344
+ return this.#isExpandable;
1345
+ }
1346
+
1347
+ set isExpandable(isExpandable: boolean) {
1348
+ this.#isExpandable = isExpandable;
1349
+ this.requestUpdate();
1350
+ }
1351
+
1352
+ get selected(): boolean {
1353
+ return this.#selected;
1354
+ }
1355
+
1356
+ set selected(selected: boolean) {
1357
+ this.#selected = selected;
1358
+ this.requestUpdate();
1359
+ }
1360
+
1361
+ get tagTypeContext(): TagTypeContext {
1362
+ if (this.isClosingTag) {
1363
+ return {tagType: TagType.CLOSING};
1364
+ }
1365
+ return {
1366
+ tagType: TagType.OPENING,
1367
+ canAddAttributes: this.#node ? this.#node.nodeType() === Node.ELEMENT_NODE : false,
1368
+ };
1369
+ }
1370
+
1371
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
1372
+ super(element);
1373
+ this.#view = view;
1292
1374
 
1293
1375
  this.searchQuery = null;
1294
1376
  this.#expandedChildrenLimit = InitialChildrenLimit;
@@ -1298,18 +1380,9 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1298
1380
  this.#hovered = false;
1299
1381
 
1300
1382
  this.editing = null;
1301
-
1302
- if (!isClosingTag) {
1303
- void this.#updateAdorners();
1304
- }
1305
1383
  this.expandAllButtonElement = null;
1306
1384
  }
1307
1385
 
1308
- static animateOnDOMUpdate(treeElement: ElementsTreeElement): void {
1309
- const tagName = treeElement.listItemElement.querySelector('.webkit-html-tag-name');
1310
- UI.UIUtils.runCSSAnimationOnce(tagName || treeElement.listItemElement, DOM_UPDATE_ANIMATION_CLASS_NAME);
1311
- }
1312
-
1313
1386
  static visibleShadowRoots(node: SDK.DOMModel.DOMNode): SDK.DOMModel.DOMNode[] {
1314
1387
  let roots = node.shadowRoots();
1315
1388
  if (roots.length && !Common.Settings.Settings.instance().moduleSetting('show-ua-shadow-dom').get()) {
@@ -1358,6 +1431,11 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1358
1431
  }
1359
1432
  }
1360
1433
 
1434
+ animateOnDOMUpdate(): void {
1435
+ const tagName = this.contentElement.querySelector('.webkit-html-tag-name');
1436
+ UI.UIUtils.runCSSAnimationOnce(tagName || this.contentElement, DOM_UPDATE_ANIMATION_CLASS_NAME);
1437
+ }
1438
+
1361
1439
  #clearDOMNextUpdate = false;
1362
1440
 
1363
1441
  override performUpdate(): void {
@@ -1371,108 +1449,90 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1371
1449
  this.#clearDOMNextUpdate = false;
1372
1450
  Lit.render(Lit.nothing, this.contentElement, {host: this});
1373
1451
  }
1374
- const isClosingTag = this.treeElement.isClosingTag();
1452
+ const isClosingTag = this.isClosingTag;
1375
1453
  const output: ViewOutput = {};
1376
- DEFAULT_VIEW({
1377
- node: this.nodeInternal,
1454
+ this.#view({
1455
+ node: this.node,
1378
1456
  isClosingTag,
1379
- expanded: this.treeElement.expanded,
1380
- isExpandable: this.treeElement.isExpandable(),
1381
- isXMLMimeType: Boolean(this.treeElement.treeOutline?.isXMLMimeType),
1457
+ expanded: this.#expanded,
1458
+ isExpandable: this.#isExpandable,
1459
+ isXMLMimeType: this.isXMLMimeType,
1382
1460
  updateRecord: this.#updateRecord,
1383
1461
  onHighlightSearchResults: () => this.#highlightSearchResults(),
1384
- onExpand: () => this.treeElement.expand(),
1462
+ onExpand: () => this.expand?.(),
1385
1463
 
1386
1464
  containerAdornerActive: this.#containerAdornerActive,
1387
- adProvenance: this.nodeInternal.adProvenance(),
1465
+ adProvenance: this.node.adProvenance(),
1388
1466
  adTooltipId: this.#adTooltipId,
1389
- target: this.nodeInternal.domModel().target(),
1467
+ target: this.node.domModel().target(),
1390
1468
  showContainerAdorner: Boolean(this.#layout?.containerType) && !isClosingTag,
1391
1469
  containerType: this.#layout?.containerType,
1392
1470
  showFlexAdorner: Boolean(this.#layout?.isFlex) && !isClosingTag,
1393
1471
  flexAdornerActive: this.#flexAdornerActive,
1394
1472
  showGridAdorner: Boolean(this.#layout?.isGrid) && !isClosingTag,
1395
1473
  showGridLanesAdorner: Boolean(this.#layout?.isGridLanes) && !isClosingTag,
1396
- showMediaAdorner: this.node().isMediaNode() && !isClosingTag,
1397
- showPopoverAdorner: Boolean(this.node().attributes().find(attr => attr.name === 'popover')) && !isClosingTag,
1474
+ showMediaAdorner: this.node.isMediaNode() && !isClosingTag,
1475
+ showPopoverAdorner: Boolean(this.node.attributes().find(attr => attr.name === 'popover')) && !isClosingTag,
1398
1476
  showInterestAdorner: Boolean(Root.Runtime.hostConfig.devToolsAllowInterestForcing?.enabled) &&
1399
- Boolean(this.node().attributes().find(attr =>
1400
- attr.name === 'interesttarget' || attr.name === 'interestfor')) &&
1477
+ Boolean(this.node.attributes().find(attr => attr.name === 'interesttarget' || attr.name === 'interestfor')) &&
1401
1478
  !isClosingTag,
1402
- showTopLayerAdorner: this.node().topLayerIndex() !== -1 && !isClosingTag,
1479
+ showTopLayerAdorner: this.node.topLayerIndex() !== -1 && !isClosingTag,
1403
1480
  gridAdornerActive: this.#gridAdornerActive,
1404
1481
  popoverAdornerActive: this.#popoverAdornerActive,
1405
1482
  interestAdornerActive: this.#interestAdornerActive,
1406
1483
  isSubgrid: Boolean(this.#layout?.isSubgrid),
1407
- showViewSourceAdorner: this.nodeInternal.isRootNode() && isOpeningTag(this.treeElement.tagTypeContext),
1408
- showScrollAdorner: ((this.node().nodeName() === 'HTML' && this.node().ownerDocument?.isScrollable()) ||
1409
- (this.node().nodeName() !== '#document' && this.node().isScrollable())) &&
1484
+ showViewSourceAdorner: this.node.isRootNode() && isOpeningTag(this.tagTypeContext),
1485
+ showScrollAdorner: ((this.node.nodeName() === 'HTML' && this.node.ownerDocument?.isScrollable()) ||
1486
+ (this.node.nodeName() !== '#document' && this.node.isScrollable())) &&
1410
1487
  !isClosingTag,
1411
1488
  decorations: this.#decorations,
1412
- descendantDecorations: this.treeElement.expanded ? [] : this.#descendantDecorations,
1489
+ descendantDecorations: this.#expanded ? [] : this.#descendantDecorations,
1413
1490
  decorationsTooltip: this.#decorationsTooltip,
1414
- indent: this.computeLeftIndent(),
1491
+ indent: this.computeLeftIndent ? this.computeLeftIndent() : 0,
1415
1492
  showScrollSnapAdorner: Boolean(this.#layout?.hasScroll) && !isClosingTag,
1416
1493
  scrollSnapAdornerActive: this.#scrollSnapAdornerActive,
1417
- showSlotAdorner: Boolean(this.nodeInternal.assignedSlot) && !isClosingTag,
1418
- showCustomElementAdorner: this.node().isCustomElement() && !isClosingTag,
1419
- onCustomElementAdornerClick: this.treeElement.treeOutline?.disableEdits ?
1420
- () => {} :
1421
- (event: Event) => void this.#onCustomElementAdornerClick(event),
1422
- showStartingStyleAdorner: this.nodeInternal.affectedByStartingStyles() && !isClosingTag,
1494
+ showSlotAdorner: Boolean(this.node.assignedSlot) && !isClosingTag,
1495
+ showCustomElementAdorner: this.node.isCustomElement() && !isClosingTag,
1496
+ onCustomElementAdornerClick: this.disableEdits ? () => {} :
1497
+ (event: Event) => void this.#onCustomElementAdornerClick(event),
1498
+ showStartingStyleAdorner: this.node.affectedByStartingStyles() && !isClosingTag,
1423
1499
  startingStyleAdornerActive: this.#startingStyleAdornerActive,
1424
- onStartingStyleAdornerClick: this.treeElement.treeOutline?.disableEdits ?
1425
- () => {} :
1426
- (event: Event) => this.#onStartingStyleAdornerClick(event),
1500
+ onStartingStyleAdornerClick: this.disableEdits ? () => {} :
1501
+ (event: Event) => this.#onStartingStyleAdornerClick(event),
1427
1502
  onSlotAdornerClick:
1428
1503
  () => {
1429
- if (this.nodeInternal.assignedSlot) {
1430
- const deferredNode = this.nodeInternal.assignedSlot.deferredNode;
1504
+ if (this.node.assignedSlot) {
1505
+ const deferredNode = this.node.assignedSlot.deferredNode;
1431
1506
  deferredNode.resolve(node => {
1432
1507
  void Common.Revealer.reveal(node);
1433
1508
  });
1434
1509
  }
1435
1510
  },
1436
- topLayerIndex: this.node().topLayerIndex(),
1437
- onViewSourceAdornerClick: this.treeElement.treeOutline?.disableEdits ? () => {} :
1438
- this.revealHTMLInSources.bind(this),
1439
- onGutterClick: this.showContextMenu.bind(this),
1440
- onContainerAdornerClick: this.treeElement.treeOutline?.disableEdits ?
1441
- () => {} :
1442
- (event: Event) => this.#onContainerAdornerClick(event),
1443
- onFlexAdornerClick:
1444
- this.treeElement.treeOutline?.disableEdits ? () => {} : (event: Event) => this.#onFlexAdornerClick(event),
1445
- onGridAdornerClick:
1446
- this.treeElement.treeOutline?.disableEdits ? () => {} : (event: Event) => this.#onGridAdornerClick(event),
1447
- onMediaAdornerClick:
1448
- this.treeElement.treeOutline?.disableEdits ? () => {} : (event: Event) => this.#onMediaAdornerClick(event),
1449
- onPopoverAdornerClick:
1450
- this.treeElement.treeOutline?.disableEdits ? () => {} : (event: Event) => this.#onPopoverAdornerClick(event),
1451
- onInterestAdornerClick:
1452
- this.treeElement.treeOutline?.disableEdits ? () => {} : (event: Event) => this.#onInterestAdornerClick(event),
1453
- onScrollSnapAdornerClick: this.treeElement.treeOutline?.disableEdits ?
1454
- () => {} :
1455
- (event: Event) => this.#onScrollSnapAdornerClick(event),
1456
- onTopLayerAdornerClick: this.treeElement.treeOutline?.disableEdits ?
1457
- () => {} :
1458
- () => {
1459
- if (!this.treeElement.treeOutline) {
1460
- return;
1461
- }
1462
- this.treeElement.treeOutline.revealInTopLayer(this.node());
1463
- },
1511
+ topLayerIndex: this.node.topLayerIndex(),
1512
+ onViewSourceAdornerClick: this.disableEdits ? () => {} : this.revealHTMLInSources.bind(this),
1513
+ onGutterClick: this.showContextMenu ? (event: Event) => this.showContextMenu?.(event) : () => {},
1514
+ onContainerAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onContainerAdornerClick(event),
1515
+ onFlexAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onFlexAdornerClick(event),
1516
+ onGridAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onGridAdornerClick(event),
1517
+ onMediaAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onMediaAdornerClick(event),
1518
+ onPopoverAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onPopoverAdornerClick(event),
1519
+ onInterestAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onInterestAdornerClick(event),
1520
+ onScrollSnapAdornerClick: this.disableEdits ? () => {} : (event: Event) => this.#onScrollSnapAdornerClick(event),
1521
+ onTopLayerAdornerClick: this.disableEdits ? () => {} :
1522
+ () => {
1523
+ this.revealInTopLayer?.(this.node);
1524
+ },
1464
1525
  isHovered: this.#hovered,
1465
- isSelected: this.treeElement.selected,
1466
- canInspect: this.node().canInspectNode(),
1467
- showAiButton: Boolean(this.#hovered || this.treeElement.selected) &&
1468
- this.node().nodeType() === Node.ELEMENT_NODE && this.isAiButtonEnabled() &&
1469
- (this.treeElement.treeOutline as ElementsTreeOutline)?.showAIButton,
1526
+ isSelected: this.#selected,
1527
+ canInspect: this.node.canInspectNode(),
1528
+ showAiButton: Boolean(this.#hovered || this.#selected) && this.node.nodeType() === Node.ELEMENT_NODE &&
1529
+ this.isAiButtonEnabled() && this.showAIButton,
1470
1530
  aiButtonTitle: this.isAiButtonEnabled() ?
1471
1531
  UI.ActionRegistry.ActionRegistry.instance().getAction('freestyler.elements-floating-button').title() :
1472
1532
  undefined,
1473
1533
  onAiButtonClick: (ev: Event) => {
1474
1534
  ev.stopPropagation();
1475
- this.treeElement.select(true, false);
1535
+ this.selectTreeElement?.(true, false);
1476
1536
  const action = UI.ActionRegistry.ActionRegistry.instance().getAction('freestyler.elements-floating-button');
1477
1537
  if (action) {
1478
1538
  void action.execute();
@@ -1481,7 +1541,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1481
1541
  editorState: this.#editorState,
1482
1542
  editorWidth: this.#editorWidth,
1483
1543
  },
1484
- output, this.contentElement);
1544
+ output, this.contentElement);
1485
1545
 
1486
1546
  this.#editorRef = output.editorRef;
1487
1547
  if (this.#updateRecord) {
@@ -1491,7 +1551,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1491
1551
 
1492
1552
  async #onCustomElementAdornerClick(event: Event): Promise<void> {
1493
1553
  event.stopPropagation();
1494
- const node = this.node();
1554
+ const node = this.node;
1495
1555
  const object = await node.resolveToObject('');
1496
1556
  if (!object) {
1497
1557
  return;
@@ -1529,7 +1589,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1529
1589
 
1530
1590
  #onContainerAdornerClick(event: Event): void {
1531
1591
  event.stopPropagation();
1532
- const node = this.node();
1592
+ const node = this.node;
1533
1593
  const nodeId = node.id;
1534
1594
  if (!nodeId) {
1535
1595
  return;
@@ -1548,7 +1608,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1548
1608
 
1549
1609
  #onFlexAdornerClick(event: Event): void {
1550
1610
  event.stopPropagation();
1551
- const node = this.node();
1611
+ const node = this.node;
1552
1612
  const nodeId = node.id;
1553
1613
  if (!nodeId) {
1554
1614
  return;
@@ -1567,7 +1627,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1567
1627
 
1568
1628
  #onGridAdornerClick(event: Event): void {
1569
1629
  event.stopPropagation();
1570
- const node = this.node();
1630
+ const node = this.node;
1571
1631
  const nodeId = node.id;
1572
1632
  if (!nodeId) {
1573
1633
  return;
@@ -1594,7 +1654,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1594
1654
  const widget = await view.widget();
1595
1655
  if (widget instanceof Media.MainView.MainView) {
1596
1656
  await widget.waitForInitialPlayers();
1597
- widget.selectPlayerByDOMNodeId(this.node().backendNodeId());
1657
+ widget.selectPlayerByDOMNodeId(this.node.backendNodeId());
1598
1658
  }
1599
1659
  }
1600
1660
  }
@@ -1603,7 +1663,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1603
1663
  // If the attribute is not found, we highlight the tag name instead.
1604
1664
  let animationElement = this.contentElement.querySelector('.webkit-html-tag-name') ?? this.element;
1605
1665
 
1606
- if (this.nodeInternal.getAttribute(attributeName) !== undefined) {
1666
+ if (this.node.getAttribute(attributeName) !== undefined) {
1607
1667
  const tag = this.contentElement.querySelector('.webkit-html-tag');
1608
1668
  const attributes = tag?.getElementsByClassName('webkit-html-attribute') ?? [];
1609
1669
  for (const attribute of attributes) {
@@ -1621,10 +1681,6 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1621
1681
  return Boolean(this.#layout?.isContents);
1622
1682
  }
1623
1683
 
1624
- node(): SDK.DOMModel.DOMNode {
1625
- return this.nodeInternal;
1626
- }
1627
-
1628
1684
  get isEditing(): boolean {
1629
1685
  return Boolean(this.editing);
1630
1686
  }
@@ -1695,7 +1751,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1695
1751
  if (attribute.getElementsByClassName('webkit-html-attribute-name')[0].textContent === name) {
1696
1752
  const attributeElement = attribute.getElementsByClassName('webkit-html-attribute-name')[0];
1697
1753
  attributeElement.classList.add('violating-element');
1698
- this.#updateNodeElementToIssue(attributeElement, issue);
1754
+ this.#recordAndNotifyIssue(attributeElement, issue);
1699
1755
  }
1700
1756
  }
1701
1757
  }
@@ -1703,17 +1759,17 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1703
1759
  #highlightTagAsViolating(issue: IssuesManager.Issue.Issue): void {
1704
1760
  const tagElement = this.contentElement.querySelectorAll('.webkit-html-tag-name')[0];
1705
1761
  tagElement.classList.add('violating-element');
1706
- this.#updateNodeElementToIssue(tagElement, issue);
1762
+ this.#recordAndNotifyIssue(tagElement, issue);
1707
1763
  }
1708
1764
 
1709
- #updateNodeElementToIssue(nodeElement: Element, issue: IssuesManager.Issue.Issue): void {
1765
+ #recordAndNotifyIssue(nodeElement: Element, issue: IssuesManager.Issue.Issue): void {
1710
1766
  let issues = this.#nodeElementToIssue.get(nodeElement);
1711
1767
  if (!issues) {
1712
1768
  issues = [];
1713
1769
  this.#nodeElementToIssue.set(nodeElement, issues);
1714
1770
  }
1715
1771
  issues.push(issue);
1716
- this.treeElement.treeOutline?.updateNodeElementToIssue(nodeElement, issues);
1772
+ this.updateNodeElementToIssue?.(nodeElement, issues);
1717
1773
  }
1718
1774
 
1719
1775
  removeIssue(issue: IssuesManager.Issue.Issue): void {
@@ -1774,7 +1830,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1774
1830
  } else {
1775
1831
  this.#nodeElementToIssue.set(nodeElement, issues);
1776
1832
  }
1777
- this.treeElement.treeOutline?.updateNodeElementToIssue(nodeElement, issues);
1833
+ this.updateNodeElementToIssue?.(nodeElement, issues);
1778
1834
  }
1779
1835
 
1780
1836
  expandedChildrenLimit(): number {
@@ -1791,25 +1847,20 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1791
1847
 
1792
1848
  onbind(): void {
1793
1849
  this.requestUpdate();
1794
- if (this.treeElement.treeOutline && !this.treeElement.isClosingTag()) {
1795
- this.treeElement.treeOutline.treeElementByNode.set(this.nodeInternal, this.treeElement);
1796
- this.nodeInternal.addEventListener(
1797
- SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.onTopLayerIndexChanged, this);
1798
- this.nodeInternal.addEventListener(
1799
- SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated, this);
1800
- this.nodeInternal.addEventListener(
1801
- SDK.DOMModel.DOMNodeEvents.AD_RELATED_STATE_UPDATED, this.#onAdRelatedStateUpdated, this);
1802
- this.nodeInternal.addEventListener(
1803
- SDK.DOMModel.DOMNodeEvents.CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1804
- this.#onPersistentContainerQueryOverlayStateChanged, this);
1805
- this.nodeInternal.addEventListener(
1806
- SDK.DOMModel.DOMNodeEvents.FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1807
- this.#onPersistentFlexContainerOverlayStateChanged, this);
1808
- this.nodeInternal.addEventListener(
1809
- SDK.DOMModel.DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED, this.#onPersistentGridOverlayStateChanged, this);
1810
- this.nodeInternal.addEventListener(
1811
- SDK.DOMModel.DOMNodeEvents.SCROLL_SNAP_OVERLAY_STATE_CHANGED, this.#onPersistentScrollSnapOverlayStateChanged,
1812
- this);
1850
+ if (!this.isClosingTag) {
1851
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.onTopLayerIndexChanged, this);
1852
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated,
1853
+ this);
1854
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.AD_RELATED_STATE_UPDATED, this.#onAdRelatedStateUpdated,
1855
+ this);
1856
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1857
+ this.#onPersistentContainerQueryOverlayStateChanged, this);
1858
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1859
+ this.#onPersistentFlexContainerOverlayStateChanged, this);
1860
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED,
1861
+ this.#onPersistentGridOverlayStateChanged, this);
1862
+ this.node.addEventListener(SDK.DOMModel.DOMNodeEvents.SCROLL_SNAP_OVERLAY_STATE_CHANGED,
1863
+ this.#onPersistentScrollSnapOverlayStateChanged, this);
1813
1864
  }
1814
1865
  }
1815
1866
 
@@ -1818,7 +1869,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1818
1869
  // ElementsPanel.
1819
1870
  // We do not change the ElementsTreeElement state in case the
1820
1871
  // element is bound again.
1821
- DEFAULT_VIEW({
1872
+ this.#view({
1822
1873
  node: null,
1823
1874
  isClosingTag: false,
1824
1875
  expanded: false,
@@ -1879,7 +1930,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1879
1930
  editorState: null,
1880
1931
  editorWidth: null,
1881
1932
  },
1882
- {}, this.contentElement);
1933
+ {}, this.contentElement);
1883
1934
  }
1884
1935
 
1885
1936
  onunbind(): void {
@@ -1887,27 +1938,20 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1887
1938
  this.editing.cancel();
1888
1939
  }
1889
1940
  this.clearView();
1890
- if (this.treeElement.treeOutline &&
1891
- this.treeElement.treeOutline.treeElementByNode.get(this.nodeInternal) === this.treeElement) {
1892
- this.treeElement.treeOutline.treeElementByNode.delete(this.nodeInternal);
1893
- }
1894
- this.nodeInternal.removeEventListener(
1895
- SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.onTopLayerIndexChanged, this);
1896
- this.nodeInternal.removeEventListener(
1897
- SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated, this);
1898
- this.nodeInternal.removeEventListener(
1899
- SDK.DOMModel.DOMNodeEvents.AD_RELATED_STATE_UPDATED, this.#onAdRelatedStateUpdated, this);
1900
- this.nodeInternal.removeEventListener(
1901
- SDK.DOMModel.DOMNodeEvents.CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1902
- this.#onPersistentContainerQueryOverlayStateChanged, this);
1903
- this.nodeInternal.removeEventListener(
1904
- SDK.DOMModel.DOMNodeEvents.FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1905
- this.#onPersistentFlexContainerOverlayStateChanged, this);
1906
- this.nodeInternal.removeEventListener(
1907
- SDK.DOMModel.DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED, this.#onPersistentGridOverlayStateChanged, this);
1908
- this.nodeInternal.removeEventListener(
1909
- SDK.DOMModel.DOMNodeEvents.SCROLL_SNAP_OVERLAY_STATE_CHANGED, this.#onPersistentScrollSnapOverlayStateChanged,
1910
- this);
1941
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.onTopLayerIndexChanged,
1942
+ this);
1943
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated,
1944
+ this);
1945
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.AD_RELATED_STATE_UPDATED, this.#onAdRelatedStateUpdated,
1946
+ this);
1947
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1948
+ this.#onPersistentContainerQueryOverlayStateChanged, this);
1949
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1950
+ this.#onPersistentFlexContainerOverlayStateChanged, this);
1951
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED,
1952
+ this.#onPersistentGridOverlayStateChanged, this);
1953
+ this.node.removeEventListener(SDK.DOMModel.DOMNodeEvents.SCROLL_SNAP_OVERLAY_STATE_CHANGED,
1954
+ this.#onPersistentScrollSnapOverlayStateChanged, this);
1911
1955
  }
1912
1956
 
1913
1957
  #onScrollableFlagUpdated(): void {
@@ -1940,7 +1984,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1940
1984
 
1941
1985
  #onScrollSnapAdornerClick(event: Event): void {
1942
1986
  event.stopPropagation();
1943
- const node = this.node();
1987
+ const node = this.node;
1944
1988
  const nodeId = node.id;
1945
1989
  if (!nodeId) {
1946
1990
  return;
@@ -1959,53 +2003,42 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
1959
2003
  this.requestUpdate();
1960
2004
  }
1961
2005
 
1962
- this.treeElement.updateTitle();
2006
+ this.updateTitle();
1963
2007
  this.element.draggable = true;
1964
2008
  }
1965
2009
 
1966
2010
  async onpopulate(): Promise<void> {
1967
- if (this.treeElement.treeOutline) {
1968
- return await this.treeElement.treeOutline.populateTreeElement(this.treeElement);
2011
+ if (this.populateTreeElement) {
2012
+ return await this.populateTreeElement();
1969
2013
  }
1970
2014
  }
1971
2015
 
1972
2016
  onexpand(): void {
1973
- if (this.treeElement.isClosingTag()) {
2017
+ if (this.isClosingTag) {
1974
2018
  return;
1975
2019
  }
1976
2020
 
1977
- this.treeElement.updateTitle();
2021
+ this.updateTitle();
1978
2022
  }
1979
2023
 
1980
2024
  oncollapse(): void {
1981
- if (this.treeElement.isClosingTag()) {
2025
+ if (this.isClosingTag) {
1982
2026
  return;
1983
2027
  }
1984
2028
 
1985
- this.treeElement.updateTitle();
2029
+ this.updateTitle();
1986
2030
  }
1987
2031
 
1988
2032
  onselect(selectedByUser?: boolean): boolean {
1989
- if (!this.treeElement.treeOutline) {
2033
+ if (!this.selectDOMNode) {
1990
2034
  return false;
1991
2035
  }
1992
- this.treeElement.treeOutline.suppressRevealAndSelect = true;
1993
- this.treeElement.treeOutline.selectDOMNode(this.nodeInternal, selectedByUser);
2036
+ this.selectDOMNode(this.node, selectedByUser);
1994
2037
  if (selectedByUser) {
1995
- this.nodeInternal.highlight();
2038
+ this.node.highlight();
1996
2039
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.ChangeInspectedNodeInElementsPanel);
1997
2040
  }
1998
2041
  this.requestUpdate();
1999
- this.treeElement.treeOutline.suppressRevealAndSelect = false;
2000
- return true;
2001
- }
2002
-
2003
- ondelete(): boolean {
2004
- if (!this.treeElement.treeOutline) {
2005
- return false;
2006
- }
2007
- const startTagTreeElement = this.treeElement.treeOutline.findTreeElement(this.nodeInternal);
2008
- startTagTreeElement ? (void (startTagTreeElement as ElementsTreeElement).remove()) : (void this.remove());
2009
2042
  return true;
2010
2043
  }
2011
2044
 
@@ -2023,7 +2056,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2023
2056
  }
2024
2057
 
2025
2058
  ondblclick(event: Event): boolean {
2026
- if (this.editing || this.treeElement.isClosingTag()) {
2059
+ if (this.editing || this.isClosingTag) {
2027
2060
  return false;
2028
2061
  }
2029
2062
  const target = (event.composedPath()[0] || event.target) as Element;
@@ -2031,14 +2064,13 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2031
2064
  return false;
2032
2065
  }
2033
2066
 
2034
- if (this.treeElement.isExpandable() && !this.treeElement.expanded) {
2035
- this.treeElement.expand();
2067
+ if (this.#isExpandable && !this.#expanded) {
2068
+ this.expand?.();
2036
2069
  }
2037
2070
  return false;
2038
2071
  }
2039
-
2040
2072
  hasEditableNode(): boolean {
2041
- return !this.nodeInternal.isShadowRoot() && !this.nodeInternal.ancestorUserAgentShadowRoot();
2073
+ return !this.node.isShadowRoot() && !this.node.ancestorUserAgentShadowRoot();
2042
2074
  }
2043
2075
 
2044
2076
  private insertInLastAttributePosition(tag: Element, node: Element): void {
@@ -2058,12 +2090,12 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2058
2090
  }
2059
2091
 
2060
2092
  private startEditingTarget(eventTarget: Element): boolean {
2061
- if (!this.treeElement.treeOutline || this.treeElement.treeOutline.selectedDOMNode() !== this.nodeInternal) {
2093
+ if (!this.isDOMNodeSelected) {
2062
2094
  return false;
2063
2095
  }
2064
2096
 
2065
- if (this.nodeInternal.nodeType() !== Node.ELEMENT_NODE && this.nodeInternal.nodeType() !== Node.TEXT_NODE &&
2066
- this.nodeInternal.nodeType() !== Node.PROCESSING_INSTRUCTION_NODE) {
2097
+ if (this.node.nodeType() !== Node.ELEMENT_NODE && this.node.nodeType() !== Node.TEXT_NODE &&
2098
+ this.node.nodeType() !== Node.PROCESSING_INSTRUCTION_NODE) {
2067
2099
  return false;
2068
2100
  }
2069
2101
 
@@ -2080,23 +2112,19 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2080
2112
 
2081
2113
  const tagName = eventTarget.enclosingNodeOrSelfWithClass('webkit-html-tag-name');
2082
2114
  if (tagName) {
2083
- return this.treeElement.startEditingTagName(tagName);
2115
+ return this.startEditingTagName(tagName);
2084
2116
  }
2085
2117
 
2086
2118
  const newAttribute = eventTarget.enclosingNodeOrSelfWithClass('add-attribute');
2087
2119
  if (newAttribute) {
2088
- return this.treeElement.addNewAttribute();
2120
+ return this.addNewAttribute();
2089
2121
  }
2090
2122
 
2091
2123
  return false;
2092
2124
  }
2093
2125
 
2094
- private showContextMenu(event: Event): void {
2095
- this.treeElement.treeOutline && void this.treeElement.treeOutline.showContextMenu(this.treeElement, event);
2096
- }
2097
-
2098
2126
  private revealHTMLInSources(): void {
2099
- const frameOwnerId = this.nodeInternal.frameOwnerFrameId();
2127
+ const frameOwnerId = this.node.frameOwnerFrameId();
2100
2128
  if (frameOwnerId) {
2101
2129
  const frame = SDK.FrameManager.FrameManager.instance().getFrame(frameOwnerId);
2102
2130
  if (frame) {
@@ -2107,16 +2135,13 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2107
2135
  }
2108
2136
 
2109
2137
  async populateTagContextMenu(contextMenu: UI.ContextMenu.ContextMenu, event: Event): Promise<void> {
2110
- // Add attribute-related actions.
2111
- const treeElement = this.treeElement.isClosingTag() && this.treeElement.treeOutline ?
2112
- this.treeElement.treeOutline.findTreeElement(this.nodeInternal) as ElementsTreeElement | null :
2113
- this.treeElement;
2114
- if (!treeElement) {
2138
+ const targetWidget = this.isClosingTag ? this.findStartTagWidget?.() : this;
2139
+ if (!targetWidget) {
2115
2140
  return;
2116
2141
  }
2117
- contextMenu.editSection().appendItem(
2118
- i18nString(UIStrings.addAttribute), treeElement.addNewAttribute.bind(treeElement),
2119
- {jslogContext: 'add-attribute'});
2142
+ contextMenu.editSection().appendItem(i18nString(UIStrings.addAttribute),
2143
+ targetWidget.addNewAttribute.bind(targetWidget),
2144
+ {jslogContext: 'add-attribute'});
2120
2145
 
2121
2146
  const target = (event.composedPath()[0] || event.target) as Element;
2122
2147
  const attribute = target.enclosingNodeOrSelfWithClass('webkit-html-attribute');
@@ -2127,15 +2152,15 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2127
2152
  {jslogContext: 'edit-attribute'});
2128
2153
  }
2129
2154
  await this.populateNodeContextMenu(contextMenu);
2130
- ElementsTreeWidget.populateForcedPseudoStateItems(contextMenu, treeElement.node());
2155
+ ElementsTreeWidget.populateForcedPseudoStateItems(contextMenu, this.node);
2131
2156
  this.populateScrollIntoView(contextMenu);
2132
2157
  contextMenu.viewSection().appendItem(i18nString(UIStrings.focus), async () => {
2133
- await this.nodeInternal.focus();
2158
+ await this.node.focus();
2134
2159
  }, {jslogContext: 'focus'});
2135
2160
  }
2136
2161
 
2137
2162
  populatePseudoElementContextMenu(contextMenu: UI.ContextMenu.ContextMenu): void {
2138
- if (this.treeElement.childCount() !== 0) {
2163
+ if ((this.childCount?.() ?? 0) !== 0) {
2139
2164
  this.populateExpandRecursively(contextMenu);
2140
2165
  }
2141
2166
 
@@ -2143,15 +2168,15 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2143
2168
  }
2144
2169
 
2145
2170
  private populateExpandRecursively(contextMenu: UI.ContextMenu.ContextMenu): void {
2146
- contextMenu.viewSection().appendItem(i18nString(UIStrings.expandRecursively),
2147
- this.treeElement.expandRecursively.bind(this.treeElement),
2148
- {jslogContext: 'expand-recursively'});
2171
+ if (this.expandRecursively) {
2172
+ contextMenu.viewSection().appendItem(i18nString(UIStrings.expandRecursively),
2173
+ () => void this.expandRecursively?.(), {jslogContext: 'expand-recursively'});
2174
+ }
2149
2175
  }
2150
2176
 
2151
2177
  private populateScrollIntoView(contextMenu: UI.ContextMenu.ContextMenu): void {
2152
- contextMenu.viewSection().appendItem(
2153
- i18nString(UIStrings.scrollIntoView), () => this.nodeInternal.scrollIntoView(),
2154
- {jslogContext: 'scroll-into-view'});
2178
+ contextMenu.viewSection().appendItem(i18nString(UIStrings.scrollIntoView), () => this.node.scrollIntoView(),
2179
+ {jslogContext: 'scroll-into-view'});
2155
2180
  }
2156
2181
 
2157
2182
  private isAiButtonEnabled(): boolean {
@@ -2175,14 +2200,10 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2175
2200
  contextMenu.editSection().appendItem(i18nString(UIStrings.editAsHtml), this.editAsHTML.bind(this), { jslogContext: 'elements.edit-as-html' });
2176
2201
  }
2177
2202
  // clang-format on
2178
- const isShadowRoot = this.nodeInternal.isShadowRoot();
2203
+ const isShadowRoot = this.node.isShadowRoot();
2179
2204
 
2180
2205
  const createShortcut = UI.KeyboardShortcut.KeyboardShortcut.shortcutToString.bind(null);
2181
2206
  const modifier = UI.KeyboardShortcut.Modifiers.CtrlOrMeta.value;
2182
- const treeOutline = this.treeElement.treeOutline;
2183
- if (!treeOutline) {
2184
- return;
2185
- }
2186
2207
  let menuItem;
2187
2208
 
2188
2209
  const openAiAssistanceId = 'freestyler.element-panel-context';
@@ -2195,8 +2216,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2195
2216
  UI.UIUtils.PromotionManager.instance().recordFeatureInteraction(openAiAssistanceId);
2196
2217
  }, {disabled: !action.enabled(), jslogContext});
2197
2218
  }
2198
-
2199
- UI.Context.Context.instance().setFlavor(SDK.DOMModel.DOMNode, this.nodeInternal);
2219
+ UI.Context.Context.instance().setFlavor(SDK.DOMModel.DOMNode, this.node);
2200
2220
  const action = UI.ActionRegistry.ActionRegistry.instance().getAction(openAiAssistanceId);
2201
2221
  const submenu = contextMenu.footerSection().appendSubMenuItem(action.title(), false, openAiAssistanceId);
2202
2222
  submenu.defaultSection().appendAction(openAiAssistanceId, i18nString(UIStrings.startAChat));
@@ -2321,8 +2341,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2321
2341
  },
2322
2342
  ];
2323
2343
 
2324
- const layoutProps =
2325
- await this.nodeInternal.domModel().cssModel().getLayoutPropertiesFromComputedStyle(this.nodeInternal.id);
2344
+ const layoutProps = await this.node.domModel().cssModel().getLayoutPropertiesFromComputedStyle(this.node.id);
2326
2345
  const config = submenuConfigs.find(c => c.condition(layoutProps));
2327
2346
  if (config) {
2328
2347
  for (const item of config.items) {
@@ -2332,26 +2351,24 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2332
2351
  }
2333
2352
  }
2334
2353
 
2335
- menuItem = contextMenu.clipboardSection().appendItem(
2336
- i18nString(UIStrings.cut), treeOutline.performCopyOrCut.bind(treeOutline, true, this.nodeInternal),
2337
- {disabled: !this.hasEditableNode(), jslogContext: 'cut'});
2354
+ menuItem = contextMenu.clipboardSection().appendItem(i18nString(UIStrings.cut),
2355
+ () => this.performCopyOrCut?.(true, this.node),
2356
+ {disabled: !this.hasEditableNode(), jslogContext: 'cut'});
2338
2357
  menuItem.setShortcut(createShortcut('X', modifier));
2339
2358
 
2340
2359
  // Place it here so that all "Copy"-ing items stick together.
2341
2360
  const copyMenu = contextMenu.clipboardSection().appendSubMenuItem(i18nString(UIStrings.copy), false, 'copy');
2342
2361
  const section = copyMenu.section();
2343
2362
  if (!isShadowRoot) {
2344
- menuItem = section.appendItem(
2345
- i18nString(UIStrings.copyOuterhtml), treeOutline.performCopyOrCut.bind(treeOutline, false, this.nodeInternal),
2346
- {jslogContext: 'copy-outer-html'});
2363
+ menuItem = section.appendItem(i18nString(UIStrings.copyOuterhtml),
2364
+ () => this.performCopyOrCut?.(false, this.node), {jslogContext: 'copy-outer-html'});
2347
2365
  menuItem.setShortcut(createShortcut('V', modifier));
2348
2366
  }
2349
- if (this.nodeInternal.nodeType() === Node.ELEMENT_NODE) {
2367
+ if (this.node.nodeType() === Node.ELEMENT_NODE) {
2350
2368
  section.appendItem(
2351
2369
  i18nString(UIStrings.copySelector), this.copyCSSPath.bind(this), {jslogContext: 'copy-selector'});
2352
- section.appendItem(
2353
- i18nString(UIStrings.copyJsPath), this.copyJSPath.bind(this),
2354
- {disabled: !canGetJSPath(this.nodeInternal), jslogContext: 'copy-js-path'});
2370
+ section.appendItem(i18nString(UIStrings.copyJsPath), this.copyJSPath.bind(this),
2371
+ {disabled: !canGetJSPath(this.node), jslogContext: 'copy-js-path'});
2355
2372
  section.appendItem(
2356
2373
  i18nString(UIStrings.copyStyles), this.copyStyles.bind(this), {jslogContext: 'elements.copy-styles'});
2357
2374
  }
@@ -2361,31 +2378,31 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2361
2378
  i18nString(UIStrings.copyFullXpath), this.copyFullXPath.bind(this), {jslogContext: 'copy-full-xpath'});
2362
2379
  }
2363
2380
 
2364
- menuItem = copyMenu.clipboardSection().appendItem(
2365
- i18nString(UIStrings.copyElement),
2366
- treeOutline.performCopyOrCut.bind(treeOutline, false, this.nodeInternal, true), {jslogContext: 'copy-element'});
2381
+ menuItem = copyMenu.clipboardSection().appendItem(i18nString(UIStrings.copyElement),
2382
+ () => this.performCopyOrCut?.(false, this.node, true),
2383
+ {jslogContext: 'copy-element'});
2367
2384
  menuItem.setShortcut(createShortcut('C', modifier));
2368
2385
 
2369
2386
  if (!isShadowRoot) {
2370
2387
  // Duplicate element, disabled on root element and ShadowDOM.
2371
- const isRootElement = !this.nodeInternal.parentNode || this.nodeInternal.parentNode.nodeName() === '#document';
2372
- menuItem = contextMenu.editSection().appendItem(
2373
- i18nString(UIStrings.duplicateElement), treeOutline.duplicateNode.bind(treeOutline, this.nodeInternal), {
2374
- disabled: (this.nodeInternal.isInShadowTree() || isRootElement),
2375
- jslogContext: 'elements.duplicate-element',
2376
- });
2388
+ const isRootElement = !this.node.parentNode || this.node.parentNode.nodeName() === '#document';
2389
+ menuItem = contextMenu.editSection().appendItem(i18nString(UIStrings.duplicateElement),
2390
+ () => this.duplicateNode?.(this.node), {
2391
+ disabled: (this.node.isInShadowTree() || isRootElement),
2392
+ jslogContext: 'elements.duplicate-element',
2393
+ });
2377
2394
  }
2378
2395
 
2379
- menuItem = contextMenu.clipboardSection().appendItem(
2380
- i18nString(UIStrings.paste), treeOutline.pasteNode.bind(treeOutline, this.nodeInternal),
2381
- {disabled: !treeOutline.canPaste(this.nodeInternal), jslogContext: 'paste'});
2396
+ menuItem =
2397
+ contextMenu.clipboardSection().appendItem(i18nString(UIStrings.paste), () => this.pasteNode?.(this.node),
2398
+ {disabled: !this.canPaste?.(this.node), jslogContext: 'paste'});
2382
2399
  menuItem.setShortcut(createShortcut('V', modifier));
2383
2400
 
2384
- menuItem = contextMenu.debugSection().appendCheckboxItem(
2385
- i18nString(UIStrings.hideElement), treeOutline.toggleHideElement.bind(treeOutline, this.nodeInternal), {
2386
- checked: treeOutline.isToggledToHidden(this.nodeInternal),
2387
- jslogContext: 'elements.hide-element',
2388
- });
2401
+ menuItem = contextMenu.debugSection().appendCheckboxItem(i18nString(UIStrings.hideElement),
2402
+ () => this.toggleHideElement?.(this.node), {
2403
+ checked: Boolean(this.isToggledToHidden?.(this.node)),
2404
+ jslogContext: 'elements.hide-element',
2405
+ });
2389
2406
  menuItem.setShortcut(
2390
2407
  UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutTitleForAction('elements.hide-element') || '');
2391
2408
 
@@ -2395,8 +2412,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2395
2412
  }
2396
2413
 
2397
2414
  this.populateExpandRecursively(contextMenu);
2398
- contextMenu.viewSection().appendItem(i18nString(UIStrings.collapseChildren),
2399
- this.treeElement.collapseChildren.bind(this.treeElement),
2415
+ contextMenu.viewSection().appendItem(i18nString(UIStrings.collapseChildren), () => this.collapseChildren?.(),
2400
2416
  {jslogContext: 'collapse-children'});
2401
2417
  contextMenu.viewSection().appendItem(i18nString(UIStrings.switchToAccessibilityTree),
2402
2418
  () => ElementsPanel.instance().toggleAccessibilityTree(),
@@ -2407,9 +2423,9 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2407
2423
  deviceModeWrapperAction.handleAction.bind(
2408
2424
  null, UI.Context.Context.instance(), 'emulation.capture-node-screenshot'),
2409
2425
  {jslogContext: 'emulation.capture-node-screenshot'});
2410
- if (this.nodeInternal.frameOwnerFrameId()) {
2426
+ if (this.node.frameOwnerFrameId()) {
2411
2427
  contextMenu.viewSection().appendItem(i18nString(UIStrings.showFrameDetails), () => {
2412
- const frameOwnerFrameId = this.nodeInternal.frameOwnerFrameId();
2428
+ const frameOwnerFrameId = this.node.frameOwnerFrameId();
2413
2429
  if (frameOwnerFrameId) {
2414
2430
  const frame = SDK.FrameManager.FrameManager.instance().getFrame(frameOwnerFrameId);
2415
2431
  void Common.Revealer.reveal(frame);
@@ -2419,49 +2435,44 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2419
2435
  }
2420
2436
 
2421
2437
  async populateProcessingElementContextMenu(contextMenu: UI.ContextMenu.ContextMenu): Promise<void> {
2422
- const treeOutline = this.treeElement.treeOutline;
2423
- if (!treeOutline) {
2424
- return;
2425
- }
2426
-
2427
2438
  contextMenu.editSection().appendItem(
2428
2439
  i18nString(UIStrings.editData), this.startEditingProcessingInstructionValue.bind(this),
2429
2440
  {jslogContext: 'elements.edit-data'});
2430
- contextMenu.editSection().appendItem(
2431
- i18nString(UIStrings.duplicateElement), treeOutline.duplicateNode.bind(treeOutline, this.nodeInternal), {
2432
- disabled: (this.nodeInternal.isInShadowTree()),
2433
- jslogContext: 'elements.duplicate-element',
2434
- });
2441
+ contextMenu.editSection().appendItem(i18nString(UIStrings.duplicateElement), () => this.duplicateNode?.(this.node),
2442
+ {
2443
+ disabled: (this.node.isInShadowTree()),
2444
+ jslogContext: 'elements.duplicate-element',
2445
+ });
2435
2446
  contextMenu.editSection().appendItem(
2436
2447
  i18nString(UIStrings.deleteElement), this.remove.bind(this), {jslogContext: 'delete-element'});
2437
2448
  }
2438
2449
 
2439
2450
  private startEditing(): boolean|undefined {
2440
- if (!this.treeElement.treeOutline || this.treeElement.treeOutline.selectedDOMNode() !== this.nodeInternal) {
2451
+ if (!this.isDOMNodeSelected) {
2441
2452
  return;
2442
2453
  }
2443
2454
 
2444
2455
  const listItem = this.element;
2445
2456
 
2446
- if (isOpeningTag(this.treeElement.tagTypeContext) && this.treeElement.tagTypeContext.canAddAttributes) {
2457
+ if (isOpeningTag(this.tagTypeContext) && this.tagTypeContext.canAddAttributes) {
2447
2458
  const attribute = listItem.getElementsByClassName('webkit-html-attribute')[0];
2448
2459
  if (attribute) {
2449
2460
  return this.startEditingAttribute(
2450
2461
  attribute, attribute.getElementsByClassName('webkit-html-attribute-value')[0]);
2451
2462
  }
2452
2463
 
2453
- return this.treeElement.addNewAttribute();
2464
+ return this.addNewAttribute();
2454
2465
  }
2455
2466
 
2456
- if (this.nodeInternal.nodeType() === Node.TEXT_NODE) {
2467
+ if (this.node.nodeType() === Node.TEXT_NODE) {
2457
2468
  const textNode = listItem.getElementsByClassName('webkit-html-text-node')[0];
2458
2469
  if (textNode) {
2459
2470
  return this.startEditingTextNode(textNode);
2460
2471
  }
2461
2472
  }
2462
2473
 
2463
- if (this.nodeInternal.nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
2464
- return this.treeElement.startEditingProcessingInstructionValue();
2474
+ if (this.node.nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
2475
+ return this.startEditingProcessingInstructionValue();
2465
2476
  }
2466
2477
 
2467
2478
  return;
@@ -2481,7 +2492,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2481
2492
  // a parent node. Use a temporary span container for the HTML.
2482
2493
  const container = document.createDocumentFragment();
2483
2494
 
2484
- Lit.render(renderAttribute({name: ' ', value: ''}, null, false, this.nodeInternal), container);
2495
+ Lit.render(renderAttribute({name: ' ', value: ''}, null, false, this.node), container);
2485
2496
  const attr = container.firstElementChild as HTMLElement;
2486
2497
  attr.style.marginLeft = '2px'; // overrides the .editing margin rule
2487
2498
  attr.style.marginRight = '2px'; // overrides the .editing margin rule
@@ -2546,14 +2557,14 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2546
2557
  }
2547
2558
 
2548
2559
  let attributeValue = attributeName && attributeValueElement ?
2549
- this.nodeInternal.getAttribute(attributeName)?.replaceAll('"', '&quot;') :
2560
+ this.node.getAttribute(attributeName)?.replaceAll('"', '&quot;') :
2550
2561
  undefined;
2551
2562
 
2552
2563
  const isRelation =
2553
2564
  attributeName === 'popovertarget' || attributeName === 'interesttarget' || attributeName === 'commandfor';
2554
2565
  if (isRelation && attributeName && attributeValueElement) {
2555
- const rawValue = this.nodeInternal.getAttribute(attributeName) || '';
2556
- const relatedElement = relatedElementsCache.get(this.nodeInternal)?.get(`${attributeName}:${rawValue}`);
2566
+ const rawValue = this.node.getAttribute(attributeName) || '';
2567
+ const relatedElement = relatedElementsCache.get(this.node)?.get(`${attributeName}:${rawValue}`);
2557
2568
  if (relatedElement) {
2558
2569
  attributeValue = relatedElement.getAttribute('id') || '';
2559
2570
  }
@@ -2592,7 +2603,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2592
2603
  return true;
2593
2604
  }
2594
2605
 
2595
- let textNode: SDK.DOMModel.DOMNode = this.nodeInternal;
2606
+ let textNode: SDK.DOMModel.DOMNode = this.node;
2596
2607
  // We only show text nodes inline in elements if the element only
2597
2608
  // has a single child, and that child is a text node.
2598
2609
  if (textNode.nodeType() === Node.ELEMENT_NODE && textNode.firstChild) {
@@ -2705,9 +2716,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2705
2716
  }
2706
2717
 
2707
2718
  // Hide children item.
2708
- if (this.treeElement.childrenListElement) {
2709
- this.treeElement.childrenListElement.style.display = 'none';
2710
- }
2719
+ this.setChildrenListElementVisible?.(false);
2711
2720
  const initialValue = convertUnicodeCharsToHTMLEntities(maybeInitialValue).text;
2712
2721
  // Append editor.
2713
2722
  this.#editorState = CodeMirror.EditorState.create({
@@ -2791,14 +2800,13 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2791
2800
  this.requestUpdate();
2792
2801
  resize.call(this);
2793
2802
  this.editing = {commit: commit.bind(this), cancel: dispose.bind(this), resize: resize.bind(this)};
2794
- (this.treeElement.treeOutline as ElementsTreeOutline | null)?.setMultilineEditing(this.editing);
2803
+ this.setMultilineEditing?.(this.editing);
2795
2804
  await this.updateComplete;
2796
2805
  this.#editorRef?.focus();
2797
2806
 
2798
2807
  function resize(this: ElementsTreeWidget): void {
2799
- if (this.treeElement.treeOutline) {
2800
- this.#editorWidth =
2801
- (this.treeElement.treeOutline as ElementsTreeOutline).visibleWidth() - this.computeLeftIndent() - 30;
2808
+ if (this.visibleWidth) {
2809
+ this.#editorWidth = this.visibleWidth() - (this.computeLeftIndent ? this.computeLeftIndent() : 0) - 30;
2802
2810
  this.requestUpdate();
2803
2811
  }
2804
2812
  }
@@ -2818,14 +2826,12 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2818
2826
  this.#editorState = null;
2819
2827
  this.requestUpdate();
2820
2828
  // Unhide children item.
2821
- if (this.treeElement.childrenListElement) {
2822
- this.treeElement.childrenListElement.style.removeProperty('display');
2823
- }
2829
+ this.setChildrenListElementVisible?.(true);
2824
2830
 
2825
- if (this.treeElement.treeOutline) {
2826
- (this.treeElement.treeOutline as ElementsTreeOutline).setMultilineEditing(null);
2827
- this.treeElement.treeOutline.focus();
2831
+ if (this.setMultilineEditing) {
2832
+ this.setMultilineEditing(null);
2828
2833
  }
2834
+ this.focusOutline?.();
2829
2835
 
2830
2836
  disposeCallback();
2831
2837
  }
@@ -2840,8 +2846,6 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2840
2846
  ): void {
2841
2847
  this.editing = null;
2842
2848
 
2843
- const treeOutline = this.treeElement.treeOutline;
2844
-
2845
2849
  function moveToNextAttributeIfNeeded(this: ElementsTreeWidget, error?: string|null): void {
2846
2850
  if (error) {
2847
2851
  this.editingCancelled(element, attributeName);
@@ -2851,13 +2855,11 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2851
2855
  return;
2852
2856
  }
2853
2857
 
2854
- if (treeOutline) {
2855
- (treeOutline as ElementsTreeOutline).runPendingUpdates();
2856
- treeOutline.focus();
2857
- }
2858
+ this.runPendingUpdates?.();
2859
+ this.focusOutline?.();
2858
2860
 
2859
2861
  // Search for the attribute's position, and then decide where to move to.
2860
- const attributes = this.nodeInternal.attributes();
2862
+ const attributes = this.node.attributes();
2861
2863
  for (let i = 0; i < attributes.length; ++i) {
2862
2864
  if (attributes[i].name !== attributeName) {
2863
2865
  continue;
@@ -2865,12 +2867,12 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2865
2867
 
2866
2868
  if (moveDirection === 'backward') {
2867
2869
  if (i === 0) {
2868
- this.treeElement.startEditingTagName();
2870
+ this.startEditingTagName();
2869
2871
  } else {
2870
2872
  this.triggerEditAttribute(attributes[i - 1].name);
2871
2873
  }
2872
2874
  } else if (i === attributes.length - 1) {
2873
- this.treeElement.addNewAttribute();
2875
+ this.addNewAttribute();
2874
2876
  } else {
2875
2877
  this.triggerEditAttribute(attributes[i + 1].name);
2876
2878
  }
@@ -2890,20 +2892,20 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2890
2892
  }
2891
2893
  } else if (moveDirection === 'forward') {
2892
2894
  if (!Platform.StringUtilities.isWhitespace(newText)) {
2893
- this.treeElement.addNewAttribute();
2895
+ this.addNewAttribute();
2894
2896
  } else {
2895
- this.treeElement.startEditingTagName();
2897
+ this.startEditingTagName();
2896
2898
  }
2897
2899
  }
2898
2900
  }
2899
2901
 
2900
2902
  if (attributeName !== null && (attributeName.trim() || newText.trim()) && oldText !== newText) {
2901
- this.nodeInternal.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
2903
+ this.node.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
2902
2904
  Badges.UserBadges.instance().recordAction(Badges.BadgeAction.DOM_ELEMENT_OR_ATTRIBUTE_EDITED);
2903
2905
  return;
2904
2906
  }
2905
2907
 
2906
- this.treeElement.updateTitle();
2908
+ this.updateTitle();
2907
2909
  moveToNextAttributeIfNeeded.call(this);
2908
2910
  }
2909
2911
 
@@ -2928,21 +2930,21 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2928
2930
  }
2929
2931
 
2930
2932
  function moveToNextAttributeIfNeeded(this: ElementsTreeWidget): void {
2931
- if (this.nodeInternal.nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
2932
- this.treeElement.startEditingProcessingInstructionValue();
2933
+ if (this.node.nodeType() === Node.PROCESSING_INSTRUCTION_NODE) {
2934
+ this.startEditingProcessingInstructionValue();
2933
2935
  return;
2934
2936
  }
2935
2937
 
2936
2938
  if (moveDirection !== 'forward') {
2937
- this.treeElement.addNewAttribute();
2939
+ this.addNewAttribute();
2938
2940
  return;
2939
2941
  }
2940
2942
 
2941
- const attributes = this.nodeInternal.attributes();
2943
+ const attributes = this.node.attributes();
2942
2944
  if (attributes.length > 0) {
2943
2945
  this.triggerEditAttribute(attributes[0].name);
2944
2946
  } else {
2945
- this.treeElement.addNewAttribute();
2947
+ this.addNewAttribute();
2946
2948
  }
2947
2949
  }
2948
2950
 
@@ -2952,24 +2954,21 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2952
2954
  return;
2953
2955
  }
2954
2956
 
2955
- const treeOutline = this.treeElement.treeOutline;
2956
- const wasExpanded = this.treeElement.expanded;
2957
+ const wasExpanded = this.#expanded;
2957
2958
 
2958
- this.nodeInternal.setNodeName(newText, (error, newNode) => {
2959
+ this.node.setNodeName(newText, (error, newNode) => {
2959
2960
  if (error || !newNode) {
2960
2961
  cancel();
2961
2962
  return;
2962
2963
  }
2963
- if (!treeOutline) {
2964
+ if (!this.selectNodeAfterEdit) {
2964
2965
  return;
2965
2966
  }
2966
2967
 
2967
2968
  Badges.UserBadges.instance().recordAction(Badges.BadgeAction.DOM_ELEMENT_OR_ATTRIBUTE_EDITED);
2968
- const newTreeItem =
2969
- (treeOutline as ElementsTreeOutline).selectNodeAfterEdit(wasExpanded, error, newNode) as ElementsTreeElement |
2970
- null;
2971
- if (newTreeItem) {
2972
- moveToNextAttributeIfNeeded.call(newTreeItem.widget);
2969
+ const newWidget = this.selectNodeAfterEdit(wasExpanded, error, newNode);
2970
+ if (newWidget) {
2971
+ moveToNextAttributeIfNeeded.call(newWidget);
2973
2972
  }
2974
2973
  });
2975
2974
  }
@@ -2979,7 +2978,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2979
2978
 
2980
2979
  function callback(this: ElementsTreeWidget): void {
2981
2980
  this.#clearDOMNextUpdate = true;
2982
- this.treeElement.updateTitle();
2981
+ this.updateTitle();
2983
2982
  }
2984
2983
  textNode.setNodeValue(newText, callback.bind(this));
2985
2984
  }
@@ -2989,7 +2988,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2989
2988
 
2990
2989
  // Need to restore attributes structure.
2991
2990
  this.#clearDOMNextUpdate = true;
2992
- this.treeElement.updateTitle();
2991
+ this.updateTitle();
2993
2992
  }
2994
2993
 
2995
2994
  private distinctClosingTagElement(): Element|null {
@@ -2997,9 +2996,8 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
2997
2996
 
2998
2997
  // For an expanded element, it will be the last element with class "close"
2999
2998
  // in the child element list.
3000
- if (this.treeElement.expanded) {
3001
- const closers = this.treeElement.childrenListElement.querySelectorAll('.close');
3002
- return closers[closers.length - 1];
2999
+ if (this.#expanded) {
3000
+ return this.closingTagElement?.() ?? null;
3003
3001
  }
3004
3002
 
3005
3003
  // Remaining cases are single line non-expanded elements with a closing
@@ -3016,21 +3014,16 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3016
3014
  return;
3017
3015
  }
3018
3016
  this.#updateRecord = updateRecord ?? null;
3019
- if (this.nodeInternal.nodeType() === Node.DOCUMENT_FRAGMENT_NODE && this.nodeInternal.isInShadowTree() &&
3020
- this.nodeInternal.shadowRootType()) {
3021
- this.treeElement.childrenListElement.classList.add('shadow-root');
3017
+ if (this.node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE && this.node.isInShadowTree() &&
3018
+ this.node.shadowRootType()) {
3022
3019
  let depth = 4;
3023
- for (let node: (SDK.DOMModel.DOMNode|null) = (this.nodeInternal as SDK.DOMModel.DOMNode | null); depth && node;
3020
+ for (let node: (SDK.DOMModel.DOMNode|null) = (this.node as SDK.DOMModel.DOMNode | null); depth && node;
3024
3021
  node = node.parentNode) {
3025
3022
  if (node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE) {
3026
3023
  depth--;
3027
3024
  }
3028
3025
  }
3029
- if (!depth) {
3030
- this.treeElement.childrenListElement.classList.add('shadow-root-deep');
3031
- } else {
3032
- this.treeElement.childrenListElement.classList.add('shadow-root-depth-' + depth);
3033
- }
3026
+ this.updateShadowRootDepth?.(depth);
3034
3027
  }
3035
3028
  this.performUpdate();
3036
3029
  this.updateDecorations();
@@ -3043,28 +3036,16 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3043
3036
  this.#highlightSearchResults();
3044
3037
  }
3045
3038
 
3046
- private computeLeftIndent(): number {
3047
- let treeElement: (UI.TreeOutline.TreeElement|null) = this.treeElement.parent;
3048
- let depth = 0;
3049
- while (treeElement !== null) {
3050
- depth++;
3051
- treeElement = treeElement.parent;
3052
- }
3053
-
3054
- /** Keep it in sync with elementsTreeOutline.css **/
3055
- return 12 * (depth - 2) + (this.treeElement.isExpandable() && this.treeElement.isCollapsible() ? 1 : 12);
3056
- }
3057
-
3058
3039
  updateDecorations(): void {
3059
3040
  // Important to keep the entire tree node row as a clickable area for that
3060
3041
  // node.
3061
- this.element.style.setProperty('--indent', this.computeLeftIndent() + 'px');
3042
+ this.element.style.setProperty('--indent', (this.computeLeftIndent ? this.computeLeftIndent() : 0) + 'px');
3062
3043
 
3063
- if (this.treeElement.isClosingTag()) {
3044
+ if (this.isClosingTag) {
3064
3045
  return;
3065
3046
  }
3066
3047
 
3067
- if (this.nodeInternal.nodeType() !== Node.ELEMENT_NODE) {
3048
+ if (this.node.nodeType() !== Node.ELEMENT_NODE) {
3068
3049
  return;
3069
3050
  }
3070
3051
 
@@ -3072,19 +3053,11 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3072
3053
  }
3073
3054
 
3074
3055
  #updateDecorations(): Promise<void> {
3075
- if (!this.treeElement.treeOutline) {
3076
- return Promise.resolve();
3077
- }
3078
-
3079
- const node = this.nodeInternal;
3080
-
3081
- const outline = this.treeElement.treeOutline as ElementsTreeOutline;
3082
- if (!outline.decoratorExtensions) {
3083
- outline.decoratorExtensions = getRegisteredDecorators();
3084
- }
3056
+ const node = this.node;
3057
+ const decoratorExtensions = getRegisteredDecorators();
3085
3058
 
3086
3059
  const markerToExtension = new Map<string, MarkerDecoratorRegistration>();
3087
- for (const decoratorExtension of (outline.decoratorExtensions || [])) {
3060
+ for (const decoratorExtension of decoratorExtensions) {
3088
3061
  markerToExtension.set(decoratorExtension.marker, decoratorExtension);
3089
3062
  }
3090
3063
 
@@ -3131,7 +3104,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3131
3104
  for (const decoration of decorations) {
3132
3105
  tooltip.push(decoration.title);
3133
3106
  }
3134
- if (!this.treeElement.expanded && descendantDecorations.length) {
3107
+ if (!this.#expanded && descendantDecorations.length) {
3135
3108
  tooltip.push(i18nString(UIStrings.children));
3136
3109
  for (const decoration of descendantDecorations) {
3137
3110
  tooltip.push(decoration.title);
@@ -3143,22 +3116,18 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3143
3116
  }
3144
3117
 
3145
3118
  async remove(): Promise<void> {
3146
- if (this.treeElement.treeOutline?.isToggledToHidden(this.nodeInternal)) {
3119
+ if (this.isToggledToHidden?.(this.node)) {
3147
3120
  // Unhide the node before removing. This avoids inconsistent state if the node is restored via undo.
3148
- await (this.treeElement.treeOutline as ElementsTreeOutline).toggleHideElement(this.nodeInternal);
3149
- }
3150
- if (this.nodeInternal.pseudoType()) {
3151
- return;
3121
+ await this.toggleHideElement?.(this.node);
3152
3122
  }
3153
- const parentElement = this.treeElement.parent;
3154
- if (!parentElement) {
3123
+ if (this.node.pseudoType()) {
3155
3124
  return;
3156
3125
  }
3157
3126
 
3158
- if (!this.nodeInternal.parentNode || this.nodeInternal.parentNode.nodeType() === Node.DOCUMENT_NODE) {
3127
+ if (!this.node.parentNode || this.node.parentNode.nodeType() === Node.DOCUMENT_NODE) {
3159
3128
  return;
3160
3129
  }
3161
- void this.nodeInternal.removeNode();
3130
+ void this.node.removeNode();
3162
3131
  }
3163
3132
 
3164
3133
  toggleEditAsHTML(callback?: ((arg0: boolean) => void), startEditing?: boolean): void {
@@ -3189,28 +3158,28 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3189
3158
  }
3190
3159
  }
3191
3160
 
3192
- const node = this.nodeInternal;
3161
+ const node = this.node;
3193
3162
  void node.getOuterHTML().then(this.startEditingAsHTML.bind(this, commitChange, disposeCallback));
3194
3163
  }
3195
3164
 
3196
3165
  private copyCSSPath(): void {
3197
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(cssPath(this.nodeInternal, true));
3166
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(cssPath(this.node, true));
3198
3167
  }
3199
3168
 
3200
3169
  private copyJSPath(): void {
3201
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(jsPath(this.nodeInternal, true));
3170
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(jsPath(this.node, true));
3202
3171
  }
3203
3172
 
3204
3173
  private copyXPath(): void {
3205
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(xPath(this.nodeInternal, true));
3174
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(xPath(this.node, true));
3206
3175
  }
3207
3176
 
3208
3177
  private copyFullXPath(): void {
3209
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(xPath(this.nodeInternal, false));
3178
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(xPath(this.node, false));
3210
3179
  }
3211
3180
 
3212
3181
  async copyStyles(): Promise<void> {
3213
- const node = this.nodeInternal;
3182
+ const node = this.node;
3214
3183
  const cssModel = node.domModel().cssModel();
3215
3184
  const cascade = await cssModel.cachedMatchedCascadeForNode(node);
3216
3185
  if (!cascade) {
@@ -3267,7 +3236,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3267
3236
  }
3268
3237
 
3269
3238
  private editAsHTML(): void {
3270
- const promise = Common.Revealer.reveal(this.node());
3239
+ const promise = Common.Revealer.reveal(this.node);
3271
3240
  void promise.then(() => {
3272
3241
  const action = UI.ActionRegistry.ActionRegistry.instance().getAction('elements.edit-as-html');
3273
3242
  return action.execute();
@@ -3280,10 +3249,10 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3280
3249
  }
3281
3250
 
3282
3251
  async #updateAdorners(): Promise<void> {
3283
- if (this.treeElement.isClosingTag()) {
3252
+ if (this.isClosingTag) {
3284
3253
  return;
3285
3254
  }
3286
- const node = this.node();
3255
+ const node = this.node;
3287
3256
  const nodeId = node.id;
3288
3257
  if (node.nodeType() !== Node.COMMENT_NODE && node.nodeType() !== Node.DOCUMENT_FRAGMENT_NODE &&
3289
3258
  node.nodeType() !== Node.TEXT_NODE && nodeId !== undefined) {
@@ -3296,7 +3265,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3296
3265
 
3297
3266
  async #onPopoverAdornerClick(event: Event): Promise<void> {
3298
3267
  event.stopPropagation();
3299
- const node = this.node();
3268
+ const node = this.node;
3300
3269
  const nodeId = node.id;
3301
3270
  if (!nodeId) {
3302
3271
  return;
@@ -3311,7 +3280,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3311
3280
 
3312
3281
  async #onInterestAdornerClick(event: Event): Promise<void> {
3313
3282
  event.stopPropagation();
3314
- const node = this.node();
3283
+ const node = this.node;
3315
3284
  const nodeId = node.id;
3316
3285
  if (!nodeId) {
3317
3286
  return;
@@ -3326,7 +3295,7 @@ export class ElementsTreeWidget extends UI.Widget.Widget {
3326
3295
 
3327
3296
  #onStartingStyleAdornerClick(event: Event): void {
3328
3297
  event.stopPropagation();
3329
- const node = this.node();
3298
+ const node = this.node;
3330
3299
  const nodeId = node.id;
3331
3300
  if (!nodeId) {
3332
3301
  return;
@@ -3345,11 +3314,22 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3345
3314
  widget: ElementsTreeWidget;
3346
3315
  widgetWrapper: HTMLElement;
3347
3316
  nodeInternal: SDK.DOMModel.DOMNode;
3348
- tagTypeContext: TagTypeContext;
3317
+ #isClosingTag: boolean;
3318
+
3319
+ get tagTypeContext(): TagTypeContext {
3320
+ if (this.#isClosingTag) {
3321
+ return {tagType: TagType.CLOSING};
3322
+ }
3323
+ return {
3324
+ tagType: TagType.OPENING,
3325
+ canAddAttributes: this.nodeInternal.nodeType() === Node.ELEMENT_NODE,
3326
+ };
3327
+ }
3349
3328
 
3350
3329
  constructor(node: SDK.DOMModel.DOMNode, isClosingTag?: boolean) {
3351
3330
  super();
3352
3331
  this.nodeInternal = node;
3332
+ this.#isClosingTag = Boolean(isClosingTag);
3353
3333
  this.listItemElement.setAttribute(
3354
3334
  'jslog', `${VisualLogging.treeItem().parent('elementsTreeOutline').track({
3355
3335
  keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Backspace|Delete|Enter|Space|Home|End',
@@ -3358,18 +3338,51 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3358
3338
  click: true,
3359
3339
  })}`);
3360
3340
 
3361
- if (isClosingTag) {
3362
- this.tagTypeContext = {tagType: TagType.CLOSING};
3363
- } else {
3364
- this.tagTypeContext = {
3365
- tagType: TagType.OPENING,
3366
- canAddAttributes: this.nodeInternal.nodeType() === Node.ELEMENT_NODE,
3367
- };
3368
- }
3369
3341
  this.widgetWrapper = document.createElement('div');
3370
3342
  this.widgetWrapper.style.display = 'contents';
3371
3343
  this.title = this.widgetWrapper;
3372
- this.widget = new ElementsTreeWidget(this);
3344
+ this.widget = new ElementsTreeWidget();
3345
+ this.widget.isClosingTag = this.#isClosingTag;
3346
+ this.widget.node = this.nodeInternal;
3347
+ this.widget.childCount = () => this.childCount();
3348
+ this.widget.expand = () => this.expand();
3349
+ this.widget.collapse = () => this.collapse();
3350
+ this.widget.selectTreeElement = (omitFocus, selectedByUser) => {
3351
+ return this.select(omitFocus, selectedByUser);
3352
+ };
3353
+ this.widget.expandRecursively = () => this.expandRecursively();
3354
+ this.widget.collapseChildren = () => this.collapseChildren();
3355
+ this.widget.closingTagElement = () => {
3356
+ const closers = this.childrenListElement.querySelectorAll('.close');
3357
+ return closers[closers.length - 1] ?? null;
3358
+ };
3359
+ this.widget.updateShadowRootDepth = (depth: number) => {
3360
+ this.childrenListElement.classList.add('shadow-root');
3361
+ if (!depth) {
3362
+ this.childrenListElement.classList.add('shadow-root-deep');
3363
+ } else {
3364
+ this.childrenListElement.classList.add('shadow-root-depth-' + depth);
3365
+ }
3366
+ };
3367
+ this.widget.computeLeftIndent = () => {
3368
+ let treeElement: (UI.TreeOutline.TreeElement|null) = this.parent;
3369
+ let depth = 0;
3370
+ while (treeElement !== null) {
3371
+ depth++;
3372
+ treeElement = treeElement.parent;
3373
+ }
3374
+ return 12 * (depth - 2) + (this.isExpandable() && this.isCollapsible() ? 1 : 12);
3375
+ };
3376
+ this.widget.setChildrenListElementVisible = (visible: boolean) => {
3377
+ if (this.childrenListElement) {
3378
+ if (visible) {
3379
+ this.childrenListElement.style.removeProperty('display');
3380
+ } else {
3381
+ this.childrenListElement.style.display = 'none';
3382
+ }
3383
+ }
3384
+ };
3385
+ this.treeOutline = null;
3373
3386
  this.widget.element.classList.remove('vbox', 'flex-auto');
3374
3387
  this.widget.element.style.display = 'contents';
3375
3388
  this.widget.markAsRoot();
@@ -3460,10 +3473,50 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3460
3473
  }
3461
3474
 
3462
3475
  isClosingTag(): boolean {
3463
- return this.tagTypeContext.tagType === TagType.CLOSING;
3476
+ return this.#isClosingTag;
3477
+ }
3478
+
3479
+ #syncOutlineProperties(): void {
3480
+ const outline = this.treeOutline as ElementsTreeOutline | null;
3481
+ if (outline) {
3482
+ this.widget.isXMLMimeType = Boolean(outline.isXMLMimeType);
3483
+ this.widget.disableEdits = Boolean(outline.disableEdits);
3484
+ this.widget.showAIButton = Boolean(outline.showAIButton);
3485
+ this.widget.expanded = this.expanded;
3486
+ this.widget.isExpandable = this.isExpandable();
3487
+ this.widget.selected = this.selected;
3488
+ this.widget.isDOMNodeSelected = outline.selectedDOMNode() === this.nodeInternal;
3489
+ this.widget.selectDOMNode = (node, selectedByUser) => {
3490
+ outline.suppressRevealAndSelect = true;
3491
+ outline.selectDOMNode(node, selectedByUser);
3492
+ outline.suppressRevealAndSelect = false;
3493
+ };
3494
+ this.widget.findStartTagWidget = () => {
3495
+ return (outline.findTreeElement(this.nodeInternal) as ElementsTreeElement | null)?.widget ?? null;
3496
+ };
3497
+ this.widget.revealInTopLayer = node => outline.revealInTopLayer(node);
3498
+ this.widget.showContextMenu = event => void outline.showContextMenu(this, event);
3499
+ this.widget.populateTreeElement = async () => await outline.populateTreeElement(this);
3500
+ this.widget.updateNodeElementToIssue = (el, issues) => outline.updateNodeElementToIssue(el, issues);
3501
+ this.widget.performCopyOrCut = (isCut, node, isElement) => outline.performCopyOrCut(isCut, node, isElement);
3502
+ this.widget.duplicateNode = node => outline.duplicateNode(node);
3503
+ this.widget.pasteNode = node => outline.pasteNode(node);
3504
+ this.widget.canPaste = node => outline.canPaste(node);
3505
+ this.widget.toggleHideElement = node => outline.toggleHideElement(node);
3506
+ this.widget.isToggledToHidden = node => outline.isToggledToHidden(node);
3507
+ this.widget.selectNodeAfterEdit = (wasExpanded, error, newNode) => {
3508
+ const newTreeItem = outline.selectNodeAfterEdit(wasExpanded, error, newNode);
3509
+ return newTreeItem?.widget ?? null;
3510
+ };
3511
+ this.widget.runPendingUpdates = () => outline.runPendingUpdates();
3512
+ this.widget.focusOutline = () => outline.focus();
3513
+ this.widget.setMultilineEditing = multilineEditing => outline.setMultilineEditing(multilineEditing);
3514
+ this.widget.visibleWidth = () => outline.visibleWidth();
3515
+ }
3464
3516
  }
3465
3517
 
3466
3518
  override onattach(): void {
3519
+ this.#syncOutlineProperties();
3467
3520
  this.widget.onattach();
3468
3521
  }
3469
3522
 
@@ -3477,10 +3530,14 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3477
3530
  }
3478
3531
 
3479
3532
  override onexpand(): void {
3533
+ this.widget.expanded = true;
3534
+ this.widget.isExpandable = this.isExpandable();
3480
3535
  this.widget.onexpand();
3481
3536
  }
3482
3537
 
3483
3538
  override oncollapse(): void {
3539
+ this.widget.expanded = false;
3540
+ this.widget.isExpandable = this.isExpandable();
3484
3541
  this.widget.oncollapse();
3485
3542
  }
3486
3543
 
@@ -3492,14 +3549,28 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3492
3549
  }
3493
3550
 
3494
3551
  override onselect(selectedByUser?: boolean): boolean {
3552
+ this.widget.selected = true;
3553
+ this.#syncOutlineProperties();
3495
3554
  return this.widget.onselect(selectedByUser);
3496
3555
  }
3497
3556
 
3557
+ override deselect(): void {
3558
+ super.deselect();
3559
+ this.widget.selected = false;
3560
+ this.#syncOutlineProperties();
3561
+ }
3562
+
3498
3563
  override ondelete(): boolean {
3499
- return this.widget.ondelete();
3564
+ if (!this.treeOutline) {
3565
+ return false;
3566
+ }
3567
+ const startTagTreeElement = (this.treeOutline as ElementsTreeOutline).findTreeElement(this.nodeInternal);
3568
+ startTagTreeElement ? (void (startTagTreeElement as ElementsTreeElement).remove()) : (void this.remove());
3569
+ return true;
3500
3570
  }
3501
3571
 
3502
3572
  override onenter(): boolean {
3573
+ this.#syncOutlineProperties();
3503
3574
  return this.widget.onenter();
3504
3575
  }
3505
3576
 
@@ -3517,19 +3588,28 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3517
3588
  }
3518
3589
 
3519
3590
  override ondblclick(event: Event): boolean {
3591
+ this.#syncOutlineProperties();
3520
3592
  return this.widget.ondblclick(event);
3521
3593
  }
3522
3594
 
3523
3595
  override onbind(): void {
3596
+ const outline = this.treeOutline as ElementsTreeOutline | null;
3597
+ if (outline && !this.isClosingTag()) {
3598
+ outline.treeElementByNode.set(this.nodeInternal, this);
3599
+ }
3524
3600
  this.widget.onbind();
3525
3601
  }
3526
3602
 
3527
3603
  override onunbind(): void {
3604
+ const outline = this.treeOutline as ElementsTreeOutline | null;
3605
+ if (outline && outline.treeElementByNode.get(this.nodeInternal) === this) {
3606
+ outline.treeElementByNode.delete(this.nodeInternal);
3607
+ }
3528
3608
  this.widget.onunbind();
3529
3609
  }
3530
3610
 
3531
3611
  static animateOnDOMUpdate(treeElement: ElementsTreeElement): void {
3532
- ElementsTreeWidget.animateOnDOMUpdate(treeElement);
3612
+ treeElement.widget.animateOnDOMUpdate();
3533
3613
  }
3534
3614
 
3535
3615
  static visibleShadowRoots(node: SDK.DOMModel.DOMNode): SDK.DOMModel.DOMNode[] {
@@ -3556,6 +3636,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3556
3636
  }
3557
3637
 
3558
3638
  updateAdorners(): void {
3639
+ this.#syncOutlineProperties();
3559
3640
  this.widget.updateAdorners();
3560
3641
  }
3561
3642
 
@@ -3564,9 +3645,11 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3564
3645
  }
3565
3646
 
3566
3647
  requestUpdate(): void {
3648
+ this.#syncOutlineProperties();
3567
3649
  this.widget.requestUpdate();
3568
3650
  }
3569
3651
  updateTitle(updateRecord?: Elements.ElementUpdateRecord.ElementUpdateRecord|null): void {
3652
+ this.#syncOutlineProperties();
3570
3653
  this.widget.updateTitle(updateRecord);
3571
3654
  }
3572
3655