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
@@ -0,0 +1,159 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import '../../ui/kit/kit.js';
6
+ import '../../ui/legacy/components/data_grid/data_grid.js';
7
+
8
+ import * as i18n from '../../core/i18n/i18n.js';
9
+ import * as UI from '../../ui/legacy/legacy.js';
10
+ import * as Lit from '../../ui/lit/lit.js';
11
+ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
12
+
13
+ import subAppsViewStyles from './subAppsView.css.js';
14
+
15
+ const {html} = Lit;
16
+
17
+ const UIStrings = {
18
+ /**
19
+ * @description Heading label for Sub Apps view
20
+ */
21
+ subApps: 'Sub Apps',
22
+ /**
23
+ * @description Heading label for Sibling Sub Apps view
24
+ */
25
+ siblingSubApps: 'Sibling Sub Apps',
26
+ /**
27
+ * @description Column header for the sub-app name
28
+ */
29
+ name: 'Name',
30
+ /**
31
+ * @description Column header for the sub-app scope
32
+ */
33
+ scope: 'Scope',
34
+ /**
35
+ * @description Column header when Manifest ID and Start URL are identical across all sub-apps
36
+ */
37
+ manifestIdAndStartUrl: 'Manifest ID / Start URL',
38
+ /**
39
+ * @description Column header for Manifest ID
40
+ */
41
+ manifestId: 'Manifest ID',
42
+ /**
43
+ * @description Column header for Start URL
44
+ */
45
+ startUrl: 'Start URL',
46
+ } as const;
47
+
48
+ const str_ = i18n.i18n.registerUIStrings('panels/application/SubAppsView.ts', UIStrings);
49
+ export const i18nString: i18n.LocalizeString = i18n.i18n.getLocalizedString.bind(undefined, str_);
50
+
51
+ export interface SubAppEntry {
52
+ name: string;
53
+ scope: string;
54
+ manifestId: string;
55
+ startUrl: string;
56
+ }
57
+
58
+ export interface SubAppsViewInput {
59
+ subApps: SubAppEntry[];
60
+ isSiblingSubApps?: boolean;
61
+ }
62
+
63
+ /**
64
+ * Sub apps always share the parent app's origin, so, like the manifest's
65
+ * Start URL field, only the path (plus any query or fragment) is shown. The
66
+ * full URL is kept in the cell's tooltip. Falls back to the original string if
67
+ * it is not a valid absolute URL.
68
+ */
69
+ function stripOrigin(url: string): string {
70
+ try {
71
+ const parsed = new URL(url);
72
+ return parsed.pathname + parsed.search + parsed.hash;
73
+ } catch {
74
+ return url;
75
+ }
76
+ }
77
+
78
+ type View = (input: SubAppsViewInput, output: undefined, target: HTMLElement) => void;
79
+
80
+ export const DEFAULT_VIEW: View = (input, output, target) => {
81
+ const hasDistinctManifestId =
82
+ input.subApps.some(subApp => subApp.manifestId && subApp.startUrl && subApp.manifestId !== subApp.startUrl);
83
+ const headingText = input.isSiblingSubApps ? i18nString(UIStrings.siblingSubApps) : i18nString(UIStrings.subApps);
84
+
85
+ // clang-format off
86
+ Lit.render(html`
87
+ <style>${subAppsViewStyles}</style>
88
+ <style>${UI.inspectorCommonStyles}</style>
89
+ <div jslog=${VisualLogging.pane('sub-apps')}>
90
+ <span class="heading">${headingText}</span>
91
+ <devtools-data-grid striped inline role="grid" aria-label=${headingText}>
92
+ <table>
93
+ <tr>
94
+ <th id="name" weight="10" sortable>${i18nString(UIStrings.name)}</th>
95
+ <th id="scope" weight="10" sortable>${i18nString(UIStrings.scope)}</th>
96
+ ${hasDistinctManifestId ? html`
97
+ <th id="manifest-id" weight="10" sortable>${i18nString(UIStrings.manifestId)}</th>
98
+ <th id="start-url" weight="10" sortable>${i18nString(UIStrings.startUrl)}</th>
99
+ ` : html`
100
+ <th id="manifest-id-start-url" weight="10" sortable>${i18nString(UIStrings.manifestIdAndStartUrl)}</th>
101
+ `}
102
+ </tr>
103
+ ${input.subApps.map(subApp => html`
104
+ <tr>
105
+ <td>${subApp.name}</td>
106
+ <td title=${subApp.scope}>${stripOrigin(subApp.scope)}</td>
107
+ ${hasDistinctManifestId ? html`
108
+ <td title=${subApp.manifestId}>${stripOrigin(subApp.manifestId)}</td>
109
+ <td title=${subApp.startUrl}>${stripOrigin(subApp.startUrl)}</td>
110
+ ` : html`
111
+ <td title=${subApp.manifestId || subApp.startUrl}>${stripOrigin(subApp.manifestId || subApp.startUrl)}</td>
112
+ `}
113
+ </tr>
114
+ `)}
115
+ </table>
116
+ </devtools-data-grid>
117
+ </div>
118
+ `, target);
119
+ // clang-format on
120
+ };
121
+
122
+ export class SubAppsView extends UI.Widget.VBox {
123
+ #subApps: SubAppEntry[] = [];
124
+ #isSiblingSubApps = false;
125
+ #view: View;
126
+
127
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
128
+ super(element);
129
+ this.#view = view;
130
+ }
131
+
132
+ get subApps(): SubAppEntry[] {
133
+ return this.#subApps;
134
+ }
135
+
136
+ set subApps(subApps: SubAppEntry[]) {
137
+ if (subApps === this.#subApps) {
138
+ return;
139
+ }
140
+ this.#subApps = subApps;
141
+ this.requestUpdate();
142
+ }
143
+
144
+ get isSiblingSubApps(): boolean {
145
+ return this.#isSiblingSubApps;
146
+ }
147
+
148
+ set isSiblingSubApps(isSiblingSubApps: boolean) {
149
+ if (isSiblingSubApps === this.#isSiblingSubApps) {
150
+ return;
151
+ }
152
+ this.#isSiblingSubApps = isSiblingSubApps;
153
+ this.requestUpdate();
154
+ }
155
+
156
+ override async performUpdate(): Promise<void> {
157
+ this.#view({subApps: this.#subApps, isSiblingSubApps: this.#isSiblingSubApps}, undefined, this.contentElement);
158
+ }
159
+ }
@@ -34,6 +34,7 @@ import * as ServiceWorkerUpdateCycleView from './ServiceWorkerUpdateCycleView.js
34
34
  import * as StorageBucketsTreeElement from './StorageBucketsTreeElement.js';
35
35
  import * as StorageItemsToolbar from './StorageItemsToolbar.js';
36
36
  import * as StorageView from './StorageView.js';
37
+ import * as SubAppsView from './SubAppsView.js';
37
38
  import * as TrustTokensTreeElement from './TrustTokensTreeElement.js';
38
39
  import * as WebMCPTreeElement from './WebMCPTreeElement.js';
39
40
  import * as WebMCPView from './WebMCPView.js';
@@ -72,6 +73,7 @@ export {
72
73
  StorageBucketsTreeElement,
73
74
  StorageItemsToolbar,
74
75
  StorageView,
76
+ SubAppsView,
75
77
  TrustTokensTreeElement,
76
78
  WebMCPTreeElement,
77
79
  WebMCPView,
@@ -138,7 +138,7 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
138
138
  str_, valueId,
139
139
  Object.fromEntries(Object.entries(placeholders).map(
140
140
  ([key, {title, href}]) =>
141
- [key, html`<devtools-link href=${href}>${title}</devtools-link>`])));
141
+ [key, html`<devtools-link href=${href} allow-privileged>${title}</devtools-link>`])));
142
142
  return html`
143
143
  <div class="key">${key}</div>
144
144
  <div class="value">${value}</div>
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright 2026 The Chromium Authors
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ @scope to (devtools-widget > *) {
8
+ :scope {
9
+ padding: var(--sys-size-9);
10
+ height: 100%;
11
+ display: flex;
12
+ }
13
+
14
+ .heading {
15
+ font-size: 15px;
16
+ }
17
+
18
+ devtools-data-grid {
19
+ margin-top: var(--sys-size-9);
20
+ }
21
+ }
@@ -77,7 +77,9 @@ export class ClassesPaneWidget extends UI.Widget.Widget {
77
77
  }
78
78
 
79
79
  private splitTextIntoClasses(text: string): string[] {
80
- return text.split(/[,\s]/).map(className => className.trim()).filter(className => className.length);
80
+ return text.split(/[,\s]/)
81
+ .map(className => className.trim().replace(/^\./, ''))
82
+ .filter(className => className.length);
81
83
  }
82
84
 
83
85
  private onKeyDown(event: KeyboardEvent): void {
@@ -701,7 +701,9 @@ function renderLinkifiedValue(value: string, node: SDK.DOMModel.DOMNode): Lit.Te
701
701
  if (value.startsWith('data:')) {
702
702
  value = Platform.StringUtilities.trimMiddle(value, 60);
703
703
  }
704
- const isAnchor = node && node.nodeName().toLowerCase() === 'a';
704
+ // Page-authored hrefs must not open privileged URLs (e.g. `devtools://` or `chrome://`) on click. Anchors with
705
+ // other schemes fall through to the Linkifier, which renders privileged URLs as inert text.
706
+ const isAnchor = node && node.nodeName().toLowerCase() === 'a' && Common.ParsedURL.hasWebSafeScheme(rewrittenHref);
705
707
  if (isAnchor) {
706
708
  return html`<devtools-link class="devtools-link image-url" href=${rewrittenHref} ${ref(el => {
707
709
  if (el) {
@@ -690,6 +690,16 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
690
690
  input.onContextMenu(node, event);
691
691
  };
692
692
 
693
+ // Prevent the native word selection on double click. The double click
694
+ // starts inline editing instead. Inside an active inline editor the
695
+ // native selection must stay enabled.
696
+ const onMouseDown = (event: MouseEvent): void => {
697
+ if (event.detail < 2 || UI.UIUtils.isBeingEdited(event.target as Node)) {
698
+ return;
699
+ }
700
+ event.preventDefault();
701
+ };
702
+
693
703
  const onDragStart = (event: DragEvent): void => {
694
704
  event.stopPropagation();
695
705
  const currentTarget = event.currentTarget as HTMLElement | null;
@@ -733,6 +743,7 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
733
743
  @select=${on((event: UI.TreeOutline.TreeViewElement.SelectEvent) => onSelect(false, Boolean(event.detail?.selectedByUser)))}
734
744
  @expand=${on(onExpand)}
735
745
  @mousemove=${on(onMouseMove(/* isClosingTag= */ false))}
746
+ @mousedown=${on(onMouseDown)}
736
747
  @contextmenu=${on(onContextMenu)}
737
748
  @dragstart=${on(onDragStart)}
738
749
  @dragover=${on(onDragOver(/* isClosingTag= */ false))}
@@ -816,6 +827,7 @@ export const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target:
816
827
  @select=${on((event: UI.TreeOutline.TreeViewElement.SelectEvent) => onSelect(true, Boolean(event.detail?.selectedByUser)))}
817
828
  @contextmenu=${on(onContextMenu)}
818
829
  @mousemove=${on(onMouseMove(/* isClosingTag= */ true))}
830
+ @mousedown=${on(onMouseDown)}
819
831
  @dragstart=${on(onDragStart)}
820
832
  @dragover=${on(onDragOver(/* isClosingTag= */ true))}
821
833
  @dragleave=${on(onDragLeave)}
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
5
 
6
+ import * as Elements from '../../models/elements/elements.js';
6
7
  import {createIcon} from '../../ui/kit/kit.js';
7
8
  import * as UI from '../../ui/legacy/legacy.js';
8
9
 
@@ -34,6 +35,7 @@ export class StyleEditorWidget extends UI.Widget.VBox {
34
35
  private editorContainer: HTMLElement;
35
36
 
36
37
  #triggerKey: string|undefined;
38
+ #initialProperties: Map<string, string>|null = null;
37
39
 
38
40
  constructor() {
39
41
  super({useShadowDom: true});
@@ -72,6 +74,10 @@ export class StyleEditorWidget extends UI.Widget.VBox {
72
74
  bindContext(stylesContainer: StylesContainer, section: StylePropertiesSection): void {
73
75
  this.stylesContainer = stylesContainer;
74
76
  this.section = section;
77
+ if (!this.#initialProperties) {
78
+ this.#initialProperties =
79
+ this.editor ? getAuthoredStyles(section, this.editor.getEditableProperties()) : new Map();
80
+ }
75
81
  this.editor?.addEventListener('propertyselected', this.onPropertySelected);
76
82
  this.editor?.addEventListener('propertydeselected', this.onPropertyDeselected);
77
83
  }
@@ -91,6 +97,28 @@ export class StyleEditorWidget extends UI.Widget.VBox {
91
97
  this.editor?.removeEventListener('propertydeselected', this.onPropertyDeselected);
92
98
  }
93
99
 
100
+ #trackChanges(): void {
101
+ const initialProperties = this.#initialProperties;
102
+ this.#initialProperties = null;
103
+ if (!this.editor || !this.section || !this.stylesContainer || !initialProperties) {
104
+ return;
105
+ }
106
+ const finalProperties = getAuthoredStyles(this.section, this.editor.getEditableProperties());
107
+ const node = this.stylesContainer.node() ?? this.section.matchedStyles.node();
108
+ const ruleHeader = this.section.headerText();
109
+ for (const {propertyName} of this.editor.getEditableProperties()) {
110
+ const oldValue = initialProperties.get(propertyName) ?? '';
111
+ const newValue = finalProperties.get(propertyName) ?? '';
112
+ Elements.StyleChanges.trackStylePropertyEdit(this.stylesContainer.changeTracker, node, {
113
+ ruleHeader,
114
+ oldName: oldValue ? propertyName : '',
115
+ oldValue,
116
+ newName: newValue ? propertyName : '',
117
+ newValue,
118
+ });
119
+ }
120
+ }
121
+
94
122
  async render(): Promise<void> {
95
123
  if (!this.editor) {
96
124
  return;
@@ -146,6 +174,7 @@ export class StyleEditorWidget extends UI.Widget.VBox {
146
174
  const onStylesUpdateCompleted = widget.requestUpdate.bind(widget);
147
175
  stylesContainer.addStyleUpdateListener(onStylesUpdateCompleted);
148
176
  popoverHelper.show(widget, triggerButton, () => {
177
+ widget.#trackChanges();
149
178
  widget.unbindContext();
150
179
  if (scrollerElement) {
151
180
  scrollerElement.removeEventListener('scroll', onScroll);
@@ -1834,6 +1834,7 @@ export class StylesSidebarPane extends StylesSidebarPaneBase implements StylesCo
1834
1834
  }
1835
1835
 
1836
1836
  #cleanupAiCodeCompletion(): void {
1837
+ this.#aiCodeCompletionSummaryToolbar?.detach();
1837
1838
  this.#aiCodeCompletionSummaryToolbarContainer?.remove();
1838
1839
  this.#aiCodeCompletionSummaryToolbarContainer = undefined;
1839
1840
  this.#aiCodeCompletionSummaryToolbar = undefined;
@@ -168,11 +168,11 @@ export class Layers3DView extends Layers3DViewBase
168
168
  private whiteTexture?: WebGLTexture|null;
169
169
  private gl?: WebGLRenderingContext|null;
170
170
  private dimensionsForAutoscale?: {width: number, height: number};
171
- private needsUpdate?: boolean;
172
171
  private updateScheduled?: boolean;
173
172
  private panelToolbar: UI.Toolbar.Toolbar;
174
- private showSlowScrollRectsSetting?: Common.Settings.Setting<boolean>;
175
- private showPaintsSetting?: Common.Settings.Setting<boolean>;
173
+ private readonly showSlowScrollRectsSetting: Common.Settings.Setting<boolean>;
174
+ private readonly showPaintsSetting: Common.Settings.Setting<boolean>;
175
+ readonly #chromeWindowSetting: Common.Settings.Setting<boolean>;
176
176
  private mouseDownX?: number;
177
177
  private mouseDownY?: number;
178
178
 
@@ -197,10 +197,8 @@ export class Layers3DView extends Layers3DViewBase
197
197
  SettingsUI.LayerViewerSettings.showPaintsSettingDescriptor, this.panelToolbar);
198
198
  this.showSlowScrollRectsSetting = this.createVisibilitySetting(
199
199
  SettingsUI.LayerViewerSettings.showSlowScrollRectsSettingDescriptor, this.panelToolbar);
200
- this.showPaintsSetting.addChangeListener(this.updatePaints, this);
201
- Common.Settings.Settings.instance()
202
- .resolve(SettingsUI.LayerViewerSettings.chromeWindowSettingDescriptor)
203
- .addChangeListener(this.updateData, this);
200
+ this.#chromeWindowSetting =
201
+ Common.Settings.Settings.instance().resolve(SettingsUI.LayerViewerSettings.chromeWindowSettingDescriptor);
204
202
 
205
203
  this.performUpdate();
206
204
 
@@ -216,8 +214,6 @@ export class Layers3DView extends Layers3DViewBase
216
214
 
217
215
  this.snapshotLayers = new Map();
218
216
  this.layerViewHost.setLayerSnapshotMap(this.snapshotLayers);
219
-
220
- this.layerViewHost.showInternalLayersSetting().addChangeListener(this.updateData, this);
221
217
  }
222
218
 
223
219
  override performUpdate(): void {
@@ -242,7 +238,7 @@ export class Layers3DView extends Layers3DViewBase
242
238
  this.layerTree = layerTree;
243
239
  this.layerTexture = null;
244
240
  delete this.oldTextureScale;
245
- if (this.showPaints()) {
241
+ if (this.showPaintsSetting.get()) {
246
242
  this.textureManager.setLayerTree(layerTree);
247
243
  }
248
244
  this.updateData();
@@ -268,19 +264,24 @@ export class Layers3DView extends Layers3DViewBase
268
264
  }
269
265
 
270
266
  override willHide(): void {
271
- super.willHide();
267
+ this.showPaintsSetting.removeChangeListener(this.updatePaints, this);
268
+ this.showSlowScrollRectsSetting.removeChangeListener(this.updateData, this);
269
+ this.#chromeWindowSetting.removeChangeListener(this.updateData, this);
270
+ this.layerViewHost.showInternalLayersSetting().removeChangeListener(this.updateData, this);
272
271
  this.textureManager.suspend();
272
+ super.willHide();
273
273
  }
274
274
 
275
275
  override wasShown(): void {
276
276
  super.wasShown();
277
+ this.showPaintsSetting.addChangeListener(this.updatePaints, this);
278
+ this.showSlowScrollRectsSetting.addChangeListener(this.updateData, this);
279
+ this.#chromeWindowSetting.addChangeListener(this.updateData, this);
280
+ this.layerViewHost.showInternalLayersSetting().addChangeListener(this.updateData, this);
277
281
  this.textureManager.resume();
278
- if (!this.needsUpdate) {
279
- return;
280
- }
281
282
  this.performUpdate();
282
283
  this.resizeCanvas();
283
- this.updateData();
284
+ this.updatePaints();
284
285
  }
285
286
 
286
287
  updateLayerSnapshot(layer: SDK.LayerTreeBase.Layer): void {
@@ -632,7 +633,7 @@ export class Layers3DView extends Layers3DViewBase
632
633
  this.layerTree.forEachLayer(this.calculateLayerRect.bind(this));
633
634
  }
634
635
 
635
- if (this.showSlowScrollRectsSetting && this.showSlowScrollRectsSetting.get() && this.layerTree) {
636
+ if (this.showSlowScrollRectsSetting.get() && this.layerTree) {
636
637
  this.layerTree.forEachLayer(this.calculateLayerScrollRects.bind(this));
637
638
  }
638
639
 
@@ -643,7 +644,7 @@ export class Layers3DView extends Layers3DViewBase
643
644
  rect.setVertices(layer.quad(), this.depthForLayer(layer));
644
645
  rect.texture = this.layerTexture.texture;
645
646
  this.appendRect(rect);
646
- } else if (this.showPaints() && this.layerTree) {
647
+ } else if (this.showPaintsSetting.get() && this.layerTree) {
647
648
  this.layerTree.forEachLayer(this.calculateLayerTileRects.bind(this));
648
649
  }
649
650
  }
@@ -731,9 +732,8 @@ export class Layers3DView extends Layers3DViewBase
731
732
  return;
732
733
  }
733
734
 
734
- const drawChrome =
735
- Common.Settings.Settings.instance().resolve(SettingsUI.LayerViewerSettings.chromeWindowSettingDescriptor).get() &&
736
- this.chromeTextures.length >= 3 && this.chromeTextures.indexOf(undefined) < 0;
735
+ const drawChrome = this.#chromeWindowSetting.get() && this.chromeTextures.length >= 3 &&
736
+ this.chromeTextures.indexOf(undefined) < 0;
737
737
  const z = (this.maxDepth + 1) * LayerSpacing;
738
738
  const borderWidth = Math.ceil(ViewportBorderWidth * this.scale);
739
739
  let vertices: number[] = [viewport.width, 0, z, viewport.width, viewport.height, z, 0, viewport.height, z, 0, 0, z];
@@ -803,7 +803,6 @@ export class Layers3DView extends Layers3DViewBase
803
803
 
804
804
  updateData(): void {
805
805
  if (!this.isShowing()) {
806
- this.needsUpdate = true;
807
806
  return;
808
807
  }
809
808
  // Debounce into the next frame (double rAF).
@@ -878,7 +877,6 @@ export class Layers3DView extends Layers3DViewBase
878
877
  descriptor: Common.Settings.SettingDescriptor<boolean>,
879
878
  toolbar: UI.Toolbar.Toolbar): Common.Settings.Setting<boolean> {
880
879
  const setting = Common.Settings.Settings.instance().resolve(descriptor);
881
- setting.addChangeListener(this.updateData, this);
882
880
  toolbar.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(setting));
883
881
  return setting;
884
882
  }
@@ -935,18 +933,13 @@ export class Layers3DView extends Layers3DViewBase
935
933
  }
936
934
 
937
935
  private updatePaints(): void {
938
- if (this.showPaints()) {
936
+ if (this.showPaintsSetting.get()) {
939
937
  this.textureManager.setLayerTree(this.layerTree);
940
- this.textureManager.forceUpdate();
941
938
  } else {
942
939
  this.textureManager.reset();
943
940
  }
944
941
  this.updateData();
945
942
  }
946
-
947
- private showPaints(): boolean {
948
- return this.showPaintsSetting ? this.showPaintsSetting.get() : false;
949
- }
950
943
  }
951
944
 
952
945
  export enum OutlineType {
@@ -1088,9 +1081,6 @@ export class LayerTextureManager {
1088
1081
  }
1089
1082
  });
1090
1083
  }
1091
- if (!oldLayers.length) {
1092
- this.forceUpdate();
1093
- }
1094
1084
  for (const layer of oldLayers) {
1095
1085
  if (newLayers.has(layer)) {
1096
1086
  continue;
@@ -1149,12 +1139,6 @@ export class LayerTextureManager {
1149
1139
  }
1150
1140
  }
1151
1141
 
1152
- forceUpdate(): void {
1153
- this.queue.forEach(layer => this.updateLayer(layer));
1154
- this.queue = [];
1155
- void this.update();
1156
- }
1157
-
1158
1142
  private update(): Promise<void> {
1159
1143
  const layer = this.queue.shift();
1160
1144
  if (!layer) {
@@ -2,8 +2,6 @@
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
4
 
5
- import '../settings/emulation/components/components.js';
6
-
7
5
  import * as Common from '../../core/common/common.js';
8
6
  import * as i18n from '../../core/i18n/i18n.js';
9
7
  import * as Platform from '../../core/platform/platform.js';
@@ -14,7 +12,7 @@ import * as UI from '../../ui/legacy/legacy.js';
14
12
  import {Directives, html, type LitTemplate, render} from '../../ui/lit/lit.js';
15
13
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
16
14
  import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
17
- import type * as EmulationComponents from '../settings/emulation/components/components.js';
15
+ import * as EmulationComponents from '../settings/emulation/components/components.js';
18
16
 
19
17
  import networkConfigViewStyles from './networkConfigView.css.js';
20
18
 
@@ -195,13 +193,17 @@ function renderUserAgentSection(input: NetworkConfigViewInput, output: NetworkCo
195
193
  </devtools-checkbox>
196
194
  <div class=${Directives.classMap({'network-config-ua-custom': true, checked: input.useCustomUA})}>
197
195
  ${renderUserAgentSelectAndInput(input, output, title)}
198
- <devtools-user-agent-client-hints-form
199
- .value=${input.clientHintsValue}
200
- .disabled=${!input.useCustomUA}
201
- @clienthintschange=${(e: Event) => input.onClientHintsChange(
202
- (e.target as EmulationComponents.UserAgentClientHintsForm.UserAgentClientHintsForm).value.metaData)}
203
- @clienthintssubmit=${(e: Event) => input.onClientHintsSubmit((e as CustomEvent).detail.value)}>
204
- </devtools-user-agent-client-hints-form>
196
+ <devtools-widget
197
+ class="user-agent-client-hints-form"
198
+ @clienthintschange=${(e: CustomEvent<Protocol.Emulation.UserAgentMetadata>) =>
199
+ input.onClientHintsChange(e.detail)}
200
+ @clienthintssubmit=${(e: CustomEvent<Protocol.Emulation.UserAgentMetadata>) =>
201
+ input.onClientHintsSubmit(e.detail)}
202
+ ${UI.Widget.widget(EmulationComponents.UserAgentClientHintsForm.UserAgentClientHintsForm, {
203
+ value: input.clientHintsValue,
204
+ disabled: !input.useCustomUA,
205
+ })}>
206
+ </devtools-widget>
205
207
  </div>
206
208
  <span class="status-text">${input.clientHintsStatusText}</span>
207
209
  `);
@@ -26,7 +26,7 @@
26
26
  flex: 2 0 200px;
27
27
  }
28
28
 
29
- .network-config-fields span:first-of-type {
29
+ .network-config-fields > span:first-of-type {
30
30
  padding: 3px 0;
31
31
  }
32
32
 
@@ -74,12 +74,12 @@
74
74
  line-height: var(--sys-size-9);
75
75
  }
76
76
 
77
- .network-config-ua input {
77
+ .network-config-ua-custom > input {
78
78
  display: block;
79
79
  width: calc(100% - var(--sys-size-9));
80
80
  }
81
81
 
82
- .network-config-ua input[type="text"],
82
+ .network-config-ua-custom > input[type="text"],
83
83
  .network-config-ua select {
84
84
  margin-top: var(--sys-size-5);
85
85
  }
@@ -92,20 +92,20 @@
92
92
  .network-config-ua-custom {
93
93
  padding-bottom: var(--sys-size-5);
94
94
 
95
- input,
96
- devtools-user-agent-client-hints-form {
95
+ > input,
96
+ > .user-agent-client-hints-form {
97
97
  opacity: 38%;
98
98
  pointer-events: none;
99
99
  }
100
100
 
101
- &.checked input,
102
- &.checked devtools-user-agent-client-hints-form {
101
+ &.checked > input,
102
+ &.checked > .user-agent-client-hints-form {
103
103
  opacity: revert;
104
104
  pointer-events: revert;
105
105
  }
106
106
  }
107
107
 
108
- devtools-user-agent-client-hints-form {
108
+ .user-agent-client-hints-form {
109
109
  display: block;
110
110
  margin-top: var(--sys-size-7);
111
111
  width: min(100%, 400px);
@@ -455,9 +455,8 @@ export class ScreencastView extends UI.Widget.Widget implements SDK.OverlayModel
455
455
  this.resourceTreeModel = screenCaptureModel.target().model(SDK.ResourceTreeModel.ResourceTreeModel);
456
456
  this.networkManager = screenCaptureModel.target().model(SDK.NetworkManager.NetworkManager);
457
457
  this.inputModel = screenCaptureModel.target().model(InputModel);
458
- this.createNavigationBar();
459
- this.updateGlasspane();
460
458
  if (this.isShowing()) {
459
+ this.createNavigationBar();
461
460
  this.#scheduleCasting();
462
461
  }
463
462
  } else {
@@ -494,6 +493,7 @@ export class ScreencastView extends UI.Widget.Widget implements SDK.OverlayModel
494
493
  super.wasShown();
495
494
  SDK.TargetManager.TargetManager.instance().addEventListener(SDK.TargetManager.Events.SUSPEND_STATE_CHANGED,
496
495
  this.onSuspendStateChange, this);
496
+ this.createNavigationBar();
497
497
  this.updateGlasspane();
498
498
  this.#scheduleCasting();
499
499
  this.requestUpdate();
@@ -539,14 +539,11 @@ export class ScreencastView extends UI.Widget.Widget implements SDK.OverlayModel
539
539
  delete this.deferredCasting;
540
540
  }
541
541
  this.stopCasting();
542
+ this.#cleanup();
542
543
  SDK.TargetManager.TargetManager.instance().removeEventListener(SDK.TargetManager.Events.SUSPEND_STATE_CHANGED,
543
544
  this.onSuspendStateChange, this);
544
545
  }
545
546
 
546
- override onDetach(): void {
547
- this.#cleanup();
548
- }
549
-
550
547
  private async startCasting(): Promise<void> {
551
548
  if (!this.#screenCaptureModel) {
552
549
  return;
@@ -272,37 +272,6 @@ export class SecurityPanelSidebar extends UI.Widget.VBox {
272
272
  this.requestUpdate();
273
273
  }
274
274
 
275
- // Used in web tests
276
- elementsByOrigin(): Map<string, {
277
- select: (omitFocus?: boolean, selectedByUser?: boolean) => void,
278
- showElement: () => void,
279
- origin: () => string,
280
- securityState: () => Protocol.Security.SecurityState | undefined,
281
- }> {
282
- const map = new Map<string, {
283
- select: (omitFocus?: boolean, selectedByUser?: boolean) => void,
284
- showElement: () => void,
285
- origin: () => string,
286
- securityState: () => Protocol.Security.SecurityState | undefined,
287
- }>();
288
- for (const [origin, state] of this.#origins.entries()) {
289
- const element = {
290
- select: () => {
291
- this.#selectedElementId = origin;
292
- this.requestUpdate();
293
- this.#onShowOrigin?.(origin);
294
- },
295
- showElement: () => {
296
- this.#onShowOrigin?.(origin);
297
- },
298
- origin: () => origin,
299
- securityState: () => state,
300
- };
301
- map.set(origin, element);
302
- }
303
- return map;
304
- }
305
-
306
275
  set selectedOrigin(origin: Platform.DevToolsPath.UrlString|null) {
307
276
  this.#selectedElementId = origin ?? 'overview';
308
277
  this.requestUpdate();