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
@@ -54,23 +54,67 @@ reviewers and typically avoids inflating the bundle size.
54
54
 
55
55
  For all third-party packages that are used either as part of the DevTools build
56
56
  process or to augment engineers workflows (for example linters), we add them to
57
- `scripts/deps/manage_node_deps.py`. This Python script has been approved by
58
- Chromium licensing to be used, on the basis that it enforces all packages have a
59
- license that is compatible with a set of pre-defined licensees.
60
-
61
- If you want to use a new package as tooling process in engineer workflows, you
62
- can add the package to the `package.json` and run `./dt install-deps` to
63
- check in the new contents.
57
+ `package.json`; `scripts/deps/manage_node_deps.py` installs them. This Python
58
+ script has been approved by Chromium licensing to be used, on the basis that it
59
+ enforces all packages have a license that is compatible with a set of
60
+ pre-defined licensees.
61
+
62
+ `node_modules/` is not checked into git. `gclient sync` downloads it as one
63
+ archive from `gs://chromium-nodejs/devtools-frontend/<sha256>`, pinned by the
64
+ `node_modules` entry in `DEPS`, the same way Chromium's WebUI toolchain and
65
+ chromium-bidi ship their npm dependencies. Local edits inside `node_modules/`
66
+ only last until the next `gclient sync` that changes the pin.
67
+
68
+ gclient decides whether to re-extract the archive from the stamp files it
69
+ keeps in `node_modules/`, not from the extracted tree. Checking out a revision
70
+ from before `node_modules/` left git restores the tracked tree over the
71
+ extracted one and leaves the stamps alone; checking out a later revision again
72
+ deletes the tracked files, and `gclient sync` would consider the now empty
73
+ directory up to date. The `ensure_node_modules` hook
74
+ (`scripts/deps/ensure_node_modules.py`) catches this and re-extracts the
75
+ archive that gclient leaves in `node_modules/node_modules.tar.gz`; if that
76
+ archive is missing, it removes the stamps and asks you to run `gclient sync`
77
+ once more.
78
+
79
+ To add or update a package:
80
+
81
+ 1. Change the version in `package.json`.
82
+ 2. Run `./dt install-deps`. It runs `npm install`, post-processes the tree,
83
+ checks licenses, applies `scripts/deps/npm_exclude.txt`, verifies that
84
+ every `node_modules/` path referenced from GN or Python build files still
85
+ exists and writes a deterministic `out/node_modules.tar.gz` (sorted
86
+ entries, zeroed timestamps and ownership: the same tree always has the
87
+ same sha256).
88
+ 3. Build and test against the new tree: `./dt build && ./dt test`.
89
+ 4. Run `./dt install-deps --upload`. It uploads the archive (a no-op if the
90
+ object exists) and updates `DEPS`. This needs write access to the bucket;
91
+ otherwise ask an infra owner (`config/owner/INFRA_OWNERS`) to run it on
92
+ your branch.
93
+ 5. Upload the CL: `package.json`, `package-lock.json` and the `DEPS` change.
94
+ Presubmit checks that these change together; add a
95
+ `Skip-Node-Modules-Check: <reason>` footer for intentional exceptions.
96
+
97
+ Reviewers can rebuild the archive from the lockfile with `./dt install-deps`
98
+ and compare the printed sha256 with `DEPS`.
64
99
 
65
100
  Only add new license types to `LICENSES` after you received approval from
66
101
  `opensource-licensing@google.com`. Their response time is typically within 24
67
102
  hours, so this typically is not a big hurdle.
68
103
 
69
104
  To avoid excessive package updates, it is typically easiest to update all
70
- packages in `manage_node_deps.py` once a month. Since NPM packages can have a
71
- lot of (shared) transitive dependencies, updating the packages on a specific day
72
- increases the chances that shared dependencies are deduplicated and thus result
73
- in smaller repository sizes.
105
+ packages once a month. Since NPM packages can have a lot of (shared) transitive
106
+ dependencies, updating the packages on a specific day increases the chances
107
+ that shared dependencies are deduplicated and thus result in a smaller archive.
108
+
109
+ #### The exclude list
110
+
111
+ `scripts/deps/npm_exclude.txt` holds rsync filter rules that drop files the
112
+ build and tests don't need (tests, docs, source maps, non-declaration
113
+ TypeScript sources, dotfiles, ...) before the archive is built. Keep rules come
114
+ first and the first matching rule wins. Stick to generic patterns: anything
115
+ package-specific must be measured and verified with a full build and test run,
116
+ because the reference check only knows about paths mentioned in GN and Python
117
+ files, not about what Node resolves at runtime.
74
118
 
75
119
  > **WARNING:** Updating tools such as Rollup and TypeScript will cause all build
76
120
  > cache output to be purged, as they are part of all DevTools modules. Whenever
@@ -334,6 +334,14 @@ Follow [instructions](https://www.chromium.org/developers/how-tos/get-the-code)
334
334
  to check out Chromium. The DevTools front-end code is located inside the
335
335
  `third_party/devtools-frontend/src/` folder (after running `gclient sync`).
336
336
 
337
+ `node_modules/` is not part of the devtools-frontend git tree: `gclient sync`,
338
+ run from `chromium/src`, downloads the archive pinned in
339
+ `third_party/devtools-frontend/src/DEPS` and extracts it (see
340
+ [dependencies.md](cookbook/dependencies.md)). Whenever you check out a
341
+ different DevTools revision or branch in `third_party/devtools-frontend/src`,
342
+ run `gclient sync` again before building; `git checkout` or `git rebase`
343
+ alone do not update `node_modules/`.
344
+
337
345
  ### Build
338
346
 
339
347
  The [instructions](https://www.chromium.org/developers/how-tos/get-the-code) on
@@ -438,6 +446,13 @@ git rebase
438
446
  popd
439
447
  ```
440
448
 
449
+ Finish with another `gclient sync` so that `node_modules/` (and the other
450
+ dependencies pinned in the DevTools `DEPS`) match the DevTools revision you
451
+ ended up on. If you switch back and forth across the revision that moved
452
+ `node_modules/` out of git, `gclient sync` repairs the directory on its own
453
+ (`ensure_node_modules` hook); in the worst case it asks you to run it once
454
+ more.
455
+
441
456
  ## Integrated checkout
442
457
 
443
458
  **This solution is experimental, please report any trouble that you run into!**
@@ -2,7 +2,9 @@
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 {globSync} from 'node:fs';
5
+ import {createHash} from 'node:crypto';
6
+ import * as fs from 'node:fs';
7
+ import {createRequire} from 'node:module';
6
8
  import * as path from 'node:path';
7
9
  import yargs from 'yargs';
8
10
  import {hideBin} from 'yargs/helpers';
@@ -58,32 +60,56 @@ if (inputDirectories.length === 0) {
58
60
  throw new Error('Provide at least one directory!');
59
61
  }
60
62
 
63
+ const outputDirectory = yargsObject['output-directory'];
64
+
65
+ // The parse results depend on collect-strings.js and the TypeScript version,
66
+ // so a change to either one discards the cache.
67
+ const cachePath = path.join(outputDirectory, 'collected-ui-strings.cache.json');
68
+ const collectStringsSource = fs.readFileSync(new URL('../../../third_party/i18n/collect-strings.js', import.meta.url));
69
+ const typescriptVersion = createRequire(import.meta.url)('typescript/package.json').version;
70
+ const cacheVersion = createHash('sha256').update(collectStringsSource).update(typescriptVersion).digest('hex');
71
+ /** @type {Record<string, {source: string, parsed: object}>} */
72
+ let savedFiles = {};
73
+ try {
74
+ const saved = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
75
+ if (saved.version === cacheVersion) {
76
+ savedFiles = saved.files;
77
+ }
78
+ } catch {
79
+ // Without a cache, all UIStrings get parsed again.
80
+ }
81
+ const cache = new Map(Object.entries(savedFiles));
82
+ const initialCacheSize = cache.size;
83
+
61
84
  /** @type {Record<string, CtcMessage>} */
62
85
  let collectedStrings = {};
63
86
  /** @type {string[]} */
64
87
  const files = [];
65
88
  for (const directory of inputDirectories) {
66
- collectedStrings = {
67
- ...collectedStrings,
68
- ...collectAllStringsInDir(directory),
69
- };
70
-
71
- const fs = globSync('**/*.{js,ts,gn}', {
89
+ const directoryFiles = fs.globSync('**/*.{js,ts,gn}', {
72
90
  cwd: directory,
73
91
  exclude: IGNORED_PATH_COMPONENTS,
74
92
  });
75
- files.push(...fs.map(f => path.join(directory, f)));
93
+ collectedStrings = {
94
+ ...collectedStrings,
95
+ ...collectAllStringsInDir(
96
+ directory,
97
+ directoryFiles.filter(f => !f.endsWith('.gn')),
98
+ cache,
99
+ ),
100
+ };
101
+ files.push(...directoryFiles.map(f => path.join(directory, f)));
76
102
  }
77
103
 
78
- const outputDirectory = yargsObject['output-directory'];
79
- await convertCtcToLhLAndSave(outputDirectory, 'en-US', collectedStrings);
104
+ const tasks = [convertCtcToLhLAndSave(outputDirectory, 'en-US', collectedStrings)];
80
105
  if (yargsObject['include-en-xl']) {
81
- await convertCtcToLhLAndSave(
106
+ tasks.push(convertCtcToLhLAndSave(
82
107
  outputDirectory,
83
108
  'en-XL',
84
109
  createPsuedoLocaleStrings(collectedStrings),
85
- );
110
+ ));
86
111
  }
112
+ await Promise.all(tasks);
87
113
 
88
114
  // Write the depfile. This is necessary to properly rebuild en-US.json/en-XL.json
89
115
  // when any of the input TS files change. We also re-build when any GN file changes,
@@ -93,3 +119,23 @@ ${path.join(outputDirectory, 'en-US.json')}: ${files.join(' ')}
93
119
  `;
94
120
 
95
121
  await writeIfChanged(path.join(outputDirectory, 'collected-ui-strings.d'), depfile);
122
+
123
+ // Drop the entries of deleted files, and save the cache only if it changed.
124
+ let cacheChanged = false;
125
+ await Promise.all(
126
+ Array.from(cache.entries()).map(async ([file, entry]) => {
127
+ if (savedFiles[file] !== entry) {
128
+ cacheChanged = true;
129
+ }
130
+ try {
131
+ await fs.promises.access(file);
132
+ } catch {
133
+ cache.delete(file);
134
+ cacheChanged = true;
135
+ }
136
+ }),
137
+ );
138
+ if (cacheChanged || cache.size !== initialCacheSize) {
139
+ const serialized = JSON.stringify({version: cacheVersion, files: Object.fromEntries(cache)});
140
+ await writeIfChanged(cachePath, serialized);
141
+ }
@@ -22,6 +22,13 @@ export interface EventTypes {
22
22
  [Events.CREDENTIAL_UPDATED]: Protocol.WebAuthn.CredentialUpdatedEvent;
23
23
  }
24
24
 
25
+ function throwIfError(response: Protocol.ProtocolResponseWithError): void {
26
+ const error = response.getError();
27
+ if (error) {
28
+ throw new Error(error);
29
+ }
30
+ }
31
+
25
32
  export class WebAuthnModel extends SDKModel<EventTypes> {
26
33
  readonly #agent: ProtocolProxyApi.WebAuthnApi;
27
34
  constructor(target: Target) {
@@ -30,44 +37,44 @@ export class WebAuthnModel extends SDKModel<EventTypes> {
30
37
  target.registerWebAuthnDispatcher(new WebAuthnDispatcher(this));
31
38
  }
32
39
 
33
- setVirtualAuthEnvEnabled(enable: boolean, enableUI = true): Promise<Object> {
34
- if (enable) {
35
- return this.#agent.invoke_enable({enableUI});
36
- }
37
- return this.#agent.invoke_disable();
40
+ async setVirtualAuthEnvEnabled(enable: boolean, enableUI = true): Promise<void> {
41
+ const response = enable ? await this.#agent.invoke_enable({enableUI}) : await this.#agent.invoke_disable();
42
+ throwIfError(response);
38
43
  }
39
44
 
40
45
  async addAuthenticator(options: Protocol.WebAuthn.VirtualAuthenticatorOptions):
41
46
  Promise<Protocol.WebAuthn.AuthenticatorId> {
42
47
  const response = await this.#agent.invoke_addVirtualAuthenticator({options});
48
+ throwIfError(response);
43
49
  return response.authenticatorId;
44
50
  }
45
51
 
46
52
  async removeAuthenticator(authenticatorId: Protocol.WebAuthn.AuthenticatorId): Promise<void> {
47
- await this.#agent.invoke_removeVirtualAuthenticator({authenticatorId});
53
+ throwIfError(await this.#agent.invoke_removeVirtualAuthenticator({authenticatorId}));
48
54
  }
49
55
 
50
56
  async setAutomaticPresenceSimulation(authenticatorId: Protocol.WebAuthn.AuthenticatorId, enabled: boolean):
51
57
  Promise<void> {
52
- await this.#agent.invoke_setAutomaticPresenceSimulation({authenticatorId, enabled});
58
+ throwIfError(await this.#agent.invoke_setAutomaticPresenceSimulation({authenticatorId, enabled}));
53
59
  }
54
60
 
55
61
  async setUserVerified(authenticatorId: Protocol.WebAuthn.AuthenticatorId, isUserVerified: boolean): Promise<void> {
56
- await this.#agent.invoke_setUserVerified({authenticatorId, isUserVerified});
62
+ throwIfError(await this.#agent.invoke_setUserVerified({authenticatorId, isUserVerified}));
57
63
  }
58
64
 
59
65
  async addCredential(authenticatorId: Protocol.WebAuthn.AuthenticatorId,
60
66
  credential: Protocol.WebAuthn.Credential): Promise<void> {
61
- await this.#agent.invoke_addCredential({authenticatorId, credential});
67
+ throwIfError(await this.#agent.invoke_addCredential({authenticatorId, credential}));
62
68
  }
63
69
 
64
70
  async getCredentials(authenticatorId: Protocol.WebAuthn.AuthenticatorId): Promise<Protocol.WebAuthn.Credential[]> {
65
71
  const response = await this.#agent.invoke_getCredentials({authenticatorId});
72
+ throwIfError(response);
66
73
  return response.credentials;
67
74
  }
68
75
 
69
76
  async removeCredential(authenticatorId: Protocol.WebAuthn.AuthenticatorId, credentialId: string): Promise<void> {
70
- await this.#agent.invoke_removeCredential({authenticatorId, credentialId});
77
+ throwIfError(await this.#agent.invoke_removeCredential({authenticatorId, credentialId}));
71
78
  }
72
79
 
73
80
  credentialAdded(params: Protocol.WebAuthn.CredentialAddedEvent): void {
@@ -867,8 +867,8 @@ inspectorBackend.registerEvent("Network.directTCPSocketAborted", ["identifier",
867
867
  inspectorBackend.registerEvent("Network.directTCPSocketClosed", ["identifier", "timestamp"]);
868
868
  inspectorBackend.registerEvent("Network.directTCPSocketChunkSent", ["identifier", "data", "timestamp"]);
869
869
  inspectorBackend.registerEvent("Network.directTCPSocketChunkReceived", ["identifier", "data", "timestamp"]);
870
- inspectorBackend.registerEvent("Network.directUDPSocketJoinedMulticastGroup", ["identifier", "IPAddress"]);
871
- inspectorBackend.registerEvent("Network.directUDPSocketLeftMulticastGroup", ["identifier", "IPAddress"]);
870
+ inspectorBackend.registerEvent("Network.directUDPSocketJoinedMulticastGroup", ["identifier", "IPAddress", "sourceAddress"]);
871
+ inspectorBackend.registerEvent("Network.directUDPSocketLeftMulticastGroup", ["identifier", "IPAddress", "sourceAddress"]);
872
872
  inspectorBackend.registerEvent("Network.directUDPSocketCreated", ["identifier", "options", "timestamp", "initiator"]);
873
873
  inspectorBackend.registerEvent("Network.directUDPSocketOpened", ["identifier", "localAddr", "localPort", "timestamp", "remoteAddr", "remotePort"]);
874
874
  inspectorBackend.registerEvent("Network.directUDPSocketAborted", ["identifier", "errorMessage", "timestamp"]);
@@ -13395,12 +13395,28 @@ export namespace Network {
13395
13395
 
13396
13396
  export interface DirectUDPSocketJoinedMulticastGroupEvent {
13397
13397
  identifier: RequestId;
13398
+ /**
13399
+ * Multicast group address.
13400
+ */
13398
13401
  IPAddress: string;
13402
+ /**
13403
+ * Source address of a source-specific multicast (SSM) membership. Absent
13404
+ * for any-source multicast (ASM) memberships.
13405
+ */
13406
+ sourceAddress?: string;
13399
13407
  }
13400
13408
 
13401
13409
  export interface DirectUDPSocketLeftMulticastGroupEvent {
13402
13410
  identifier: RequestId;
13411
+ /**
13412
+ * Multicast group address.
13413
+ */
13403
13414
  IPAddress: string;
13415
+ /**
13416
+ * Source address of a source-specific multicast (SSM) membership. Absent
13417
+ * for any-source multicast (ASM) memberships.
13418
+ */
13419
+ sourceAddress?: string;
13404
13420
  }
13405
13421
 
13406
13422
  /**
@@ -113,6 +113,10 @@ export class CD4ABridge extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
113
113
  details.push(`- Editor: ${editorInfo}`);
114
114
  }
115
115
 
116
+ for (const line of thread.anchor.agentContext ?? []) {
117
+ details.push(`- ${line}`);
118
+ }
119
+
116
120
  if (details.length === 0) {
117
121
  return rawText;
118
122
  }
@@ -51,6 +51,22 @@ export interface CommentAnchorSignature {
51
51
  editor?: EditorAnchorSignature;
52
52
  /** Optional timeline flamechart anchor coordinates for Performance panel trace entries */
53
53
  timeline?: TimelineAnchorSignature;
54
+ /**
55
+ * Optional formatted lines that give the AI agent context about the
56
+ * anchored target beyond the VE path and text signature, for example the
57
+ * timing and warnings of a Performance panel trace entry. CD4ABridge
58
+ * appends each line to the comment text that it sends to the agent.
59
+ *
60
+ * These lines are only context for the agent. They are not used to
61
+ * re-match the anchor to its target; the other fields of this signature
62
+ * do that.
63
+ *
64
+ * Currently only the Performance panel sets this field. Before adding
65
+ * context here, consider whether it belongs in a new field on this
66
+ * signature instead. This field is only for text that is already
67
+ * formatted for the agent, not for data that other code needs to read.
68
+ */
69
+ agentContext?: string[];
54
70
  }
55
71
 
56
72
  export interface Comment {
@@ -283,14 +283,21 @@ export async function finalize(): Promise<void> {
283
283
  */
284
284
  // @ts-expect-error
285
285
  const isLightrider = globalThis.isLightrider;
286
- if (isLightrider && request.resourceFinish && request.receiveResponse?.args.data.headers) {
287
- const lrSizeHeader = request.receiveResponse.args.data.headers.find(h => h.name === 'X-TotalFetchedSize');
288
- if (lrSizeHeader) {
289
- const size = parseFloat(lrSizeHeader.value);
290
- if (!isNaN(size)) {
291
- request.resourceFinish.args.data.encodedDataLength = size;
286
+ if (isLightrider && request.receiveResponse?.args.data.headers) {
287
+ if (request.resourceFinish) {
288
+ const lrSizeHeader = request.receiveResponse.args.data.headers.find(h => h.name === 'X-TotalFetchedSize');
289
+ if (lrSizeHeader) {
290
+ const size = parseFloat(lrSizeHeader.value);
291
+ if (!isNaN(size)) {
292
+ request.resourceFinish.args.data.encodedDataLength = size;
293
+ }
292
294
  }
293
295
  }
296
+
297
+ const isH2 = request.receiveResponse.args.data.headers.some(h => h.name === 'X-ProtocolIsH2');
298
+ if (isH2) {
299
+ request.receiveResponse.args.data.protocol = 'h2';
300
+ }
294
301
  }
295
302
 
296
303
  // If a ResourceFinish event with an encoded data length is received,
@@ -89,11 +89,86 @@ const UIStrings = {
89
89
  * @description Fallback reason shown when an unknown error occurs while blocking recording.
90
90
  */
91
91
  unknownError: 'Unknown error',
92
+ /**
93
+ * @description Accessible label for the grabber handle used to vertically resize the announcements pane.
94
+ */
95
+ resizeAnnouncementsPane: 'Resize announcements pane',
92
96
  } as const;
93
97
  const str_ = i18n.i18n.registerUIStrings('panels/accessibility/AccessibilityAnnouncementRecordingView.ts', UIStrings);
94
98
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
95
99
 
96
100
  export const BINDING_NAME = '__announcementsRecorderBinding';
101
+ const MIN_MAIN_PANE_HEIGHT = 150;
102
+ const KEYBOARD_RESIZE_STEP = 10;
103
+ let isDragging = false;
104
+ let resizeStartY = 0;
105
+ let resizeStartHeight = MIN_MAIN_PANE_HEIGHT;
106
+
107
+ function onResizerPointerDown(event: PointerEvent): void {
108
+ if (event.button !== 0) {
109
+ return;
110
+ }
111
+ const resizerEl = event.currentTarget as HTMLElement | null;
112
+ const mainPane = resizerEl?.parentElement?.querySelector<HTMLElement>('.announcements-main-pane');
113
+ if (!resizerEl || !mainPane) {
114
+ return;
115
+ }
116
+ isDragging = true;
117
+ resizeStartY = event.clientY;
118
+ resizeStartHeight = mainPane.getBoundingClientRect().height;
119
+ try {
120
+ resizerEl.setPointerCapture(event.pointerId);
121
+ } catch {
122
+ // Pointer capture may fail on synthetic events in unit tests.
123
+ }
124
+ event.preventDefault();
125
+ }
126
+
127
+ function onResizerPointerMove(event: PointerEvent): void {
128
+ const resizerEl = event.currentTarget as HTMLElement | null;
129
+ if (!resizerEl || !isDragging) {
130
+ return;
131
+ }
132
+ const mainPane = resizerEl.parentElement?.querySelector<HTMLElement>('.announcements-main-pane');
133
+ if (!mainPane) {
134
+ return;
135
+ }
136
+ const delta = event.clientY - resizeStartY;
137
+ const newHeight = Math.max(MIN_MAIN_PANE_HEIGHT, resizeStartHeight + delta);
138
+ mainPane.style.height = `${newHeight}px`;
139
+ mainPane.style.flex = 'none';
140
+ }
141
+
142
+ function onResizerPointerUp(event: PointerEvent): void {
143
+ isDragging = false;
144
+ const resizerEl = event.currentTarget as HTMLElement | null;
145
+ if (resizerEl) {
146
+ try {
147
+ if (resizerEl.hasPointerCapture(event.pointerId)) {
148
+ resizerEl.releasePointerCapture(event.pointerId);
149
+ }
150
+ } catch {
151
+ // Ignored for synthetic events in unit tests.
152
+ }
153
+ }
154
+ }
155
+
156
+ function onResizerKeyDown(event: KeyboardEvent): void {
157
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') {
158
+ return;
159
+ }
160
+ const resizerEl = event.currentTarget as HTMLElement | null;
161
+ const mainPane = resizerEl?.parentElement?.querySelector<HTMLElement>('.announcements-main-pane');
162
+ if (!mainPane) {
163
+ return;
164
+ }
165
+ event.preventDefault();
166
+ const delta = event.key === 'ArrowDown' ? KEYBOARD_RESIZE_STEP : -KEYBOARD_RESIZE_STEP;
167
+ const currentHeight = mainPane.getBoundingClientRect().height;
168
+ const newHeight = Math.max(MIN_MAIN_PANE_HEIGHT, currentHeight + delta);
169
+ mainPane.style.height = `${newHeight}px`;
170
+ mainPane.style.flex = 'none';
171
+ }
97
172
 
98
173
  export enum AnnouncementApi {
99
174
  ARIA_LIVE = 'aria-live',
@@ -218,6 +293,23 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
218
293
  @reveal-in-a11y-tree=${(e: CustomEvent<A11yAnnouncement>) => input.onRevealInA11yTree(e.detail)}>
219
294
  </devtools-widget>
220
295
  </div>
296
+ <div
297
+ class="announcements-resizer"
298
+ role="separator"
299
+ aria-orientation="horizontal"
300
+ aria-label=${i18nString(UIStrings.resizeAnnouncementsPane)}
301
+ title=${i18nString(UIStrings.resizeAnnouncementsPane)}
302
+ tabindex="0"
303
+ jslog=${VisualLogging.resizer('accessibility-announcements.resizer').track({
304
+ drag: true,
305
+ keydown: 'ArrowUp|ArrowDown',
306
+ })}
307
+ @pointerdown=${onResizerPointerDown}
308
+ @pointermove=${onResizerPointerMove}
309
+ @pointerup=${onResizerPointerUp}
310
+ @lostpointercapture=${onResizerPointerUp}
311
+ @keydown=${onResizerKeyDown}>
312
+ </div>
221
313
  </div>`,
222
314
  target);
223
315
  // clang-format on
@@ -10,7 +10,7 @@
10
10
  flex-direction: column;
11
11
  flex: auto;
12
12
  height: 100%;
13
- min-height: 0;
13
+ min-height: 150px;
14
14
  overflow: hidden;
15
15
  }
16
16
 
@@ -21,6 +21,7 @@
21
21
  flex-direction: column;
22
22
  flex: auto;
23
23
  height: 100%;
24
+ min-height: 150px;
24
25
  overflow: hidden;
25
26
  }
26
27
 
@@ -28,6 +29,7 @@
28
29
  font-family: inherit;
29
30
  flex: auto;
30
31
  height: 100%;
32
+ min-height: 150px;
31
33
  border: none;
32
34
  }
33
35
  }
@@ -20,6 +20,7 @@
20
20
  flex: auto;
21
21
  height: 100%;
22
22
  overflow: hidden;
23
+ position: relative;
23
24
  }
24
25
 
25
26
  .announcements-toolbar-container {
@@ -79,7 +80,17 @@
79
80
  display: flex;
80
81
  flex-direction: column;
81
82
  flex: auto;
82
- min-height: 0;
83
+ min-height: 150px;
83
84
  overflow: hidden;
84
85
  }
86
+
87
+ .announcements-resizer {
88
+ position: absolute;
89
+ left: 0;
90
+ right: 0;
91
+ bottom: 0;
92
+ height: var(--sys-size-4);
93
+ z-index: 4000;
94
+ cursor: ns-resize;
95
+ }
85
96
  }