chrome-devtools-frontend 1.0.1721762 → 1.0.1726686

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 (273) hide show
  1. package/.agents/skills/review-ui-widgets/SKILL.md +7 -7
  2. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +12 -0
  3. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +3 -3
  4. package/.agents/skills/ui-widgets/SKILL.md +2 -1
  5. package/docs/cookbook/dependencies.md +57 -11
  6. package/docs/get_the_code.md +15 -0
  7. package/front_end/core/i18n/collect-ui-strings.js +58 -12
  8. package/front_end/core/i18n/i18nImpl.ts +1 -1
  9. package/front_end/core/root/Runtime.ts +1 -1
  10. package/front_end/core/sdk/ResourceTreeModel.ts +16 -0
  11. package/front_end/core/sdk/WebAuthnModel.ts +17 -10
  12. package/front_end/entrypoints/js_app/js_app.ts +2 -5
  13. package/front_end/entrypoints/node_app/node_app.ts +2 -3
  14. package/front_end/generated/InspectorBackendCommands.ts +3 -3
  15. package/front_end/generated/protocol.ts +17 -0
  16. package/front_end/models/ai_assistance/skills/lighthouse.md +2 -1
  17. package/front_end/models/ai_assistance/skills/network.md +1 -0
  18. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +26 -2
  19. package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +1 -1
  20. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -7
  21. package/front_end/models/ai_assistance/tools/RunLighthouse.ts +2 -2
  22. package/front_end/models/comment_manager/CD4ABridge.ts +4 -0
  23. package/front_end/models/comment_manager/CommentManager.ts +0 -6
  24. package/front_end/models/comment_manager/CommentThread.ts +39 -19
  25. package/front_end/models/elements/StyleChanges.ts +66 -0
  26. package/front_end/models/trace/EventsSerializer.ts +2 -7
  27. package/front_end/models/trace/ModelImpl.ts +0 -2
  28. package/front_end/models/trace/handlers/FlowsHandler.ts +37 -29
  29. package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +13 -6
  30. package/front_end/models/trace/helpers/SyntheticEvents.ts +10 -37
  31. package/front_end/models/trace/insights/RenderBlocking.ts +3 -1
  32. package/front_end/models/trace/lantern/simulation/Simulator.ts +4 -0
  33. package/front_end/models/trace/lantern/types/Lantern.ts +1 -0
  34. package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +92 -0
  35. package/front_end/panels/accessibility/SourceOrderView.ts +1 -1
  36. package/front_end/panels/accessibility/accessibilityAnnouncementRecordingListView.css +3 -1
  37. package/front_end/panels/accessibility/accessibilityAnnouncementRecordingView.css +12 -1
  38. package/front_end/panels/application/ApplicationPanelSidebar.ts +90 -0
  39. package/front_end/panels/application/StorageView.ts +348 -254
  40. package/front_end/panels/application/SubAppsView.ts +159 -0
  41. package/front_end/panels/application/application.ts +2 -0
  42. package/front_end/panels/application/preloading/PreloadingView.ts +360 -336
  43. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +3 -3
  44. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +6 -3
  45. package/front_end/panels/application/preloading/components/RuleSetGrid.ts +17 -17
  46. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -2
  47. package/front_end/panels/application/preloading/preloadingView.css +12 -4
  48. package/front_end/panels/application/preloading/preloadingViewDropDown.css +1 -1
  49. package/front_end/panels/application/storageView.css +16 -21
  50. package/front_end/panels/application/subAppsView.css +21 -0
  51. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +2 -2
  52. package/front_end/panels/browser_debugger/browser_debugger-meta.ts +6 -8
  53. package/front_end/panels/comments/CommentsPane.ts +26 -9
  54. package/front_end/panels/comments/commentsPane.css +25 -6
  55. package/front_end/panels/common/CommentThreadWidget.ts +2 -2
  56. package/front_end/panels/common/CommentsOverlayWidget.ts +94 -35
  57. package/front_end/panels/common/commentThreadWidget.css +17 -0
  58. package/front_end/panels/common/commentsOverlay.css +5 -10
  59. package/front_end/panels/common/common-meta.ts +11 -1
  60. package/front_end/panels/elements/ClassesPaneWidget.ts +133 -89
  61. package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +7 -33
  62. package/front_end/panels/elements/DOMTreeElementWidget.ts +3 -1
  63. package/front_end/panels/elements/DOMTreeWidget.ts +19 -3
  64. package/front_end/panels/elements/ElementStatePaneWidget.ts +11 -1
  65. package/front_end/panels/elements/PropertyRenderer.ts +3 -2
  66. package/front_end/panels/elements/StyleEditorWidget.ts +87 -39
  67. package/front_end/panels/elements/StylePropertiesSection.ts +32 -5
  68. package/front_end/panels/elements/StylePropertyTreeElement.ts +227 -162
  69. package/front_end/panels/elements/StylesSidebarPane.ts +1 -0
  70. package/front_end/panels/event_listeners/EventListenersView.ts +11 -8
  71. package/front_end/panels/layer_viewer/Layers3DView.ts +21 -37
  72. package/front_end/panels/linear_memory_inspector/components/ValueInterpreterSettings.ts +1 -1
  73. package/front_end/panels/network/NetworkConfigView.ts +12 -10
  74. package/front_end/panels/network/NetworkDataGridNode.ts +3 -1
  75. package/front_end/panels/network/RequestConditionsDrawer.ts +1 -1
  76. package/front_end/panels/network/RequestPayloadView.ts +12 -5
  77. package/front_end/panels/network/networkConfigView.css +8 -8
  78. package/front_end/panels/profiler/HeapProfileView.ts +28 -6
  79. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +7 -3
  80. package/front_end/panels/protocol_monitor/JSONEditor.ts +0 -1
  81. package/front_end/panels/recorder/RecorderPanel.ts +2 -2
  82. package/front_end/panels/screencast/ScreencastView.ts +3 -6
  83. package/front_end/panels/security/SecurityPanelSidebar.ts +0 -31
  84. package/front_end/panels/settings/SettingsScreen.ts +1 -1
  85. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +9 -16
  86. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +358 -345
  87. package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +136 -121
  88. package/front_end/panels/sources/NavigatorView.ts +105 -45
  89. package/front_end/panels/sources/ScopeChainSidebarPane.ts +8 -5
  90. package/front_end/panels/sources/SourcesNavigator.ts +421 -213
  91. package/front_end/panels/sources/SourcesPanel.ts +9 -5
  92. package/front_end/panels/sources/TabbedEditorContainer.ts +41 -18
  93. package/front_end/panels/sources/UISourceCodeFrame.ts +1 -1
  94. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +10 -5
  95. package/front_end/panels/sources/sources-meta.ts +4 -15
  96. package/front_end/panels/sources/sourcesNavigator.css +5 -0
  97. package/front_end/panels/timeline/ModificationsManager.ts +0 -2
  98. package/front_end/panels/timeline/README.md +2 -0
  99. package/front_end/panels/timeline/TimelineCommentContext.ts +171 -0
  100. package/front_end/panels/timeline/TimelineCommentController.ts +168 -30
  101. package/front_end/panels/timeline/TimelinePanel.ts +4 -0
  102. package/front_end/panels/timeline/components/IgnoreListSetting.ts +1 -1
  103. package/front_end/panels/timeline/timeline.ts +2 -0
  104. package/front_end/panels/timeline/utils/Treemap.ts +8 -0
  105. package/front_end/panels/webauthn/WebauthnPane.ts +15 -13
  106. package/front_end/third_party/chromium/README.chromium +1 -1
  107. package/front_end/third_party/puppeteer/README.chromium +2 -2
  108. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +113 -3
  109. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21311 -20981
  110. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +36 -0
  111. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js +22 -0
  113. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +20 -18
  116. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts +20 -1
  118. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +2 -2
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +40 -1
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js +3 -1
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts +2 -0
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js +41 -5
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js.map +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts +2 -1
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js +23 -2
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js.map +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts +3 -2
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +13 -1
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts +1 -0
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js +18 -11
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js.map +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts +2 -1
  143. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js +8 -1
  145. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js.map +1 -1
  146. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +2 -1
  147. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +24 -12
  149. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +13 -7
  153. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.d.ts.map +1 -1
  155. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js +5 -1
  156. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js.map +1 -1
  157. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts +22 -1
  158. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  159. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js +75 -9
  160. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js.map +1 -1
  161. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts +18 -4
  162. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js +8 -4
  164. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  165. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +65 -26
  167. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
  168. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +3 -2
  169. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
  170. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +19 -0
  171. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
  172. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.d.ts.map +1 -1
  173. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js +4 -3
  174. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js.map +1 -1
  175. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts +1 -0
  176. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts.map +1 -1
  177. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js +4 -0
  178. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js.map +1 -1
  179. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts +2 -0
  180. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts.map +1 -1
  181. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js +95 -8
  182. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js.map +1 -1
  183. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts +0 -8
  184. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
  185. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +8 -24
  186. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
  187. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts +1 -0
  188. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts.map +1 -1
  189. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js +5 -4
  190. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js.map +1 -1
  191. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +9 -0
  192. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  193. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.d.ts.map +1 -1
  194. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js +10 -0
  195. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js.map +1 -1
  196. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +10 -0
  197. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
  198. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +30 -5
  199. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
  200. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
  201. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
  202. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
  203. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
  204. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts +2 -0
  205. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts.map +1 -1
  206. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js +33 -3
  207. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js.map +1 -1
  208. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  209. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +1 -2
  210. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
  211. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts +4 -0
  212. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts.map +1 -1
  213. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +1 -0
  214. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
  215. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  216. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  217. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js.map +1 -1
  218. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts +2 -2
  219. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts.map +1 -1
  220. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  221. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  222. package/front_end/third_party/puppeteer/package/lib/types.d.ts +113 -3
  223. package/front_end/third_party/puppeteer/package/package.json +4 -4
  224. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +42 -0
  225. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +25 -22
  226. package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +22 -2
  227. package/front_end/third_party/puppeteer/package/src/api/Page.ts +45 -2
  228. package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +79 -32
  229. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +32 -12
  230. package/front_end/third_party/puppeteer/package/src/bidi/Input.ts +1 -1
  231. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +18 -2
  232. package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +21 -13
  233. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +12 -2
  234. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +37 -16
  235. package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +14 -11
  236. package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +7 -1
  237. package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +101 -14
  238. package/front_end/third_party/puppeteer/package/src/cdp/NetworkEventManager.ts +26 -6
  239. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +111 -29
  240. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +37 -1
  241. package/front_end/third_party/puppeteer/package/src/cdp/ScreenRecording.ts +5 -4
  242. package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +5 -0
  243. package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +122 -7
  244. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +13 -33
  245. package/front_end/third_party/puppeteer/package/src/common/BrowserWebSocketTransport.ts +10 -5
  246. package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +10 -0
  247. package/front_end/third_party/puppeteer/package/src/common/WaitTask.ts +12 -0
  248. package/front_end/third_party/puppeteer/package/src/common/util.ts +39 -5
  249. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  250. package/front_end/third_party/puppeteer/package/src/injected/Poller.ts +35 -3
  251. package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +4 -2
  252. package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +5 -0
  253. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  254. package/front_end/third_party/puppeteer/package/src/util/encoding.ts +2 -2
  255. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  256. package/front_end/ui/comments/CommentAnchorResolver.ts +3 -0
  257. package/front_end/ui/comments/CommentOverlayManager.ts +2 -4
  258. package/front_end/ui/components/lists/List.ts +14 -1
  259. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +1 -1
  260. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +23 -14
  261. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +3 -0
  262. package/front_end/ui/helpers/OpenInNewTab.ts +8 -0
  263. package/front_end/ui/legacy/LinkContextMenuProvider.ts +1 -1
  264. package/front_end/ui/legacy/ListWidget.ts +14 -18
  265. package/front_end/ui/legacy/TabbedPane.ts +46 -3
  266. package/front_end/ui/legacy/Toolbar.ts +0 -1
  267. package/front_end/ui/legacy/Treeoutline.ts +10 -3
  268. package/front_end/ui/legacy/UIUtils.ts +5 -2
  269. package/front_end/ui/legacy/components/inline_editor/Swatches.ts +19 -6
  270. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +20 -11
  271. package/front_end/ui/legacy/components/source_frame/XMLView.ts +27 -7
  272. package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
  273. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  // Copyright 2015 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- /* eslint-disable @devtools/no-imperative-dom-api */
5
4
 
6
5
  import * as Common from '../../core/common/common.js';
7
6
  import * as i18n from '../../core/i18n/i18n.js';
8
7
  import * as Platform from '../../core/platform/platform.js';
9
8
  import * as SDK from '../../core/sdk/sdk.js';
10
9
  import * as UI from '../../ui/legacy/legacy.js';
10
+ import {Directives, html, render} from '../../ui/lit/lit.js';
11
11
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
12
12
 
13
13
  import classesPaneWidgetStyles from './classesPaneWidget.css.js';
@@ -37,72 +37,114 @@ const UIStrings = {
37
37
  } as const;
38
38
  const str_ = i18n.i18n.registerUIStrings('panels/elements/ClassesPaneWidget.ts', UIStrings);
39
39
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
40
+
41
+ const {ref, repeat} = Directives;
42
+
43
+ export interface ClassItem {
44
+ className: string;
45
+ enabled: boolean;
46
+ }
47
+
48
+ export interface ViewInput {
49
+ classes: ClassItem[];
50
+ onCommit: () => void;
51
+ /** Returns whether the prompt had text to discard, in which case the key event is fully consumed. */
52
+ onCancel: () => boolean;
53
+ onClick: (className: string, enabled: boolean) => void;
54
+ }
55
+
56
+ export interface ViewOutput {
57
+ attachPrompt?: (prompt: UI.TextPrompt.TextPrompt) => void;
58
+ }
59
+
60
+ export type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
61
+
62
+ export const DEFAULT_VIEW: View = (input, output, target) => {
63
+ const onKeyDown = (event: KeyboardEvent): void => {
64
+ if (event.key === Platform.KeyboardUtilities.ENTER_KEY && !event.isComposing) {
65
+ event.consume();
66
+ input.onCommit();
67
+ } else if (Platform.KeyboardUtilities.isEscKey(event) && input.onCancel()) {
68
+ // Escape discarded non-empty prompt text, so stop it here instead of letting
69
+ // it reach global DevTools shortcuts (e.g. closing the drawer).
70
+ event.consume(true);
71
+ }
72
+ };
73
+ // clang-format off
74
+ render(html`
75
+ <style>${classesPaneWidgetStyles}</style>
76
+ <div class="styles-element-classes-pane">
77
+ <div class="title-container" @keydown=${onKeyDown}>
78
+ <div class="new-class-input monospace" autofocus ${ref(element => {
79
+ output.attachPrompt = element instanceof HTMLElement ? prompt => prompt.attach(element) : undefined;
80
+ })}></div>
81
+ </div>
82
+ <div class="source-code styles-element-classes-container">
83
+ ${repeat(input.classes, item => item.className, item => html`
84
+ <devtools-checkbox
85
+ class="monospace"
86
+ small
87
+ .checked=${item.enabled}
88
+ title=${item.className}
89
+ jslog=${VisualLogging.toggle('element-class').track({change: true})}
90
+ @click=${(event: Event) => input.onClick(item.className, (event.target as UI.UIUtils.CheckboxLabel).checked)}>${item.className}</devtools-checkbox>`)}
91
+ </div>
92
+ </div>`, target);
93
+ // clang-format on
94
+ };
95
+
40
96
  export class ClassesPaneWidget extends UI.Widget.Widget {
41
- private input: HTMLElement;
42
- private readonly classesContainer: HTMLElement;
43
- private readonly prompt: ClassNamePrompt;
44
- private readonly mutatingNodes: Set<SDK.DOMModel.DOMNode>;
45
- private readonly pendingNodeClasses: Map<SDK.DOMModel.DOMNode, string>;
46
- private readonly updateNodeThrottler: Common.Throttler.Throttler;
47
- private previousTarget: SDK.DOMModel.DOMNode|null;
48
-
49
- constructor() {
50
- super({
97
+ readonly #view: View;
98
+ readonly #prompt: ClassNamePrompt;
99
+ #promptAttached = false;
100
+ readonly #mutatingNodes: Set<SDK.DOMModel.DOMNode>;
101
+ readonly #pendingNodeClasses: Map<SDK.DOMModel.DOMNode, string>;
102
+ readonly #updateNodeThrottler: Common.Throttler.Throttler;
103
+ #previousTarget: SDK.DOMModel.DOMNode|null;
104
+
105
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
106
+ super(element, {
51
107
  jslog: `${VisualLogging.pane('elements-classes')}`,
52
108
  useShadowDom: true,
53
109
  });
54
- this.registerRequiredCSS(classesPaneWidgetStyles);
55
- this.contentElement.className = 'styles-element-classes-pane';
56
- const container = this.contentElement.createChild('div', 'title-container');
57
- this.input = container.createChild('div', 'new-class-input monospace');
58
- this.setDefaultFocusedElement(this.input);
59
- this.classesContainer = this.contentElement.createChild('div', 'source-code');
60
- this.classesContainer.classList.add('styles-element-classes-container');
61
- this.prompt = new ClassNamePrompt(this.nodeClasses.bind(this));
62
- this.prompt.setAutocompletionTimeout(0);
63
- this.prompt.renderAsBlock();
64
-
65
- const proxyElement = (this.prompt.attach(this.input) as HTMLElement);
66
- this.prompt.setPlaceholder(i18nString(UIStrings.addNewClass));
67
- this.prompt.addEventListener(UI.TextPrompt.Events.TEXT_CHANGED, this.onTextChanged, this);
68
- proxyElement.addEventListener('keydown', this.onKeyDown.bind(this), false);
110
+ this.#view = view;
111
+ this.#prompt = new ClassNamePrompt(this.nodeClasses.bind(this));
112
+ this.#prompt.setAutocompletionTimeout(0);
113
+ this.#prompt.renderAsBlock();
114
+
115
+ this.#prompt.addEventListener(UI.TextPrompt.Events.TEXT_CHANGED, this.onTextChanged, this);
69
116
 
70
117
  SDK.TargetManager.TargetManager.instance().addModelListener(
71
118
  SDK.DOMModel.DOMModel, SDK.DOMModel.Events.DOMMutated, this.onDOMMutated, this, {scoped: true});
72
- this.mutatingNodes = new Set();
73
- this.pendingNodeClasses = new Map();
74
- this.updateNodeThrottler = new Common.Throttler.Throttler(0);
75
- this.previousTarget = null;
119
+ this.#mutatingNodes = new Set();
120
+ this.#pendingNodeClasses = new Map();
121
+ this.#updateNodeThrottler = new Common.Throttler.Throttler(0);
122
+ this.#previousTarget = null;
76
123
  UI.Context.Context.instance().addFlavorChangeListener(SDK.DOMModel.DOMNode, this.onSelectedNodeChanged, this);
77
124
  }
78
125
 
79
126
  private splitTextIntoClasses(text: string): string[] {
80
- return text.split(/[,\s]/).map(className => className.trim()).filter(className => className.length);
127
+ return text.split(/[,\s]/)
128
+ .map(className => className.trim().replace(/^\./, ''))
129
+ .filter(className => className.length);
81
130
  }
82
131
 
83
- private onKeyDown(event: KeyboardEvent): void {
84
- if (!(event.key === 'Enter') && !Platform.KeyboardUtilities.isEscKey(event)) {
132
+ private onCommit(): void {
133
+ if (this.#prompt.acceptAutoComplete()) {
85
134
  return;
86
135
  }
136
+ this.applyPromptText(this.#prompt.text());
137
+ }
87
138
 
88
- if (event.key === 'Enter') {
89
- event.consume();
90
- if (this.prompt.acceptAutoComplete()) {
91
- return;
92
- }
93
- }
94
-
95
- const eventTarget = (event.target as HTMLElement);
96
- let text = eventTarget.textContent;
97
- if (Platform.KeyboardUtilities.isEscKey(event)) {
98
- if (!Platform.StringUtilities.isWhitespace(text)) {
99
- event.consume(true);
100
- }
101
- text = '';
102
- }
139
+ /** Discards the prompt text and returns whether there was any non-whitespace text to discard. */
140
+ private onCancel(): boolean {
141
+ const hadText = !Platform.StringUtilities.isWhitespace(this.#prompt.text());
142
+ this.applyPromptText('');
143
+ return hadText;
144
+ }
103
145
 
104
- this.prompt.clearAutocomplete();
105
- eventTarget.textContent = '';
146
+ private applyPromptText(text: string): void {
147
+ this.#prompt.setText('');
106
148
 
107
149
  const node = UI.Context.Context.instance().flavor(SDK.DOMModel.DOMNode);
108
150
  if (!node) {
@@ -126,7 +168,7 @@ export class ClassesPaneWidget extends UI.Widget.Widget {
126
168
  UI.ARIAUtils.LiveAnnouncer.alert(announcementString);
127
169
 
128
170
  this.installNodeClasses(node);
129
- this.update();
171
+ this.requestUpdate();
130
172
  }
131
173
 
132
174
  private onTextChanged(): void {
@@ -139,65 +181,67 @@ export class ClassesPaneWidget extends UI.Widget.Widget {
139
181
 
140
182
  private onDOMMutated(event: Common.EventTarget.EventTargetEvent<SDK.DOMModel.DOMNode>): void {
141
183
  const node = event.data;
142
- if (this.mutatingNodes.has(node)) {
184
+ if (this.#mutatingNodes.has(node)) {
143
185
  return;
144
186
  }
145
187
  cachedClassesMap.delete(node);
146
- this.update();
188
+ this.requestUpdate();
147
189
  }
148
190
 
149
191
  private onSelectedNodeChanged(event: Common.EventTarget.EventTargetEvent<SDK.DOMModel.DOMNode|null>): void {
150
- if (this.previousTarget && this.prompt.text()) {
151
- this.input.textContent = '';
152
- this.installNodeClasses(this.previousTarget);
192
+ if (this.#previousTarget && this.#promptAttached && this.#prompt.text()) {
193
+ this.#prompt.setText('');
194
+ this.installNodeClasses(this.#previousTarget);
153
195
  }
154
- this.previousTarget = event.data;
155
- this.update();
196
+ this.#previousTarget = event.data;
197
+ this.requestUpdate();
156
198
  }
157
199
 
158
200
  override wasShown(): void {
159
201
  super.wasShown();
160
- this.update();
202
+ // Render synchronously rather than via requestUpdate(): callers such as
203
+ // StylesSidebarPane.showToolbarPane() focus the widget right after show(),
204
+ // so the autofocus prompt must already exist. This also re-reads the
205
+ // selected node, which may have changed while the pane was hidden.
206
+ this.performUpdate();
161
207
  }
162
208
 
163
- update(): void {
164
- if (!this.isShowing()) {
165
- return;
166
- }
167
-
209
+ override performUpdate(): void {
168
210
  let node = UI.Context.Context.instance().flavor(SDK.DOMModel.DOMNode);
169
211
  if (node) {
170
212
  node = node.enclosingElementOrSelf();
171
213
  }
172
214
 
173
- this.classesContainer.removeChildren();
174
- // @ts-expect-error this.input is a div, not an input element. So this line makes no sense at all
175
- this.input.disabled = !node;
176
-
177
- if (!node) {
178
- return;
179
- }
180
-
181
- const classes = this.nodeClasses(node);
215
+ const classes = node ? this.nodeClasses(node) : new Map<string, boolean>();
182
216
  const keys = [...classes.keys()];
183
217
  keys.sort(Platform.StringUtilities.caseInsensetiveComparator);
184
- for (const className of keys) {
185
- const checkbox =
186
- UI.UIUtils.CheckboxLabel.createWithStringLiteral(className, classes.get(className), 'element-class', true);
187
- checkbox.classList.add('monospace');
188
- checkbox.addEventListener('click', this.onClick.bind(this, className), false);
189
- this.classesContainer.appendChild(checkbox);
218
+ const input: ViewInput = {
219
+ classes: keys.map(className => ({className, enabled: Boolean(classes.get(className))})),
220
+ onCommit: this.onCommit.bind(this),
221
+ onCancel: this.onCancel.bind(this),
222
+ onClick: this.onClick.bind(this),
223
+ };
224
+ const output: ViewOutput = {};
225
+ this.#view(input, output, this.contentElement);
226
+ if (output.attachPrompt && !this.#promptAttached) {
227
+ output.attachPrompt(this.#prompt);
228
+ this.#prompt.setPlaceholder(i18nString(UIStrings.addNewClass));
229
+ this.#promptAttached = true;
230
+ }
231
+ if (this.#promptAttached) {
232
+ // Classes can only be added to a selected node.
233
+ this.#prompt.setEnabled(Boolean(node));
190
234
  }
191
235
  }
192
236
 
193
- private onClick(className: string, event: Event): void {
237
+ private onClick(className: string, enabled: boolean): void {
194
238
  const node = UI.Context.Context.instance().flavor(SDK.DOMModel.DOMNode);
195
239
  if (!node) {
196
240
  return;
197
241
  }
198
- const enabled = (event.target as HTMLInputElement).checked;
199
242
  this.toggleClass(node, className, enabled);
200
243
  this.installNodeClasses(node);
244
+ this.requestUpdate();
201
245
  }
202
246
 
203
247
  private nodeClasses(node: SDK.DOMModel.DOMNode): Map<string, boolean> {
@@ -233,30 +277,30 @@ export class ClassesPaneWidget extends UI.Widget.Widget {
233
277
  }
234
278
  }
235
279
 
236
- const additionalClasses = this.splitTextIntoClasses(this.prompt.textWithCurrentSuggestion());
280
+ const additionalClasses = this.splitTextIntoClasses(this.#prompt.textWithCurrentSuggestion());
237
281
  for (const className of additionalClasses) {
238
282
  activeClasses.add(className);
239
283
  }
240
284
 
241
285
  const newClasses = [...activeClasses.values()].sort();
242
286
 
243
- this.pendingNodeClasses.set(node, newClasses.join(' '));
244
- void this.updateNodeThrottler.schedule(this.flushPendingClasses.bind(this));
287
+ this.#pendingNodeClasses.set(node, newClasses.join(' '));
288
+ void this.#updateNodeThrottler.schedule(this.flushPendingClasses.bind(this));
245
289
  }
246
290
 
247
291
  private async flushPendingClasses(): Promise<void> {
248
292
  const promises = [];
249
- for (const node of this.pendingNodeClasses.keys()) {
250
- this.mutatingNodes.add(node);
251
- const promise = node.setAttributeValuePromise('class', (this.pendingNodeClasses.get(node) as string))
293
+ for (const node of this.#pendingNodeClasses.keys()) {
294
+ this.#mutatingNodes.add(node);
295
+ const promise = node.setAttributeValuePromise('class', (this.#pendingNodeClasses.get(node) as string))
252
296
  .then(onClassValueUpdated.bind(this, node));
253
297
  promises.push(promise);
254
298
  }
255
- this.pendingNodeClasses.clear();
299
+ this.#pendingNodeClasses.clear();
256
300
  await Promise.all(promises);
257
301
 
258
302
  function onClassValueUpdated(this: ClassesPaneWidget, node: SDK.DOMModel.DOMNode): void {
259
- this.mutatingNodes.delete(node);
303
+ this.#mutatingNodes.delete(node);
260
304
  }
261
305
  }
262
306
  }
@@ -21,11 +21,6 @@ const UIStrings = {
21
21
  * allows the user to edit cubic-bezier CSS properties directly.
22
22
  */
23
23
  openCubicBezierEditor: 'Open cubic bezier editor',
24
- /**
25
- * @description Tooltip text for an icon that opens the shadow editor. The shadow editor is a tool
26
- * which allows the user to edit CSS shadow properties.
27
- */
28
- openShadowEditor: 'Open shadow editor',
29
24
  } as const;
30
25
  const str_ = i18n.i18n.registerUIStrings('panels/elements/ColorSwatchPopoverIcon.ts', UIStrings);
31
26
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -321,56 +316,35 @@ export interface ShadowEventTypes {
321
316
  export class ShadowSwatchPopoverHelper extends Common.ObjectWrapper.ObjectWrapper<ShadowEventTypes> {
322
317
  private treeElement: StylePropertyTreeElement;
323
318
  private readonly swatchPopoverHelper: InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper;
324
- private readonly shadowSwatch: InlineEditor.Swatches.CSSShadowSwatch;
325
- private iconElement: HTMLSpanElement;
326
319
  private readonly boundShadowChanged:
327
320
  (event: Common.EventTarget.EventTargetEvent<InlineEditor.CSSShadowEditor.CSSShadowModel>) => void;
328
321
  private readonly boundOnScroll: (event: Event) => void;
329
322
  private cssShadowEditor?: InlineEditor.CSSShadowEditor.CSSShadowEditor;
330
323
  private scrollerElement?: Element;
331
324
  private originalPropertyText?: string|null;
332
- constructor(
333
- treeElement: StylePropertyTreeElement, swatchPopoverHelper: InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper,
334
- shadowSwatch: InlineEditor.Swatches.CSSShadowSwatch) {
325
+ constructor(treeElement: StylePropertyTreeElement,
326
+ swatchPopoverHelper: InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper) {
335
327
  super();
336
328
  this.treeElement = treeElement;
337
329
  this.swatchPopoverHelper = swatchPopoverHelper;
338
- this.shadowSwatch = shadowSwatch;
339
- this.iconElement = shadowSwatch.iconElement();
340
-
341
- UI.Tooltip.Tooltip.install(this.iconElement, i18nString(UIStrings.openShadowEditor));
342
- this.iconElement.addEventListener('click', this.iconClick.bind(this), false);
343
- this.iconElement.addEventListener('keydown', this.keyDown.bind(this), false);
344
- this.iconElement.addEventListener('mousedown', event => event.consume(), false);
345
330
 
346
331
  this.boundShadowChanged = this.shadowChanged.bind(this);
347
332
  this.boundOnScroll = this.onScroll.bind(this);
348
333
  }
349
334
 
350
- private keyDown(event: KeyboardEvent): void {
351
- if (Platform.KeyboardUtilities.isEnterOrSpaceKey(event)) {
352
- event.consume(true);
353
- this.showPopover();
354
- }
355
- }
356
-
357
- private iconClick(event: Event): void {
358
- event.consume(true);
359
- this.showPopover();
360
- }
361
-
362
- showPopover(): void {
335
+ showPopover(shadowSwatch: InlineEditor.Swatches.CSSShadowSwatch): void {
363
336
  if (this.swatchPopoverHelper.isShowing()) {
364
337
  this.swatchPopoverHelper.hide(true);
365
338
  return;
366
339
  }
367
340
 
341
+ const iconElement = shadowSwatch.iconElement();
368
342
  this.cssShadowEditor = new InlineEditor.CSSShadowEditor.CSSShadowEditor();
369
343
  this.cssShadowEditor.element.classList.toggle('with-padding', true);
370
- this.cssShadowEditor.setModel(this.shadowSwatch.model());
344
+ this.cssShadowEditor.setModel(shadowSwatch.model());
371
345
  this.cssShadowEditor.addEventListener(InlineEditor.CSSShadowEditor.Events.SHADOW_CHANGED, this.boundShadowChanged);
372
- this.swatchPopoverHelper.show(this.cssShadowEditor, this.iconElement, this.onPopoverHidden.bind(this));
373
- this.scrollerElement = this.iconElement.enclosingNodeOrSelfWithClass('style-panes-wrapper');
346
+ this.swatchPopoverHelper.show(this.cssShadowEditor, iconElement, this.onPopoverHidden.bind(this));
347
+ this.scrollerElement = iconElement.enclosingNodeOrSelfWithClass('style-panes-wrapper');
374
348
  if (this.scrollerElement) {
375
349
  this.scrollerElement.addEventListener('scroll', this.boundOnScroll, false);
376
350
  }
@@ -701,7 +701,9 @@ function renderLinkifiedValue(value: string, node: SDK.DOMModel.DOMNode): Lit.Te
701
701
  if (value.startsWith('data:')) {
702
702
  value = Platform.StringUtilities.trimMiddle(value, 60);
703
703
  }
704
- const isAnchor = node && node.nodeName().toLowerCase() === 'a';
704
+ // Page-authored hrefs must not open privileged URLs (e.g. `devtools://` or `chrome://`) on click. Anchors with
705
+ // other schemes fall through to the Linkifier, which renders privileged URLs as inert text.
706
+ const isAnchor = node && node.nodeName().toLowerCase() === 'a' && Common.ParsedURL.hasWebSafeScheme(rewrittenHref);
705
707
  if (isAnchor) {
706
708
  return html`<devtools-link class="devtools-link image-url" href=${rewrittenHref} ${ref(el => {
707
709
  if (el) {
@@ -120,7 +120,7 @@ interface ViewInput {
120
120
  selectedClosingTag: boolean;
121
121
 
122
122
  onSelect: (node: SDK.DOMModel.DOMNode, isClosingTag: boolean, selectedByUser: boolean) => void;
123
- onExpand: (node: SDK.DOMModel.DOMNode, expanded: boolean) => void;
123
+ onExpand: (node: SDK.DOMModel.DOMNode, expanded: boolean, recursively?: boolean) => void;
124
124
  onContextMenu: (node: SDK.DOMModel.DOMNode, event: MouseEvent) => void;
125
125
  onClearMaxRows: () => void;
126
126
  onHoverNode: (node: SDK.DOMModel.DOMNode|null, showInfo: boolean, isClosingTag: boolean) => void;
@@ -659,7 +659,7 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
659
659
  if (!isCollapsible) {
660
660
  return;
661
661
  }
662
- input.onExpand(node, event.detail.expanded);
662
+ input.onExpand(node, event.detail.expanded, event.detail.recursively);
663
663
  };
664
664
 
665
665
  const isDragOver = input.dragOverNode?.node === node && !input.dragOverNode.isClosingTag;
@@ -690,6 +690,16 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
690
690
  input.onContextMenu(node, event);
691
691
  };
692
692
 
693
+ // Prevent the native word selection on double click. The double click
694
+ // starts inline editing instead. Inside an active inline editor the
695
+ // native selection must stay enabled.
696
+ const onMouseDown = (event: MouseEvent): void => {
697
+ if (event.detail < 2 || UI.UIUtils.isBeingEdited(event.target as Node)) {
698
+ return;
699
+ }
700
+ event.preventDefault();
701
+ };
702
+
693
703
  const onDragStart = (event: DragEvent): void => {
694
704
  event.stopPropagation();
695
705
  const currentTarget = event.currentTarget as HTMLElement | null;
@@ -733,6 +743,7 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
733
743
  @select=${on((event: UI.TreeOutline.TreeViewElement.SelectEvent) => onSelect(false, Boolean(event.detail?.selectedByUser)))}
734
744
  @expand=${on(onExpand)}
735
745
  @mousemove=${on(onMouseMove(/* isClosingTag= */ false))}
746
+ @mousedown=${on(onMouseDown)}
736
747
  @contextmenu=${on(onContextMenu)}
737
748
  @dragstart=${on(onDragStart)}
738
749
  @dragover=${on(onDragOver(/* isClosingTag= */ false))}
@@ -816,6 +827,7 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
816
827
  @select=${on((event: UI.TreeOutline.TreeViewElement.SelectEvent) => onSelect(true, Boolean(event.detail?.selectedByUser)))}
817
828
  @contextmenu=${on(onContextMenu)}
818
829
  @mousemove=${on(onMouseMove(/* isClosingTag= */ true))}
830
+ @mousedown=${on(onMouseDown)}
819
831
  @dragstart=${on(onDragStart)}
820
832
  @dragover=${on(onDragOver(/* isClosingTag= */ true))}
821
833
  @dragleave=${on(onDragLeave)}
@@ -1777,7 +1789,11 @@ export class DOMTreeWidget extends UI.Widget.Widget {
1777
1789
  node.highlight();
1778
1790
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.ChangeInspectedNodeInElementsPanel);
1779
1791
  },
1780
- onExpand: (node: SDK.DOMModel.DOMNode, expanded: boolean) => {
1792
+ onExpand: (node: SDK.DOMModel.DOMNode, expanded: boolean, recursively = false) => {
1793
+ if (expanded && recursively) {
1794
+ void this.expandRecursively(node);
1795
+ return;
1796
+ }
1781
1797
  this.setNodeExpanded(node, expanded);
1782
1798
  },
1783
1799
  onContextMenu: (node: SDK.DOMModel.DOMNode, event: MouseEvent) => {
@@ -69,6 +69,8 @@ enum SpecificPseudoStates {
69
69
  AUTOFILL = 'autofill',
70
70
  OPEN = 'open',
71
71
  TARGET_CURRENT = 'target-current',
72
+ BUFFERING = 'buffering',
73
+ STALLED = 'stalled',
72
74
  }
73
75
 
74
76
  interface ElementState {
@@ -92,7 +94,7 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
92
94
  return html`
93
95
  <div id=${state.state}>
94
96
  <devtools-checkbox class="small" @click=${input.onStateCheckboxClicked}
95
- jslog=${VisualLogging.toggle(state.state).track({change: true})} ?checked=${state.checked} ?disabled=${state.disabled}
97
+ jslog=${VisualLogging.toggle(state.state).track({change: true})} .checked=${Boolean(state.checked)} ?disabled=${state.disabled}
96
98
  title=${':' + state.state}>
97
99
  <span class="source-code">${':' + state.state}</span>
98
100
  </devtools-checkbox>
@@ -184,6 +186,8 @@ export class ElementStatePaneWidget extends UI.Widget.Widget {
184
186
  this.#states.set(SpecificPseudoStates.OPEN, {state: SpecificPseudoStates.OPEN, type: 'specific'});
185
187
  this.#states.set(
186
188
  SpecificPseudoStates.TARGET_CURRENT, {state: SpecificPseudoStates.TARGET_CURRENT, type: 'specific'});
189
+ this.#states.set(SpecificPseudoStates.BUFFERING, {state: SpecificPseudoStates.BUFFERING, type: 'specific'});
190
+ this.#states.set(SpecificPseudoStates.STALLED, {state: SpecificPseudoStates.STALLED, type: 'specific'});
187
191
 
188
192
  setDualStateCheckboxes(SpecificPseudoStates.VALID, SpecificPseudoStates.INVALID);
189
193
  setDualStateCheckboxes(SpecificPseudoStates.USER_VALID, SpecificPseudoStates.USER_INVALID);
@@ -399,6 +403,12 @@ export class ElementStatePaneWidget extends UI.Widget.Widget {
399
403
  } else {
400
404
  hideSpecificCheckbox(SpecificPseudoStates.TARGET_CURRENT, true);
401
405
  }
406
+
407
+ // :buffering and :stalled are independent. Forcing :stalled does not force
408
+ // :buffering, even though a real stalled media element is also buffering.
409
+ const isMediaElement = isElementOfTypes(node, ['audio', 'video']);
410
+ hideSpecificCheckbox(SpecificPseudoStates.BUFFERING, !isMediaElement);
411
+ hideSpecificCheckbox(SpecificPseudoStates.STALLED, !isMediaElement);
402
412
  }
403
413
  }
404
414
 
@@ -324,8 +324,9 @@ export class TracingContext {
324
324
  // evaluation callback is run. The callback should return synchronously an array of Nodes as placeholder to be
325
325
  // rendered immediately and optionally a callback for asynchronous updates of the placeholder nodes. The callback
326
326
  // returns a boolean indicating whether the update was successful or not.
327
- applyEvaluation(children: TracingContext[],
328
- evaluation: () => ({placeholder: Node[], asyncEvalCallback?: () => Promise<boolean>})): Node[]|null {
327
+ applyEvaluation<T extends Node[]|LitTemplate = Node[]>(
328
+ children: TracingContext[], evaluation: () => ({placeholder: T, asyncEvalCallback?: () => Promise<boolean>})): T
329
+ |null {
329
330
  if (this.#evaluationCount === 0 || children.some(child => child.#appliedEvaluations >= this.#evaluationCount)) {
330
331
  this.#setHasMoreEvaluations(true);
331
332
  children.forEach(child => this.#asyncEvalCallbacks.push(...child.#asyncEvalCallbacks));