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,25 +1,30 @@
1
1
  // Copyright 2016 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 */
4
+
5
+ import '../../ui/components/report_view/report_view.js';
6
+ import '../../ui/kit/kit.js';
7
+ import '../../ui/legacy/components/perf_ui/perf_ui.js';
5
8
 
6
9
  import * as Common from '../../core/common/common.js';
7
10
  import * as i18n from '../../core/i18n/i18n.js';
8
11
  import * as Platform from '../../core/platform/platform.js';
9
12
  import * as SDK from '../../core/sdk/sdk.js';
10
13
  import * as Protocol from '../../generated/protocol.js';
11
- import type * as Buttons from '../../ui/components/buttons/buttons.js';
14
+ import * as Buttons from '../../ui/components/buttons/buttons.js';
12
15
  import * as uiI18n from '../../ui/i18n/i18n.js';
13
- import {Icon, Link} from '../../ui/kit/kit.js';
14
- import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
15
- import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.js';
16
+ import type * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
16
17
  import * as UI from '../../ui/legacy/legacy.js';
18
+ import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
17
19
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
18
20
 
19
21
  import {IndexedDBModel} from './IndexedDBModel.js';
20
22
  import {ResourcesPanel} from './ResourcesPanel.js';
21
23
  import storageViewStyles from './storageView.css.js';
22
24
 
25
+ const {classMap, ifDefined, live, ref} = Directives;
26
+ const {bindToSetting} = UI.UIUtils;
27
+
23
28
  const UIStrings = {
24
29
  /**
25
30
  * @description Text in the storage view that expresses the amount of used and available storage quota.
@@ -162,49 +167,225 @@ export const storagePieColors: Map<Protocol.Storage.StorageType, string> =
162
167
  const str_ = i18n.i18n.registerUIStrings('panels/application/StorageView.ts', UIStrings);
163
168
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
164
169
 
170
+ export interface ViewInput {
171
+ subtitle: string;
172
+ settings: Map<Protocol.Storage.StorageType, Common.Settings.Setting<boolean>>;
173
+ includeThirdPartyCookiesSetting: Common.Settings.Setting<boolean>;
174
+ includeThirdPartyCookiesDisabled: boolean;
175
+ clearing: boolean;
176
+ quotaUsage: number|null;
177
+ quotaQuota: number|null;
178
+ quotaOverrideActive: boolean|null;
179
+ pieChartSlices: PerfUI.PieChart.Slice[];
180
+ quotaOverrideEnabled: boolean;
181
+ quotaOverrideValue: string;
182
+ quotaOverrideError: string;
183
+ onClear: () => void;
184
+ onToggleQuotaOverride: () => void;
185
+ onQuotaOverrideInput: (value: string) => void;
186
+ onApplyQuotaOverride: (value: string) => void;
187
+ }
188
+
189
+ export interface ViewOutput {
190
+ focusClearButton?: () => void;
191
+ focusQuotaOverrideEditor?: () => void;
192
+ }
193
+
194
+ export type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
195
+
196
+ export const DEFAULT_VIEW: View = (input, output, target) => {
197
+ function renderSettingCheckbox(title: Platform.UIString.LocalizedString, settingName: Protocol.Storage.StorageType,
198
+ className: string): LitTemplate {
199
+ const setting = input.settings.get(settingName);
200
+ if (!setting) {
201
+ throw new Error(`Missing setting for storage type: ${settingName}`);
202
+ }
203
+ return html`<devtools-checkbox class=${className} title=${title} ${bindToSetting(setting)}>${
204
+ title}</devtools-checkbox>`;
205
+ }
206
+
207
+ function renderClearSiteData(): LitTemplate {
208
+ // clang-format off
209
+ return html`
210
+ <div class="report-section" jslog=${VisualLogging.section('clear-storage')}>
211
+ <devtools-report-section-header role="heading" aria-level="2">
212
+ ${i18nString(UIStrings.clearSiteData)}
213
+ </devtools-report-section-header>
214
+ <devtools-report-section>
215
+ <div class="clear-site-data-checkboxes-row" role="group" aria-label=${i18nString(UIStrings.clearSiteData)}>
216
+ <div class="clear-site-data-checkbox-column">
217
+ ${renderSettingCheckbox(i18nString(UIStrings.cacheStorage), Protocol.Storage.StorageType.Cache_storage, 'cache-storage-checkbox')}
218
+ ${renderSettingCheckbox(i18nString(UIStrings.fileSystem), Protocol.Storage.StorageType.File_systems, 'file-systems-checkbox')}
219
+ ${renderSettingCheckbox(i18nString(UIStrings.indexDB), Protocol.Storage.StorageType.Indexeddb, 'indexeddb-checkbox')}
220
+ ${renderSettingCheckbox(i18nString(UIStrings.localAndSessionStorage), Protocol.Storage.StorageType.Local_storage, 'local-and-session-storage-checkbox')}
221
+ </div>
222
+ <div class="clear-site-data-checkbox-column">
223
+ ${renderSettingCheckbox(i18nString(UIStrings.unregisterServiceWorker), Protocol.Storage.StorageType.Service_workers, 'unregister-service-worker-checkbox')}
224
+ ${renderSettingCheckbox(i18nString(UIStrings.cookies), Protocol.Storage.StorageType.Cookies, 'cookies-checkbox cookies-row')}
225
+ <div class="include-third-party-cookies-row">
226
+ <devtools-checkbox class="third-party-cookies-checkbox"
227
+ title=${i18nString(UIStrings.thirdPartyCookies)}
228
+ ?disabled=${input.includeThirdPartyCookiesDisabled}
229
+ ${bindToSetting(input.includeThirdPartyCookiesSetting)}>
230
+ ${i18nString(UIStrings.thirdPartyCookies)}
231
+ </devtools-checkbox>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </devtools-report-section>
236
+ <devtools-report-section class="clear-selected-button-row">
237
+ <devtools-button id="storage-view-clear-button"
238
+ .variant=${Buttons.Button.Variant.OUTLINED}
239
+ .disabled=${input.clearing}
240
+ .jslogContext=${'storage.clear-site-data'}
241
+ @click=${input.onClear}
242
+ ${ref(e => {
243
+ output.focusClearButton = e instanceof HTMLElement ? () => e.focus() : undefined;
244
+ })}
245
+ >${input.clearing ? i18nString(UIStrings.clearing) : i18nString(UIStrings.clearSelected)}</devtools-button>
246
+ </devtools-report-section>
247
+ </div>`;
248
+ // clang-format on
249
+ }
250
+
251
+ function quotaTooltip(): string|undefined {
252
+ if (input.quotaUsage === null || input.quotaQuota === null) {
253
+ return undefined;
254
+ }
255
+ return i18nString(UIStrings.storageQuotaUsedWithBytes,
256
+ {PH1: input.quotaUsage.toLocaleString(), PH2: input.quotaQuota.toLocaleString()});
257
+ }
258
+
259
+ function renderQuotaRow(): LitTemplate {
260
+ if (input.quotaUsage === null || input.quotaQuota === null) {
261
+ return nothing;
262
+ }
263
+ const quotaAsString = i18n.ByteUtilities.bytesToString(input.quotaQuota);
264
+ const usageAsString = i18n.ByteUtilities.bytesToString(input.quotaUsage);
265
+ const formattedQuotaAsString = i18nString(UIStrings.storageWithCustomMarker, {PH1: quotaAsString});
266
+ const quota = input.quotaOverrideActive ? html`<b>${formattedQuotaAsString}</b>` : quotaAsString;
267
+ // clang-format off
268
+ return html`
269
+ ${uiI18n.getFormatLocalizedStringTemplate(str_, UIStrings.storageQuotaUsed, {PH1: usageAsString, PH2: quota})}
270
+ ${!input.quotaOverrideActive && input.quotaQuota < 125829120 /* 120 MiB */ ? html`
271
+ <devtools-icon name="info" class="small" style="color: var(--icon-info)"
272
+ title=${i18nString(UIStrings.storageQuotaIsLimitedIn)}></devtools-icon>` : nothing}`;
273
+ // clang-format on
274
+ }
275
+
276
+ function renderUsage(): LitTemplate {
277
+ const pieChartData: PerfUI.PieChart.PieChartData = {
278
+ chartName: i18nString(UIStrings.storageUsage),
279
+ size: 110,
280
+ formatter: i18n.ByteUtilities.bytesToString,
281
+ showLegend: true,
282
+ total: input.quotaUsage ?? 0,
283
+ slices: input.pieChartSlices,
284
+ };
285
+ const onEditorInput = (event: Event): void => {
286
+ input.onQuotaOverrideInput((event.target as HTMLInputElement).value);
287
+ };
288
+ const onEditorKeyUp = (event: KeyboardEvent): void => {
289
+ if (event.key === 'Enter' && !event.isComposing) {
290
+ input.onApplyQuotaOverride((event.target as HTMLInputElement).value);
291
+ event.consume(true);
292
+ }
293
+ };
294
+ const onEditorFocusOut = (event: FocusEvent): void => {
295
+ input.onApplyQuotaOverride((event.target as HTMLInputElement).value);
296
+ event.consume(true);
297
+ };
298
+ // clang-format off
299
+ return html`
300
+ <div class="report-section" jslog=${VisualLogging.section('usage')}>
301
+ <devtools-report-section-header role="heading" aria-level="2">
302
+ ${i18nString(UIStrings.usage)}
303
+ </devtools-report-section-header>
304
+ <devtools-report-section class="quota-usage-row" jslog=${VisualLogging.item('storage-usage')}
305
+ title=${ifDefined(quotaTooltip())}>${renderQuotaRow()}</devtools-report-section>
306
+ <devtools-report-section>
307
+ <devtools-link href="https://developer.chrome.com/docs/devtools/progressive-web-apps#opaque-responses"
308
+ jslogcontext="learn-more">${i18nString(UIStrings.learnMore)}</devtools-link>
309
+ </devtools-report-section>
310
+ <devtools-report-section class="usage-breakdown-row" jslog=${VisualLogging.item('usage-breakdown')}>
311
+ <devtools-perf-piechart .data=${pieChartData}></devtools-perf-piechart>
312
+ </devtools-report-section>
313
+ <devtools-report-section class="quota-override-row">
314
+ <devtools-checkbox .checked=${live(input.quotaOverrideEnabled)}
315
+ title=${i18nString(UIStrings.simulateCustomStorage)}
316
+ @change=${input.onToggleQuotaOverride}
317
+ jslog=${VisualLogging.toggle('simulate-custom-quota').track({change: true})}>
318
+ ${i18nString(UIStrings.simulateCustomStorage)}
319
+ </devtools-checkbox>
320
+ </devtools-report-section>
321
+ <devtools-report-section class=${classMap({hidden: !input.quotaOverrideEnabled})}>
322
+ <input class="quota-override-notification-editor"
323
+ aria-label=${i18nString(UIStrings.simulateCustomStorage)}
324
+ placeholder=${i18nString(UIStrings.pleaseEnterANumber)}
325
+ .value=${live(input.quotaOverrideValue)}
326
+ @input=${onEditorInput}
327
+ @keyup=${onEditorKeyUp}
328
+ @focusout=${onEditorFocusOut}
329
+ ${ref(e => {
330
+ output.focusQuotaOverrideEditor = e instanceof HTMLElement ? () => e.focus() : undefined;
331
+ })}
332
+ jslog=${VisualLogging.textField('quota-override').track({change: true})}>
333
+ <label>${i18nString(UIStrings.mb)}</label>
334
+ </devtools-report-section>
335
+ <devtools-report-section><div class="quota-override-error">${input.quotaOverrideError}</div></devtools-report-section>
336
+ </div>`;
337
+ // clang-format on
338
+ }
339
+
340
+ // clang-format off
341
+ render(html`
342
+ <devtools-report class="clear-storage-header" .data=${{reportTitle: i18nString(UIStrings.storageTitle)}}>
343
+ ${input.subtitle ? html`<div class="report-subtitle" slot="toolbar">${input.subtitle}</div>` : nothing}
344
+ ${renderClearSiteData()}
345
+ <devtools-report-divider></devtools-report-divider>
346
+ ${renderUsage()}
347
+ </devtools-report>`, target);
348
+ // clang-format on
349
+ };
350
+
165
351
  /**
166
352
  * @implements {SDK.TargetManager.Observer}
167
353
  */
168
354
  export class StorageView extends UI.Widget.VBox {
355
+ readonly #view: View;
356
+ readonly #viewOutput: ViewOutput = {};
169
357
  private pieColors: Map<Protocol.Storage.StorageType, string>;
170
- private reportView: UI.ReportView.ReportView;
171
- private target: SDK.Target.Target|null;
172
- private securityOrigin: string|null;
173
- private storageKey: string|null;
358
+ private target: SDK.Target.Target|null = null;
359
+ private securityOrigin: string|null = null;
360
+ private storageKey: string|null = null;
361
+ private subtitle = '';
174
362
  private settings: Map<Protocol.Storage.StorageType, Common.Settings.Setting<boolean>>;
175
363
  private includeThirdPartyCookiesSetting: Common.Settings.Setting<boolean>;
176
- private includeThirdPartyCookiesCheckbox: UI.UIUtils.CheckboxLabel;
177
- private quotaRow: HTMLElement;
178
- private quotaUsage: number|null;
179
- private quotaQuota: number|null;
180
- private quotaOverrideActive: boolean|null;
181
- private pieChart: PerfUI.PieChart.PieChart;
182
- private previousOverrideFieldValue: string;
183
- private quotaOverrideCheckbox: UI.UIUtils.CheckboxLabel;
184
- private quotaOverrideControlRow: HTMLElement;
185
- private quotaOverrideEditor: HTMLInputElement;
186
- private quotaOverrideErrorMessage: HTMLElement;
187
- private clearButton: Buttons.Button.Button;
364
+ private quotaUsage: number|null = null;
365
+ private quotaQuota: number|null = null;
366
+ private quotaOverrideActive: boolean|null = null;
367
+ private pieChartSlices: PerfUI.PieChart.Slice[] = [];
368
+ private previousOverrideFieldValue = '';
369
+ private quotaOverrideFieldValue = '';
370
+ private quotaOverrideEnabled = false;
371
+ private quotaOverrideError = '';
372
+ private clearing = false;
373
+ private clearTimerId?: number;
188
374
  private readonly throttler = new Common.Throttler.Throttler(1000);
189
-
190
- constructor() {
191
- super({useShadowDom: true});
375
+ private readonly boundOnCookiesSettingChanged = (event: Common.EventTarget.EventTargetEvent<boolean>): void => {
376
+ this.onCookiesSettingChanged(event.data);
377
+ };
378
+ private readonly boundOnIncludeThirdPartyCookiesSettingChanged =
379
+ (event: Common.EventTarget.EventTargetEvent<boolean>): void => {
380
+ this.onIncludeThirdPartyCookiesSettingChanged(event.data);
381
+ };
382
+
383
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
384
+ super(element, {useShadowDom: true, jslog: `${VisualLogging.pane('clear-storage')}`});
385
+ this.#view = view;
192
386
  this.registerRequiredCSS(storageViewStyles);
193
-
194
- this.contentElement.classList.add('clear-storage-container');
195
- this.contentElement.setAttribute('jslog', `${VisualLogging.pane('clear-storage')}`);
196
387
  this.pieColors = storagePieColors;
197
388
 
198
- // TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
199
- this.reportView = new UI.ReportView.ReportView(i18nString(UIStrings.storageTitle));
200
- this.reportView.registerRequiredCSS(storageViewStyles);
201
-
202
- this.reportView.element.classList.add('clear-storage-header');
203
- this.reportView.show(this.contentElement);
204
- this.target = null;
205
- this.securityOrigin = null;
206
- this.storageKey = null;
207
-
208
389
  this.settings = new Map();
209
390
  for (const type of AllStorageTypes) {
210
391
  this.settings.set(
@@ -216,156 +397,28 @@ export class StorageView extends UI.Widget.VBox {
216
397
  this.includeThirdPartyCookiesSetting =
217
398
  Common.Settings.Settings.instance().createSetting('clear-storage-include-third-party-cookies', false);
218
399
 
219
- const clearSiteData = this.reportView.appendSection(i18nString(UIStrings.clearSiteData));
220
- clearSiteData.element.setAttribute('jslog', `${VisualLogging.section('clear-storage')}`);
221
-
222
- const clearSiteDataCheckboxesRow = clearSiteData.appendRow();
223
- clearSiteDataCheckboxesRow.classList.add('clear-site-data-checkboxes-row');
224
- const leftColumn = clearSiteDataCheckboxesRow.createChild('div', 'clear-site-data-checkbox-column');
225
- this.appendSettingCheckbox(leftColumn, i18nString(UIStrings.cacheStorage),
226
- Protocol.Storage.StorageType.Cache_storage, 'cache-storage-checkbox');
227
- this.appendSettingCheckbox(leftColumn, i18nString(UIStrings.fileSystem), Protocol.Storage.StorageType.File_systems,
228
- 'file-systems-checkbox');
229
- this.appendSettingCheckbox(leftColumn, i18nString(UIStrings.indexDB), Protocol.Storage.StorageType.Indexeddb,
230
- 'indexeddb-checkbox');
231
- this.appendSettingCheckbox(leftColumn, i18nString(UIStrings.localAndSessionStorage),
232
- Protocol.Storage.StorageType.Local_storage, 'local-and-session-storage-checkbox');
233
-
234
- const rightColumn = clearSiteDataCheckboxesRow.createChild('div', 'clear-site-data-checkbox-column');
235
- this.appendSettingCheckbox(rightColumn, i18nString(UIStrings.unregisterServiceWorker),
236
- Protocol.Storage.StorageType.Service_workers, 'unregister-service-worker-checkbox');
237
- const cookiesCheckbox = this.appendSettingCheckbox(rightColumn, i18nString(UIStrings.cookies),
238
- Protocol.Storage.StorageType.Cookies, 'cookies-checkbox');
239
- cookiesCheckbox.classList.add('cookies-row');
240
-
241
- const includeThirdPartyCookiesRow = rightColumn.createChild('div', 'include-third-party-cookies-row');
242
- this.includeThirdPartyCookiesCheckbox = SettingsUI.SettingsUI.createSettingCheckbox(
243
- i18nString(UIStrings.thirdPartyCookies), this.includeThirdPartyCookiesSetting);
244
- this.includeThirdPartyCookiesCheckbox.classList.add('third-party-cookies-checkbox');
245
- includeThirdPartyCookiesRow.appendChild(this.includeThirdPartyCookiesCheckbox);
246
-
247
- const clearButtonRow = clearSiteData.appendRow();
248
- clearButtonRow.classList.add('clear-selected-button-row');
249
- this.clearButton = UI.UIUtils.createTextButton(i18nString(UIStrings.clearSelected), this.clear.bind(this),
250
- {jslogContext: 'storage.clear-site-data'});
251
- this.clearButton.id = 'storage-view-clear-button';
252
- clearButtonRow.appendChild(this.clearButton);
253
-
254
- clearSiteData.markFieldListAsGroup();
255
-
256
400
  const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
257
- if (cookiesSetting) {
258
- cookiesSetting.addChangeListener(event => this.onCookiesSettingChanged(event.data));
259
- }
260
- this.includeThirdPartyCookiesSetting.addChangeListener(
261
- event => this.onIncludeThirdPartyCookiesSettingChanged(event.data));
262
- cookiesCheckbox.addEventListener('change', () => {
263
- this.syncCheckboxAttributeState(cookiesCheckbox);
264
- if (!cookiesCheckbox.checked && this.includeThirdPartyCookiesCheckbox.checked) {
265
- this.includeThirdPartyCookiesCheckbox.click();
266
- }
267
- this.onCookiesSettingChanged(cookiesCheckbox.checked);
268
- });
269
- this.includeThirdPartyCookiesCheckbox.addEventListener('change', () => {
270
- this.syncCheckboxAttributeState(this.includeThirdPartyCookiesCheckbox);
271
- this.onIncludeThirdPartyCookiesSettingChanged(this.includeThirdPartyCookiesCheckbox.checked);
272
- });
273
401
  this.onCookiesSettingChanged(Boolean(cookiesSetting?.get()));
274
-
275
- const quota = this.reportView.appendSection(i18nString(UIStrings.usage));
276
- quota.element.setAttribute('jslog', `${VisualLogging.section('usage')}`);
277
- this.quotaRow = quota.appendSelectableRow();
278
- this.quotaRow.classList.add('quota-usage-row');
279
- this.quotaRow.setAttribute('jslog', `${VisualLogging.item('storage-usage')}`);
280
- const learnMoreRow = quota.appendRow();
281
- const learnMore = Link.create(
282
- 'https://developer.chrome.com/docs/devtools/progressive-web-apps#opaque-responses',
283
- i18nString(UIStrings.learnMore), undefined, 'learn-more');
284
- learnMoreRow.appendChild(learnMore);
285
- this.quotaUsage = null;
286
- this.quotaQuota = null;
287
- this.quotaOverrideActive = null;
288
- this.pieChart = new PerfUI.PieChart.PieChart();
289
- this.populatePieChart(0, []);
290
- const usageBreakdownRow = quota.appendRow();
291
- usageBreakdownRow.classList.add('usage-breakdown-row');
292
- usageBreakdownRow.setAttribute('jslog', `${VisualLogging.item('usage-breakdown')}`);
293
- usageBreakdownRow.appendChild(this.pieChart);
294
-
295
- this.previousOverrideFieldValue = '';
296
- const quotaOverrideCheckboxRow = quota.appendRow();
297
- quotaOverrideCheckboxRow.classList.add('quota-override-row');
298
- this.quotaOverrideCheckbox = UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.simulateCustomStorage), false);
299
- this.quotaOverrideCheckbox.setAttribute(
300
- 'jslog', `${VisualLogging.toggle('simulate-custom-quota').track({change: true})}`);
301
- quotaOverrideCheckboxRow.appendChild(this.quotaOverrideCheckbox);
302
- this.quotaOverrideCheckbox.addEventListener('click', this.onClickCheckbox.bind(this), false);
303
- this.quotaOverrideControlRow = quota.appendRow();
304
- this.quotaOverrideEditor = this.quotaOverrideControlRow.createChild('input', 'quota-override-notification-editor');
305
- this.quotaOverrideEditor.setAttribute('placeholder', i18nString(UIStrings.pleaseEnterANumber));
306
- this.quotaOverrideEditor.setAttribute(
307
- 'jslog', `${VisualLogging.textField('quota-override').track({change: true})}`);
308
- this.quotaOverrideControlRow.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.mb)));
309
- this.quotaOverrideControlRow.classList.add('hidden');
310
- this.quotaOverrideEditor.addEventListener('keyup', event => {
311
- if (event.key === 'Enter') {
312
- void this.applyQuotaOverrideFromInputField();
313
- event.consume(true);
314
- }
315
- });
316
- this.quotaOverrideEditor.addEventListener('focusout', event => {
317
- void this.applyQuotaOverrideFromInputField();
318
- event.consume(true);
319
- });
320
-
321
- const errorMessageRow = quota.appendRow();
322
- this.quotaOverrideErrorMessage = errorMessageRow.createChild('div', 'quota-override-error');
323
-
324
402
  SDK.TargetManager.TargetManager.instance().observeTargets(this);
325
403
  }
326
404
 
327
- private appendSettingCheckbox(container: HTMLElement, title: Platform.UIString.LocalizedString,
328
- settingName: Protocol.Storage.StorageType,
329
- className?: string): UI.UIUtils.CheckboxLabel {
330
- const setting = this.settings.get(settingName);
331
- if (!setting) {
332
- throw new Error(`Missing setting for storage type: ${settingName}`);
333
- }
334
- const checkbox = SettingsUI.SettingsUI.createSettingCheckbox(title, setting);
335
- if (className) {
336
- checkbox.classList.add(className);
337
- }
338
- container.appendChild(checkbox);
339
- return checkbox;
340
- }
341
-
342
405
  private onCookiesSettingChanged(cookiesEnabled: boolean): void {
343
- if (!cookiesEnabled) {
344
- this.includeThirdPartyCookiesCheckbox.toggleAttribute('checked', true);
345
- this.includeThirdPartyCookiesCheckbox.toggleAttribute('checked', false);
346
- if (this.includeThirdPartyCookiesSetting.get()) {
347
- this.includeThirdPartyCookiesSetting.set(false);
348
- }
406
+ // Unchecking general cookies clearing must also uncheck third-party cookies.
407
+ if (!cookiesEnabled && this.includeThirdPartyCookiesSetting.get()) {
408
+ this.includeThirdPartyCookiesSetting.set(false);
409
+ return;
349
410
  }
350
- this.updateThirdPartyCookiesCheckboxState();
411
+ this.requestUpdate();
351
412
  }
352
413
 
353
414
  private onIncludeThirdPartyCookiesSettingChanged(includeThirdPartyCookiesEnabled: boolean): void {
354
415
  const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
416
+ // Checking third-party cookies requires general cookies clearing to be enabled.
355
417
  if (includeThirdPartyCookiesEnabled && cookiesSetting && !cookiesSetting.get()) {
356
418
  cookiesSetting.set(true);
357
419
  return;
358
420
  }
359
- this.updateThirdPartyCookiesCheckboxState();
360
- }
361
-
362
- private syncCheckboxAttributeState(checkbox: UI.UIUtils.CheckboxLabel): void {
363
- checkbox.toggleAttribute('checked', checkbox.checked);
364
- }
365
-
366
- private updateThirdPartyCookiesCheckboxState(): void {
367
- const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
368
- this.includeThirdPartyCookiesCheckbox.disabled = !cookiesSetting?.get();
421
+ this.requestUpdate();
369
422
  }
370
423
 
371
424
  targetAdded(target: SDK.Target.Target): void {
@@ -400,6 +453,25 @@ export class StorageView extends UI.Widget.VBox {
400
453
  SDK.StorageKeyManager.Events.MAIN_STORAGE_KEY_CHANGED, this.storageKeyChanged, this);
401
454
  }
402
455
 
456
+ override willHide(): void {
457
+ super.willHide();
458
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
459
+ cookiesSetting?.removeChangeListener(this.boundOnCookiesSettingChanged);
460
+ this.includeThirdPartyCookiesSetting.removeChangeListener(this.boundOnIncludeThirdPartyCookiesSettingChanged);
461
+ }
462
+
463
+ override wasHidden(): void {
464
+ super.wasHidden();
465
+ if (this.clearTimerId !== undefined) {
466
+ window.clearTimeout(this.clearTimerId);
467
+ this.clearTimerId = undefined;
468
+ }
469
+ if (this.clearing) {
470
+ this.clearing = false;
471
+ this.requestUpdate();
472
+ }
473
+ }
474
+
403
475
  private originChanged(
404
476
  event: Common.EventTarget.EventTargetEvent<SDK.SecurityOriginManager.MainSecurityOriginChangedEvent>): void {
405
477
  const {mainSecurityOrigin, unreachableMainSecurityOrigin} = event.data;
@@ -416,69 +488,74 @@ export class StorageView extends UI.Widget.VBox {
416
488
  const oldOrigin = this.securityOrigin;
417
489
  if (unreachableMainOrigin) {
418
490
  this.securityOrigin = unreachableMainOrigin;
419
- this.reportView.setSubtitle(i18nString(UIStrings.sFailedToLoad, {PH1: unreachableMainOrigin}));
491
+ this.subtitle = i18nString(UIStrings.sFailedToLoad, {PH1: unreachableMainOrigin});
420
492
  } else {
421
493
  this.securityOrigin = mainOrigin;
422
- this.reportView.setSubtitle(mainOrigin);
494
+ this.subtitle = mainOrigin;
423
495
  }
424
496
 
425
497
  if (oldOrigin !== this.securityOrigin) {
426
- this.quotaOverrideControlRow.classList.add('hidden');
427
- this.quotaOverrideCheckbox.checked = false;
428
- this.quotaOverrideErrorMessage.textContent = '';
498
+ this.quotaOverrideEnabled = false;
499
+ this.quotaOverrideError = '';
429
500
  this.quotaUsage = null;
430
501
  this.quotaQuota = null;
431
502
  this.quotaOverrideActive = null;
503
+ this.pieChartSlices = [];
432
504
  }
433
- void this.performUpdate();
505
+ this.requestUpdate();
506
+ void this.refreshUsageAndQuota();
434
507
  }
435
508
 
436
509
  private updateStorageKey(mainStorageKey: string): void {
437
510
  const oldStorageKey = this.storageKey;
438
511
 
439
512
  this.storageKey = mainStorageKey;
440
- this.reportView.setSubtitle(mainStorageKey);
513
+ this.subtitle = mainStorageKey;
441
514
 
442
515
  if (oldStorageKey !== this.storageKey) {
443
- this.quotaOverrideControlRow.classList.add('hidden');
444
- this.quotaOverrideCheckbox.checked = false;
445
- this.quotaOverrideErrorMessage.textContent = '';
516
+ this.quotaOverrideEnabled = false;
517
+ this.quotaOverrideError = '';
446
518
  }
447
- void this.performUpdate();
519
+ this.requestUpdate();
448
520
  }
449
521
 
450
- private async applyQuotaOverrideFromInputField(): Promise<void> {
522
+ private async applyQuotaOverrideFromInputField(editorString: string): Promise<void> {
523
+ this.quotaOverrideFieldValue = editorString;
451
524
  if (!this.target || !this.securityOrigin) {
452
- this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.internalError);
525
+ this.quotaOverrideError = i18nString(UIStrings.internalError);
526
+ this.requestUpdate();
453
527
  return;
454
528
  }
455
- this.quotaOverrideErrorMessage.textContent = '';
456
- const editorString = this.quotaOverrideEditor.value;
529
+ this.quotaOverrideError = '';
457
530
  if (editorString === '') {
458
531
  await this.clearQuotaForOrigin(this.target, this.securityOrigin);
459
532
  this.previousOverrideFieldValue = '';
533
+ this.requestUpdate();
460
534
  return;
461
535
  }
462
536
  const quota = parseFloat(editorString);
463
537
  if (!Number.isFinite(quota)) {
464
- this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.pleaseEnterANumber);
538
+ this.quotaOverrideError = i18nString(UIStrings.pleaseEnterANumber);
539
+ this.requestUpdate();
465
540
  return;
466
541
  }
467
542
  if (quota < 0) {
468
- this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.numberMustBeNonNegative);
543
+ this.quotaOverrideError = i18nString(UIStrings.numberMustBeNonNegative);
544
+ this.requestUpdate();
469
545
  return;
470
546
  }
471
547
  const cutoff = 9_000_000_000_000;
472
548
  if (quota >= cutoff) {
473
- this.quotaOverrideErrorMessage.textContent =
474
- i18nString(UIStrings.numberMustBeSmaller, {PH1: cutoff.toLocaleString()});
549
+ this.quotaOverrideError = i18nString(UIStrings.numberMustBeSmaller, {PH1: cutoff.toLocaleString()});
550
+ this.requestUpdate();
475
551
  return;
476
552
  }
477
553
  const bytesPerMB = 1000 * 1000;
478
554
  const quotaInBytes = Math.round(quota * bytesPerMB);
479
555
  const quotaFieldValue = `${quotaInBytes / bytesPerMB}`;
480
- this.quotaOverrideEditor.value = quotaFieldValue;
481
556
  this.previousOverrideFieldValue = quotaFieldValue;
557
+ this.quotaOverrideFieldValue = quotaFieldValue;
558
+ this.requestUpdate();
482
559
  await this.target.storageAgent().invoke_overrideQuotaForOrigin(
483
560
  {origin: this.securityOrigin, quotaSize: quotaInBytes});
484
561
  }
@@ -488,16 +565,19 @@ export class StorageView extends UI.Widget.VBox {
488
565
  }
489
566
 
490
567
  private async onClickCheckbox(): Promise<void> {
491
- if (this.quotaOverrideControlRow.classList.contains('hidden')) {
492
- this.quotaOverrideControlRow.classList.remove('hidden');
493
- this.quotaOverrideCheckbox.checked = true;
494
- this.quotaOverrideEditor.value = this.previousOverrideFieldValue;
495
- window.setTimeout(() => this.quotaOverrideEditor.focus(), 500);
496
- } else if (this.target && this.securityOrigin) {
497
- this.quotaOverrideControlRow.classList.add('hidden');
498
- this.quotaOverrideCheckbox.checked = false;
499
- await this.clearQuotaForOrigin(this.target, this.securityOrigin);
500
- this.quotaOverrideErrorMessage.textContent = '';
568
+ if (!this.quotaOverrideEnabled) {
569
+ this.quotaOverrideEnabled = true;
570
+ this.quotaOverrideFieldValue = this.previousOverrideFieldValue;
571
+ this.requestUpdate();
572
+ await this.updateComplete;
573
+ this.#viewOutput.focusQuotaOverrideEditor?.();
574
+ } else {
575
+ this.quotaOverrideEnabled = false;
576
+ this.quotaOverrideError = '';
577
+ this.requestUpdate();
578
+ if (this.target && this.securityOrigin) {
579
+ await this.clearQuotaForOrigin(this.target, this.securityOrigin);
580
+ }
501
581
  }
502
582
  }
503
583
 
@@ -519,13 +599,17 @@ export class StorageView extends UI.Widget.VBox {
519
599
  this.target, this.storageKey, this.securityOrigin, selectedStorageTypes, includeThirdPartyCookies);
520
600
  }
521
601
 
522
- this.clearButton.disabled = true;
523
- const label = this.clearButton.textContent;
524
- this.clearButton.textContent = i18nString(UIStrings.clearing);
525
- window.setTimeout(() => {
526
- this.clearButton.disabled = false;
527
- this.clearButton.textContent = label;
528
- this.clearButton.focus();
602
+ this.clearing = true;
603
+ this.requestUpdate();
604
+ window.clearTimeout(this.clearTimerId);
605
+ this.clearTimerId = window.setTimeout(async () => {
606
+ this.clearTimerId = undefined;
607
+ this.clearing = false;
608
+ this.requestUpdate();
609
+ await this.updateComplete;
610
+ if (this.isShowing()) {
611
+ this.#viewOutput.focusClearButton?.();
612
+ }
529
613
  }, 500);
530
614
 
531
615
  UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.SiteDataCleared));
@@ -578,24 +662,33 @@ export class StorageView extends UI.Widget.VBox {
578
662
  }
579
663
  }
580
664
 
581
- override async performUpdate(): Promise<void> {
665
+ private async refreshUsageAndQuota(): Promise<void> {
666
+ if (!this.isShowing()) {
667
+ return;
668
+ }
582
669
  if (!this.securityOrigin || !this.target) {
583
- this.quotaRow.textContent = '';
584
670
  this.quotaUsage = null;
585
671
  this.quotaQuota = null;
586
672
  this.quotaOverrideActive = null;
587
- this.populatePieChart(0, []);
673
+ this.pieChartSlices = [];
674
+ this.requestUpdate();
588
675
  return;
589
676
  }
590
677
 
591
678
  const securityOrigin = this.securityOrigin;
592
679
  const response = await this.target.storageAgent().invoke_getUsageAndQuota({origin: securityOrigin});
680
+ if (this.securityOrigin !== securityOrigin) {
681
+ return;
682
+ }
593
683
  if (response.getError()) {
594
- this.quotaRow.textContent = '';
595
684
  this.quotaUsage = null;
596
685
  this.quotaQuota = null;
597
686
  this.quotaOverrideActive = null;
598
- this.populatePieChart(0, []);
687
+ this.pieChartSlices = [];
688
+ this.requestUpdate();
689
+ if (this.isShowing()) {
690
+ void this.throttler.schedule(() => this.refreshUsageAndQuota());
691
+ }
599
692
  return;
600
693
  }
601
694
 
@@ -608,35 +701,6 @@ export class StorageView extends UI.Widget.VBox {
608
701
  this.quotaQuota = response.quota;
609
702
  this.quotaOverrideActive = response.overrideActive;
610
703
 
611
- this.quotaRow.textContent = '';
612
- const quotaAsString = i18n.ByteUtilities.bytesToString(response.quota);
613
- const usageAsString = i18n.ByteUtilities.bytesToString(response.usage);
614
- const formattedQuotaAsString = i18nString(UIStrings.storageWithCustomMarker, {PH1: quotaAsString});
615
-
616
- let quota: string|HTMLElement = quotaAsString;
617
- if (response.overrideActive) {
618
- const element = document.createElement('b');
619
- element.textContent = formattedQuotaAsString;
620
- quota = element;
621
- }
622
-
623
- const element =
624
- uiI18n.getFormatLocalizedString(str_, UIStrings.storageQuotaUsed, {PH1: usageAsString, PH2: quota});
625
- this.quotaRow.appendChild(element);
626
- UI.Tooltip.Tooltip.install(
627
- this.quotaRow,
628
- i18nString(UIStrings.storageQuotaUsedWithBytes,
629
- {PH1: response.usage.toLocaleString(), PH2: response.quota.toLocaleString()}));
630
-
631
- if (!response.overrideActive && response.quota < 125829120) { // 120 MiB
632
- const icon = new Icon();
633
- icon.name = 'info';
634
- icon.style.color = 'var(--icon-info)';
635
- icon.classList.add('small');
636
- UI.Tooltip.Tooltip.install(icon, i18nString(UIStrings.storageQuotaIsLimitedIn));
637
- this.quotaRow.appendChild(icon);
638
- }
639
-
640
704
  if (usageChanged) {
641
705
  const slices: PerfUI.PieChart.Slice[] = [];
642
706
  for (const usageForType of response.usageBreakdown.sort((a, b) => b.usage - a.usage)) {
@@ -648,22 +712,52 @@ export class StorageView extends UI.Widget.VBox {
648
712
  const color = this.pieColors.get(usageForType.storageType) || '#ccc';
649
713
  slices.push({value, color, title});
650
714
  }
651
- this.populatePieChart(response.usage, slices);
715
+ this.pieChartSlices = slices;
652
716
  }
717
+ this.requestUpdate();
653
718
  }
654
719
 
655
- void this.throttler.schedule(this.requestUpdate.bind(this));
720
+ if (this.isShowing()) {
721
+ void this.throttler.schedule(() => this.refreshUsageAndQuota());
722
+ }
656
723
  }
657
724
 
658
- private populatePieChart(total: number, slices: PerfUI.PieChart.Slice[]): void {
659
- this.pieChart.data = {
660
- chartName: i18nString(UIStrings.storageUsage),
661
- size: 110,
662
- formatter: i18n.ByteUtilities.bytesToString,
663
- showLegend: true,
664
- total,
665
- slices,
666
- };
725
+ override wasShown(): void {
726
+ super.wasShown();
727
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
728
+ cookiesSetting?.addChangeListener(this.boundOnCookiesSettingChanged);
729
+ this.includeThirdPartyCookiesSetting.addChangeListener(this.boundOnIncludeThirdPartyCookiesSettingChanged);
730
+ this.onCookiesSettingChanged(Boolean(cookiesSetting?.get()));
731
+ void this.refreshUsageAndQuota();
732
+ }
733
+
734
+ override performUpdate(): void {
735
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
736
+ this.#view({
737
+ subtitle: this.subtitle,
738
+ settings: this.settings,
739
+ includeThirdPartyCookiesSetting: this.includeThirdPartyCookiesSetting,
740
+ includeThirdPartyCookiesDisabled: !cookiesSetting?.get(),
741
+ clearing: this.clearing,
742
+ quotaUsage: this.quotaUsage,
743
+ quotaQuota: this.quotaQuota,
744
+ quotaOverrideActive: this.quotaOverrideActive,
745
+ pieChartSlices: this.pieChartSlices,
746
+ quotaOverrideEnabled: this.quotaOverrideEnabled,
747
+ quotaOverrideValue: this.quotaOverrideFieldValue,
748
+ quotaOverrideError: this.quotaOverrideError,
749
+ onClear: () => this.clear(),
750
+ onToggleQuotaOverride: () => {
751
+ void this.onClickCheckbox();
752
+ },
753
+ onQuotaOverrideInput: value => {
754
+ this.quotaOverrideFieldValue = value;
755
+ },
756
+ onApplyQuotaOverride: value => {
757
+ void this.applyQuotaOverrideFromInputField(value);
758
+ },
759
+ },
760
+ this.#viewOutput, this.contentElement);
667
761
  }
668
762
 
669
763
  static getStorageTypeName(type: Protocol.Storage.StorageType): string {