chrome-devtools-frontend 1.0.1721762 → 1.0.1724140

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 (195) hide show
  1. package/docs/cookbook/dependencies.md +55 -11
  2. package/docs/get_the_code.md +15 -0
  3. package/front_end/core/i18n/collect-ui-strings.js +58 -12
  4. package/front_end/core/sdk/WebAuthnModel.ts +17 -10
  5. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  6. package/front_end/generated/protocol.ts +16 -0
  7. package/front_end/models/comment_manager/CD4ABridge.ts +4 -0
  8. package/front_end/models/comment_manager/CommentThread.ts +16 -0
  9. package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +13 -6
  10. package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +92 -0
  11. package/front_end/panels/accessibility/accessibilityAnnouncementRecordingListView.css +3 -1
  12. package/front_end/panels/accessibility/accessibilityAnnouncementRecordingView.css +12 -1
  13. package/front_end/panels/application/StorageView.ts +250 -178
  14. package/front_end/panels/application/SubAppsView.ts +159 -0
  15. package/front_end/panels/application/application.ts +2 -0
  16. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +1 -1
  17. package/front_end/panels/application/subAppsView.css +21 -0
  18. package/front_end/panels/elements/ClassesPaneWidget.ts +3 -1
  19. package/front_end/panels/elements/DOMTreeElementWidget.ts +3 -1
  20. package/front_end/panels/elements/DOMTreeWidget.ts +12 -0
  21. package/front_end/panels/elements/StyleEditorWidget.ts +29 -0
  22. package/front_end/panels/elements/StylesSidebarPane.ts +1 -0
  23. package/front_end/panels/layer_viewer/Layers3DView.ts +21 -37
  24. package/front_end/panels/network/NetworkConfigView.ts +12 -10
  25. package/front_end/panels/network/networkConfigView.css +8 -8
  26. package/front_end/panels/screencast/ScreencastView.ts +3 -6
  27. package/front_end/panels/security/SecurityPanelSidebar.ts +0 -31
  28. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +9 -16
  29. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +358 -345
  30. package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +136 -121
  31. package/front_end/panels/sources/SourcesPanel.ts +3 -1
  32. package/front_end/panels/sources/TabbedEditorContainer.ts +41 -18
  33. package/front_end/panels/sources/UISourceCodeFrame.ts +1 -1
  34. package/front_end/panels/timeline/TimelineCommentContext.ts +171 -0
  35. package/front_end/panels/timeline/TimelineCommentController.ts +36 -0
  36. package/front_end/panels/timeline/timeline.ts +2 -0
  37. package/front_end/panels/webauthn/WebauthnPane.ts +15 -13
  38. package/front_end/third_party/chromium/README.chromium +1 -1
  39. package/front_end/third_party/puppeteer/README.chromium +2 -2
  40. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +113 -3
  41. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21311 -20981
  42. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +36 -0
  43. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
  44. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js +22 -0
  45. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
  46. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
  47. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +20 -18
  48. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
  49. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts +20 -1
  50. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts.map +1 -1
  51. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +2 -2
  52. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
  53. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +40 -1
  54. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  55. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js +3 -1
  56. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  57. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts +2 -0
  58. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts.map +1 -1
  59. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js +41 -5
  60. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js.map +1 -1
  61. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts +2 -1
  62. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js +23 -2
  64. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js.map +1 -1
  65. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts +3 -2
  67. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +13 -1
  69. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts +1 -0
  71. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js +18 -11
  73. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts +2 -1
  75. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js +8 -1
  77. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +2 -1
  79. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +24 -12
  81. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +13 -7
  85. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
  86. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.d.ts.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js +5 -1
  88. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts +22 -1
  90. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js +75 -9
  92. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js.map +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts +18 -4
  94. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js +8 -4
  96. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +65 -26
  99. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +3 -2
  101. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +19 -0
  103. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js +4 -3
  106. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts +1 -0
  108. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js +4 -0
  110. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts +2 -0
  112. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js +95 -8
  114. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts +0 -8
  116. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +8 -24
  118. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts +1 -0
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts.map +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js +5 -4
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +9 -0
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.d.ts.map +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js +10 -0
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +10 -0
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +30 -5
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts +2 -0
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js +33 -3
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +1 -2
  142. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts +4 -0
  144. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +1 -0
  146. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  148. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  149. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts +2 -2
  151. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  153. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/types.d.ts +113 -3
  155. package/front_end/third_party/puppeteer/package/package.json +4 -4
  156. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +42 -0
  157. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +25 -22
  158. package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +22 -2
  159. package/front_end/third_party/puppeteer/package/src/api/Page.ts +45 -2
  160. package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +79 -32
  161. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +32 -12
  162. package/front_end/third_party/puppeteer/package/src/bidi/Input.ts +1 -1
  163. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +18 -2
  164. package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +21 -13
  165. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +12 -2
  166. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +37 -16
  167. package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +14 -11
  168. package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +7 -1
  169. package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +101 -14
  170. package/front_end/third_party/puppeteer/package/src/cdp/NetworkEventManager.ts +26 -6
  171. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +111 -29
  172. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +37 -1
  173. package/front_end/third_party/puppeteer/package/src/cdp/ScreenRecording.ts +5 -4
  174. package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +5 -0
  175. package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +122 -7
  176. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +13 -33
  177. package/front_end/third_party/puppeteer/package/src/common/BrowserWebSocketTransport.ts +10 -5
  178. package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +10 -0
  179. package/front_end/third_party/puppeteer/package/src/common/WaitTask.ts +12 -0
  180. package/front_end/third_party/puppeteer/package/src/common/util.ts +39 -5
  181. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  182. package/front_end/third_party/puppeteer/package/src/injected/Poller.ts +35 -3
  183. package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +4 -2
  184. package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +5 -0
  185. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  186. package/front_end/third_party/puppeteer/package/src/util/encoding.ts +2 -2
  187. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  188. package/front_end/ui/helpers/OpenInNewTab.ts +8 -0
  189. package/front_end/ui/legacy/LinkContextMenuProvider.ts +1 -1
  190. package/front_end/ui/legacy/ListWidget.ts +14 -18
  191. package/front_end/ui/legacy/TabbedPane.ts +46 -3
  192. package/front_end/ui/legacy/Treeoutline.ts +3 -1
  193. package/front_end/ui/legacy/UIUtils.ts +1 -1
  194. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
  195. package/package.json +1 -1
@@ -8,18 +8,21 @@ import * as i18n from '../../core/i18n/i18n.js';
8
8
  import * as Platform from '../../core/platform/platform.js';
9
9
  import * as SDK from '../../core/sdk/sdk.js';
10
10
  import * as Protocol from '../../generated/protocol.js';
11
- import type * as Buttons from '../../ui/components/buttons/buttons.js';
11
+ import * as Buttons from '../../ui/components/buttons/buttons.js';
12
12
  import * as uiI18n from '../../ui/i18n/i18n.js';
13
13
  import {Icon, Link} from '../../ui/kit/kit.js';
14
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
15
  import * as UI from '../../ui/legacy/legacy.js';
16
+ import {Directives, html, type LitTemplate, render} from '../../ui/lit/lit.js';
17
17
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
18
18
 
19
19
  import {IndexedDBModel} from './IndexedDBModel.js';
20
20
  import {ResourcesPanel} from './ResourcesPanel.js';
21
21
  import storageViewStyles from './storageView.css.js';
22
22
 
23
+ const {ref} = Directives;
24
+ const {bindToSetting} = UI.UIUtils;
25
+
23
26
  const UIStrings = {
24
27
  /**
25
28
  * @description Text in the storage view that expresses the amount of used and available storage quota.
@@ -162,34 +165,111 @@ export const storagePieColors: Map<Protocol.Storage.StorageType, string> =
162
165
  const str_ = i18n.i18n.registerUIStrings('panels/application/StorageView.ts', UIStrings);
163
166
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
164
167
 
168
+ export interface ClearSiteDataViewInput {
169
+ settings: Map<Protocol.Storage.StorageType, Common.Settings.Setting<boolean>>;
170
+ includeThirdPartyCookiesSetting: Common.Settings.Setting<boolean>;
171
+ includeThirdPartyCookiesDisabled: boolean;
172
+ clearing: boolean;
173
+ onClear: () => void;
174
+ }
175
+
176
+ export interface ClearSiteDataViewOutput {
177
+ focusClearButton?: () => void;
178
+ }
179
+
180
+ export type ClearSiteDataView = (input: ClearSiteDataViewInput, output: ClearSiteDataViewOutput, target: HTMLElement) =>
181
+ void;
182
+
183
+ export const CLEAR_SITE_DATA_DEFAULT_VIEW: ClearSiteDataView = (input, output, target) => {
184
+ function renderSettingCheckbox(title: Platform.UIString.LocalizedString, settingName: Protocol.Storage.StorageType,
185
+ className: string): LitTemplate {
186
+ const setting = input.settings.get(settingName);
187
+ if (!setting) {
188
+ throw new Error(`Missing setting for storage type: ${settingName}`);
189
+ }
190
+ return html`<devtools-checkbox class=${className} title=${title} ${bindToSetting(setting)}>${
191
+ title}</devtools-checkbox>`;
192
+ }
193
+
194
+ // clang-format off
195
+ render(html`
196
+ <div class="report-row clear-site-data-checkboxes-row">
197
+ <div class="clear-site-data-checkbox-column">
198
+ ${renderSettingCheckbox(i18nString(UIStrings.cacheStorage), Protocol.Storage.StorageType.Cache_storage, 'cache-storage-checkbox')}
199
+ ${renderSettingCheckbox(i18nString(UIStrings.fileSystem), Protocol.Storage.StorageType.File_systems, 'file-systems-checkbox')}
200
+ ${renderSettingCheckbox(i18nString(UIStrings.indexDB), Protocol.Storage.StorageType.Indexeddb, 'indexeddb-checkbox')}
201
+ ${renderSettingCheckbox(i18nString(UIStrings.localAndSessionStorage), Protocol.Storage.StorageType.Local_storage, 'local-and-session-storage-checkbox')}
202
+ </div>
203
+ <div class="clear-site-data-checkbox-column">
204
+ ${renderSettingCheckbox(i18nString(UIStrings.unregisterServiceWorker), Protocol.Storage.StorageType.Service_workers, 'unregister-service-worker-checkbox')}
205
+ ${renderSettingCheckbox(i18nString(UIStrings.cookies), Protocol.Storage.StorageType.Cookies, 'cookies-checkbox cookies-row')}
206
+ <div class="include-third-party-cookies-row">
207
+ <devtools-checkbox class="third-party-cookies-checkbox"
208
+ title=${i18nString(UIStrings.thirdPartyCookies)}
209
+ ?disabled=${input.includeThirdPartyCookiesDisabled}
210
+ ${bindToSetting(input.includeThirdPartyCookiesSetting)}>
211
+ ${i18nString(UIStrings.thirdPartyCookies)}
212
+ </devtools-checkbox>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ <div class="report-row clear-selected-button-row">
217
+ <devtools-button id="storage-view-clear-button"
218
+ .variant=${Buttons.Button.Variant.OUTLINED}
219
+ .disabled=${input.clearing}
220
+ .jslogContext=${'storage.clear-site-data'}
221
+ @click=${input.onClear}
222
+ ${ref(e => {
223
+ output.focusClearButton = e instanceof HTMLElement ? () => e.focus() : undefined;
224
+ })}
225
+ >${input.clearing ? i18nString(UIStrings.clearing) : i18nString(UIStrings.clearSelected)}</devtools-button>
226
+ </div>`, target);
227
+ // clang-format on
228
+ };
229
+
165
230
  /**
166
231
  * @implements {SDK.TargetManager.Observer}
167
232
  */
168
233
  export class StorageView extends UI.Widget.VBox {
169
234
  private pieColors: Map<Protocol.Storage.StorageType, string>;
170
235
  private reportView: UI.ReportView.ReportView;
171
- private target: SDK.Target.Target|null;
172
- private securityOrigin: string|null;
173
- private storageKey: string|null;
236
+ private target: SDK.Target.Target|null = null;
237
+ private securityOrigin: string|null = null;
238
+ private storageKey: string|null = null;
239
+ private subtitle: string|null = null;
174
240
  private settings: Map<Protocol.Storage.StorageType, Common.Settings.Setting<boolean>>;
175
241
  private includeThirdPartyCookiesSetting: Common.Settings.Setting<boolean>;
176
- private includeThirdPartyCookiesCheckbox: UI.UIUtils.CheckboxLabel;
242
+ private readonly clearSiteDataView: ClearSiteDataView;
243
+ private readonly clearSiteDataViewOutput: ClearSiteDataViewOutput = {};
244
+ private readonly clearSiteDataFieldList: HTMLElement;
177
245
  private quotaRow: HTMLElement;
178
- private quotaUsage: number|null;
179
- private quotaQuota: number|null;
180
- private quotaOverrideActive: boolean|null;
246
+ private quotaUsage: number|null = null;
247
+ private quotaQuota: number|null = null;
248
+ private quotaOverrideActive: boolean|null = null;
249
+ private pieChartSlices: PerfUI.PieChart.Slice[] = [];
181
250
  private pieChart: PerfUI.PieChart.PieChart;
182
- private previousOverrideFieldValue: string;
251
+ private previousOverrideFieldValue = '';
252
+ private quotaOverrideEnabled = false;
253
+ private quotaOverrideError = '';
183
254
  private quotaOverrideCheckbox: UI.UIUtils.CheckboxLabel;
184
255
  private quotaOverrideControlRow: HTMLElement;
185
256
  private quotaOverrideEditor: HTMLInputElement;
186
257
  private quotaOverrideErrorMessage: HTMLElement;
187
- private clearButton: Buttons.Button.Button;
258
+ private clearing = false;
259
+ private clearTimerId?: number;
188
260
  private readonly throttler = new Common.Throttler.Throttler(1000);
189
-
190
- constructor() {
261
+ private readonly boundOnCookiesSettingChanged = (event: Common.EventTarget.EventTargetEvent<boolean>): void => {
262
+ this.onCookiesSettingChanged(event.data);
263
+ };
264
+ private readonly boundOnIncludeThirdPartyCookiesSettingChanged =
265
+ (event: Common.EventTarget.EventTargetEvent<boolean>): void => {
266
+ this.onIncludeThirdPartyCookiesSettingChanged(event.data);
267
+ };
268
+
269
+ constructor(clearSiteDataView: ClearSiteDataView = CLEAR_SITE_DATA_DEFAULT_VIEW) {
191
270
  super({useShadowDom: true});
192
271
  this.registerRequiredCSS(storageViewStyles);
272
+ this.clearSiteDataView = clearSiteDataView;
193
273
 
194
274
  this.contentElement.classList.add('clear-storage-container');
195
275
  this.contentElement.setAttribute('jslog', `${VisualLogging.pane('clear-storage')}`);
@@ -201,9 +281,6 @@ export class StorageView extends UI.Widget.VBox {
201
281
 
202
282
  this.reportView.element.classList.add('clear-storage-header');
203
283
  this.reportView.show(this.contentElement);
204
- this.target = null;
205
- this.securityOrigin = null;
206
- this.storageKey = null;
207
284
 
208
285
  this.settings = new Map();
209
286
  for (const type of AllStorageTypes) {
@@ -218,60 +295,9 @@ export class StorageView extends UI.Widget.VBox {
218
295
 
219
296
  const clearSiteData = this.reportView.appendSection(i18nString(UIStrings.clearSiteData));
220
297
  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
-
298
+ this.clearSiteDataFieldList = clearSiteData.getFieldElement();
254
299
  clearSiteData.markFieldListAsGroup();
255
300
 
256
- 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
- this.onCookiesSettingChanged(Boolean(cookiesSetting?.get()));
274
-
275
301
  const quota = this.reportView.appendSection(i18nString(UIStrings.usage));
276
302
  quota.element.setAttribute('jslog', `${VisualLogging.section('usage')}`);
277
303
  this.quotaRow = quota.appendSelectableRow();
@@ -282,17 +308,12 @@ export class StorageView extends UI.Widget.VBox {
282
308
  'https://developer.chrome.com/docs/devtools/progressive-web-apps#opaque-responses',
283
309
  i18nString(UIStrings.learnMore), undefined, 'learn-more');
284
310
  learnMoreRow.appendChild(learnMore);
285
- this.quotaUsage = null;
286
- this.quotaQuota = null;
287
- this.quotaOverrideActive = null;
288
311
  this.pieChart = new PerfUI.PieChart.PieChart();
289
- this.populatePieChart(0, []);
290
312
  const usageBreakdownRow = quota.appendRow();
291
313
  usageBreakdownRow.classList.add('usage-breakdown-row');
292
314
  usageBreakdownRow.setAttribute('jslog', `${VisualLogging.item('usage-breakdown')}`);
293
315
  usageBreakdownRow.appendChild(this.pieChart);
294
316
 
295
- this.previousOverrideFieldValue = '';
296
317
  const quotaOverrideCheckboxRow = quota.appendRow();
297
318
  quotaOverrideCheckboxRow.classList.add('quota-override-row');
298
319
  this.quotaOverrideCheckbox = UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.simulateCustomStorage), false);
@@ -306,7 +327,6 @@ export class StorageView extends UI.Widget.VBox {
306
327
  this.quotaOverrideEditor.setAttribute(
307
328
  'jslog', `${VisualLogging.textField('quota-override').track({change: true})}`);
308
329
  this.quotaOverrideControlRow.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.mb)));
309
- this.quotaOverrideControlRow.classList.add('hidden');
310
330
  this.quotaOverrideEditor.addEventListener('keyup', event => {
311
331
  if (event.key === 'Enter') {
312
332
  void this.applyQuotaOverrideFromInputField();
@@ -321,51 +341,28 @@ export class StorageView extends UI.Widget.VBox {
321
341
  const errorMessageRow = quota.appendRow();
322
342
  this.quotaOverrideErrorMessage = errorMessageRow.createChild('div', 'quota-override-error');
323
343
 
344
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
345
+ this.onCookiesSettingChanged(Boolean(cookiesSetting?.get()));
324
346
  SDK.TargetManager.TargetManager.instance().observeTargets(this);
325
347
  }
326
348
 
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
349
  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
- }
350
+ // Unchecking general cookies clearing must also uncheck third-party cookies.
351
+ if (!cookiesEnabled && this.includeThirdPartyCookiesSetting.get()) {
352
+ this.includeThirdPartyCookiesSetting.set(false);
353
+ return;
349
354
  }
350
- this.updateThirdPartyCookiesCheckboxState();
355
+ this.requestUpdate();
351
356
  }
352
357
 
353
358
  private onIncludeThirdPartyCookiesSettingChanged(includeThirdPartyCookiesEnabled: boolean): void {
354
359
  const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
360
+ // Checking third-party cookies requires general cookies clearing to be enabled.
355
361
  if (includeThirdPartyCookiesEnabled && cookiesSetting && !cookiesSetting.get()) {
356
362
  cookiesSetting.set(true);
357
363
  return;
358
364
  }
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();
365
+ this.requestUpdate();
369
366
  }
370
367
 
371
368
  targetAdded(target: SDK.Target.Target): void {
@@ -400,6 +397,25 @@ export class StorageView extends UI.Widget.VBox {
400
397
  SDK.StorageKeyManager.Events.MAIN_STORAGE_KEY_CHANGED, this.storageKeyChanged, this);
401
398
  }
402
399
 
400
+ override willHide(): void {
401
+ super.willHide();
402
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
403
+ cookiesSetting?.removeChangeListener(this.boundOnCookiesSettingChanged);
404
+ this.includeThirdPartyCookiesSetting.removeChangeListener(this.boundOnIncludeThirdPartyCookiesSettingChanged);
405
+ }
406
+
407
+ override wasHidden(): void {
408
+ super.wasHidden();
409
+ if (this.clearTimerId !== undefined) {
410
+ window.clearTimeout(this.clearTimerId);
411
+ this.clearTimerId = undefined;
412
+ }
413
+ if (this.clearing) {
414
+ this.clearing = false;
415
+ this.requestUpdate();
416
+ }
417
+ }
418
+
403
419
  private originChanged(
404
420
  event: Common.EventTarget.EventTargetEvent<SDK.SecurityOriginManager.MainSecurityOriginChangedEvent>): void {
405
421
  const {mainSecurityOrigin, unreachableMainSecurityOrigin} = event.data;
@@ -416,43 +432,45 @@ export class StorageView extends UI.Widget.VBox {
416
432
  const oldOrigin = this.securityOrigin;
417
433
  if (unreachableMainOrigin) {
418
434
  this.securityOrigin = unreachableMainOrigin;
419
- this.reportView.setSubtitle(i18nString(UIStrings.sFailedToLoad, {PH1: unreachableMainOrigin}));
435
+ this.subtitle = i18nString(UIStrings.sFailedToLoad, {PH1: unreachableMainOrigin});
420
436
  } else {
421
437
  this.securityOrigin = mainOrigin;
422
- this.reportView.setSubtitle(mainOrigin);
438
+ this.subtitle = mainOrigin;
423
439
  }
424
440
 
425
441
  if (oldOrigin !== this.securityOrigin) {
426
- this.quotaOverrideControlRow.classList.add('hidden');
427
- this.quotaOverrideCheckbox.checked = false;
428
- this.quotaOverrideErrorMessage.textContent = '';
442
+ this.quotaOverrideEnabled = false;
443
+ this.quotaOverrideError = '';
429
444
  this.quotaUsage = null;
430
445
  this.quotaQuota = null;
431
446
  this.quotaOverrideActive = null;
447
+ this.pieChartSlices = [];
432
448
  }
433
- void this.performUpdate();
449
+ this.requestUpdate();
450
+ void this.refreshUsageAndQuota();
434
451
  }
435
452
 
436
453
  private updateStorageKey(mainStorageKey: string): void {
437
454
  const oldStorageKey = this.storageKey;
438
455
 
439
456
  this.storageKey = mainStorageKey;
440
- this.reportView.setSubtitle(mainStorageKey);
457
+ this.subtitle = mainStorageKey;
441
458
 
442
459
  if (oldStorageKey !== this.storageKey) {
443
- this.quotaOverrideControlRow.classList.add('hidden');
444
- this.quotaOverrideCheckbox.checked = false;
445
- this.quotaOverrideErrorMessage.textContent = '';
460
+ this.quotaOverrideEnabled = false;
461
+ this.quotaOverrideError = '';
446
462
  }
447
- void this.performUpdate();
463
+ this.requestUpdate();
448
464
  }
449
465
 
450
466
  private async applyQuotaOverrideFromInputField(): Promise<void> {
451
467
  if (!this.target || !this.securityOrigin) {
452
- this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.internalError);
468
+ this.quotaOverrideError = i18nString(UIStrings.internalError);
469
+ this.requestUpdate();
453
470
  return;
454
471
  }
455
- this.quotaOverrideErrorMessage.textContent = '';
472
+ this.quotaOverrideError = '';
473
+ this.requestUpdate();
456
474
  const editorString = this.quotaOverrideEditor.value;
457
475
  if (editorString === '') {
458
476
  await this.clearQuotaForOrigin(this.target, this.securityOrigin);
@@ -461,17 +479,19 @@ export class StorageView extends UI.Widget.VBox {
461
479
  }
462
480
  const quota = parseFloat(editorString);
463
481
  if (!Number.isFinite(quota)) {
464
- this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.pleaseEnterANumber);
482
+ this.quotaOverrideError = i18nString(UIStrings.pleaseEnterANumber);
483
+ this.requestUpdate();
465
484
  return;
466
485
  }
467
486
  if (quota < 0) {
468
- this.quotaOverrideErrorMessage.textContent = i18nString(UIStrings.numberMustBeNonNegative);
487
+ this.quotaOverrideError = i18nString(UIStrings.numberMustBeNonNegative);
488
+ this.requestUpdate();
469
489
  return;
470
490
  }
471
491
  const cutoff = 9_000_000_000_000;
472
492
  if (quota >= cutoff) {
473
- this.quotaOverrideErrorMessage.textContent =
474
- i18nString(UIStrings.numberMustBeSmaller, {PH1: cutoff.toLocaleString()});
493
+ this.quotaOverrideError = i18nString(UIStrings.numberMustBeSmaller, {PH1: cutoff.toLocaleString()});
494
+ this.requestUpdate();
475
495
  return;
476
496
  }
477
497
  const bytesPerMB = 1000 * 1000;
@@ -488,16 +508,19 @@ export class StorageView extends UI.Widget.VBox {
488
508
  }
489
509
 
490
510
  private async onClickCheckbox(): Promise<void> {
491
- if (this.quotaOverrideControlRow.classList.contains('hidden')) {
492
- this.quotaOverrideControlRow.classList.remove('hidden');
493
- this.quotaOverrideCheckbox.checked = true;
511
+ if (!this.quotaOverrideEnabled) {
512
+ this.quotaOverrideEnabled = true;
494
513
  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 = '';
514
+ this.requestUpdate();
515
+ await this.updateComplete;
516
+ this.quotaOverrideEditor.focus();
517
+ } else {
518
+ this.quotaOverrideEnabled = false;
519
+ this.quotaOverrideError = '';
520
+ this.requestUpdate();
521
+ if (this.target && this.securityOrigin) {
522
+ await this.clearQuotaForOrigin(this.target, this.securityOrigin);
523
+ }
501
524
  }
502
525
  }
503
526
 
@@ -519,13 +542,17 @@ export class StorageView extends UI.Widget.VBox {
519
542
  this.target, this.storageKey, this.securityOrigin, selectedStorageTypes, includeThirdPartyCookies);
520
543
  }
521
544
 
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();
545
+ this.clearing = true;
546
+ this.requestUpdate();
547
+ window.clearTimeout(this.clearTimerId);
548
+ this.clearTimerId = window.setTimeout(async () => {
549
+ this.clearTimerId = undefined;
550
+ this.clearing = false;
551
+ this.requestUpdate();
552
+ await this.updateComplete;
553
+ if (this.isShowing()) {
554
+ this.clearSiteDataViewOutput.focusClearButton?.();
555
+ }
529
556
  }, 500);
530
557
 
531
558
  UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.SiteDataCleared));
@@ -578,24 +605,33 @@ export class StorageView extends UI.Widget.VBox {
578
605
  }
579
606
  }
580
607
 
581
- override async performUpdate(): Promise<void> {
608
+ private async refreshUsageAndQuota(): Promise<void> {
609
+ if (!this.isShowing()) {
610
+ return;
611
+ }
582
612
  if (!this.securityOrigin || !this.target) {
583
- this.quotaRow.textContent = '';
584
613
  this.quotaUsage = null;
585
614
  this.quotaQuota = null;
586
615
  this.quotaOverrideActive = null;
587
- this.populatePieChart(0, []);
616
+ this.pieChartSlices = [];
617
+ this.requestUpdate();
588
618
  return;
589
619
  }
590
620
 
591
621
  const securityOrigin = this.securityOrigin;
592
622
  const response = await this.target.storageAgent().invoke_getUsageAndQuota({origin: securityOrigin});
623
+ if (this.securityOrigin !== securityOrigin) {
624
+ return;
625
+ }
593
626
  if (response.getError()) {
594
- this.quotaRow.textContent = '';
595
627
  this.quotaUsage = null;
596
628
  this.quotaQuota = null;
597
629
  this.quotaOverrideActive = null;
598
- this.populatePieChart(0, []);
630
+ this.pieChartSlices = [];
631
+ this.requestUpdate();
632
+ if (this.isShowing()) {
633
+ void this.throttler.schedule(() => this.refreshUsageAndQuota());
634
+ }
599
635
  return;
600
636
  }
601
637
 
@@ -608,35 +644,6 @@ export class StorageView extends UI.Widget.VBox {
608
644
  this.quotaQuota = response.quota;
609
645
  this.quotaOverrideActive = response.overrideActive;
610
646
 
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
647
  if (usageChanged) {
641
648
  const slices: PerfUI.PieChart.Slice[] = [];
642
649
  for (const usageForType of response.usageBreakdown.sort((a, b) => b.usage - a.usage)) {
@@ -648,21 +655,86 @@ export class StorageView extends UI.Widget.VBox {
648
655
  const color = this.pieColors.get(usageForType.storageType) || '#ccc';
649
656
  slices.push({value, color, title});
650
657
  }
651
- this.populatePieChart(response.usage, slices);
658
+ this.pieChartSlices = slices;
652
659
  }
660
+ this.requestUpdate();
653
661
  }
654
662
 
655
- void this.throttler.schedule(this.requestUpdate.bind(this));
663
+ if (this.isShowing()) {
664
+ void this.throttler.schedule(() => this.refreshUsageAndQuota());
665
+ }
666
+ }
667
+
668
+ override wasShown(): void {
669
+ super.wasShown();
670
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
671
+ cookiesSetting?.addChangeListener(this.boundOnCookiesSettingChanged);
672
+ this.includeThirdPartyCookiesSetting.addChangeListener(this.boundOnIncludeThirdPartyCookiesSettingChanged);
673
+ this.onCookiesSettingChanged(Boolean(cookiesSetting?.get()));
674
+ void this.refreshUsageAndQuota();
675
+ }
676
+
677
+ override performUpdate(): void {
678
+ if (this.subtitle !== null) {
679
+ this.reportView.setSubtitle(this.subtitle);
680
+ }
681
+ const cookiesSetting = this.settings.get(Protocol.Storage.StorageType.Cookies);
682
+ this.clearSiteDataView({
683
+ settings: this.settings,
684
+ includeThirdPartyCookiesSetting: this.includeThirdPartyCookiesSetting,
685
+ includeThirdPartyCookiesDisabled: !cookiesSetting?.get(),
686
+ clearing: this.clearing,
687
+ onClear: () => this.clear(),
688
+ },
689
+ this.clearSiteDataViewOutput, this.clearSiteDataFieldList);
690
+ this.renderQuotaRow();
691
+ this.populatePieChart();
692
+ this.quotaOverrideControlRow.classList.toggle('hidden', !this.quotaOverrideEnabled);
693
+ this.quotaOverrideCheckbox.checked = this.quotaOverrideEnabled;
694
+ this.quotaOverrideErrorMessage.textContent = this.quotaOverrideError;
695
+ }
696
+
697
+ private renderQuotaRow(): void {
698
+ this.quotaRow.textContent = '';
699
+ if (this.quotaUsage === null || this.quotaQuota === null) {
700
+ return;
701
+ }
702
+ const quotaAsString = i18n.ByteUtilities.bytesToString(this.quotaQuota);
703
+ const usageAsString = i18n.ByteUtilities.bytesToString(this.quotaUsage);
704
+ const formattedQuotaAsString = i18nString(UIStrings.storageWithCustomMarker, {PH1: quotaAsString});
705
+
706
+ let quota: string|HTMLElement = quotaAsString;
707
+ if (this.quotaOverrideActive) {
708
+ const element = document.createElement('b');
709
+ element.textContent = formattedQuotaAsString;
710
+ quota = element;
711
+ }
712
+
713
+ const element = uiI18n.getFormatLocalizedString(str_, UIStrings.storageQuotaUsed, {PH1: usageAsString, PH2: quota});
714
+ this.quotaRow.appendChild(element);
715
+ UI.Tooltip.Tooltip.install(
716
+ this.quotaRow,
717
+ i18nString(UIStrings.storageQuotaUsedWithBytes,
718
+ {PH1: this.quotaUsage.toLocaleString(), PH2: this.quotaQuota.toLocaleString()}));
719
+
720
+ if (!this.quotaOverrideActive && this.quotaQuota < 125829120) { // 120 MiB
721
+ const icon = new Icon();
722
+ icon.name = 'info';
723
+ icon.style.color = 'var(--icon-info)';
724
+ icon.classList.add('small');
725
+ UI.Tooltip.Tooltip.install(icon, i18nString(UIStrings.storageQuotaIsLimitedIn));
726
+ this.quotaRow.appendChild(icon);
727
+ }
656
728
  }
657
729
 
658
- private populatePieChart(total: number, slices: PerfUI.PieChart.Slice[]): void {
730
+ private populatePieChart(): void {
659
731
  this.pieChart.data = {
660
732
  chartName: i18nString(UIStrings.storageUsage),
661
733
  size: 110,
662
734
  formatter: i18n.ByteUtilities.bytesToString,
663
735
  showLegend: true,
664
- total,
665
- slices,
736
+ total: this.quotaUsage ?? 0,
737
+ slices: this.pieChartSlices,
666
738
  };
667
739
  }
668
740