chrome-devtools-frontend 1.0.1535712 → 1.0.1537268

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 (231) hide show
  1. package/docs/contributing/images/issues-nearestslo.png +0 -0
  2. package/docs/contributing/issues.md +17 -21
  3. package/front_end/core/common/Console.ts +1 -8
  4. package/front_end/core/common/ParsedURL.ts +10 -20
  5. package/front_end/core/common/SegmentedRange.ts +1 -2
  6. package/front_end/core/common/StringOutputStream.ts +1 -4
  7. package/front_end/core/host/AidaClient.ts +64 -5
  8. package/front_end/core/host/DispatchHttpRequestClient.ts +62 -0
  9. package/front_end/core/host/GdpClient.ts +8 -57
  10. package/front_end/core/host/host.ts +2 -0
  11. package/front_end/core/i18n/i18nImpl.ts +0 -24
  12. package/front_end/core/protocol_client/CDPConnection.ts +10 -8
  13. package/front_end/core/protocol_client/InspectorBackend.ts +36 -42
  14. package/front_end/core/sdk/AnimationModel.ts +1 -2
  15. package/front_end/core/sdk/CSSMatchedStyles.ts +2 -2
  16. package/front_end/core/sdk/CSSModel.ts +1 -1
  17. package/front_end/core/sdk/CSSProperty.ts +3 -6
  18. package/front_end/core/sdk/CSSStyleDeclaration.ts +4 -4
  19. package/front_end/core/sdk/DebuggerModel.ts +1 -2
  20. package/front_end/core/sdk/EnhancedTracesParser.ts +24 -5
  21. package/front_end/core/sdk/RehydratingConnection.ts +112 -4
  22. package/front_end/core/sdk/RehydratingObject.ts +8 -0
  23. package/front_end/core/sdk/SourceMap.ts +2 -3
  24. package/front_end/core/sdk/TraceObject.ts +5 -1
  25. package/front_end/entrypoints/node_app/NodeConnectionsPanel.ts +2 -1
  26. package/front_end/generated/InspectorBackendCommands.js +1 -2
  27. package/front_end/generated/SupportedCSSProperties.js +19 -0
  28. package/front_end/generated/protocol.ts +0 -27
  29. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  30. package/front_end/models/trace/types/File.ts +9 -0
  31. package/front_end/panels/accessibility/AccessibilityNodeView.ts +18 -17
  32. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +9 -12
  33. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -9
  34. package/front_end/panels/ai_assistance/components/ChatView.ts +63 -74
  35. package/front_end/panels/application/AppManifestView.ts +7 -6
  36. package/front_end/panels/application/ApplicationPanelSidebar.ts +4 -4
  37. package/front_end/panels/application/BackForwardCacheTreeElement.ts +2 -6
  38. package/front_end/panels/application/OpenedWindowDetailsView.ts +6 -6
  39. package/front_end/panels/application/StorageView.ts +9 -8
  40. package/front_end/panels/application/components/BackForwardCacheView.ts +366 -342
  41. package/front_end/panels/application/components/FrameDetailsView.ts +8 -11
  42. package/front_end/panels/application/components/OriginTrialTreeView.ts +65 -69
  43. package/front_end/panels/application/components/ProtocolHandlersView.ts +3 -2
  44. package/front_end/panels/application/components/backForwardCacheView.css +4 -0
  45. package/front_end/panels/application/components/badge.css +1 -1
  46. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -1
  47. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +44 -53
  48. package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +8 -8
  49. package/front_end/panels/common/BadgeNotification.ts +2 -1
  50. package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
  51. package/front_end/panels/console/ConsoleInsightTeaser.ts +8 -2
  52. package/front_end/panels/console/ConsolePinPane.ts +12 -7
  53. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +9 -9
  54. package/front_end/panels/elements/ComputedStyleWidget.ts +7 -7
  55. package/front_end/panels/elements/EventListenersWidget.ts +9 -9
  56. package/front_end/panels/elements/NodeStackTraceWidget.ts +6 -6
  57. package/front_end/panels/elements/PlatformFontsWidget.ts +5 -5
  58. package/front_end/panels/elements/PropertiesWidget.ts +8 -8
  59. package/front_end/panels/layer_viewer/Layers3DView.ts +2 -1
  60. package/front_end/panels/layer_viewer/PaintProfilerView.ts +3 -3
  61. package/front_end/panels/network/RequestCookiesView.ts +2 -1
  62. package/front_end/panels/network/RequestTimingView.ts +2 -1
  63. package/front_end/panels/recorder/RecorderController.ts +33 -23
  64. package/front_end/panels/recorder/components/CreateRecordingView.ts +259 -226
  65. package/front_end/panels/security/CookieControlsView.ts +2 -1
  66. package/front_end/panels/security/CookieReportView.ts +3 -2
  67. package/front_end/panels/settings/AISettingsTab.ts +164 -172
  68. package/front_end/panels/settings/KeybindsSettingsTab.ts +6 -0
  69. package/front_end/panels/settings/SettingsScreen.ts +3 -7
  70. package/front_end/panels/settings/aiSettingsTab.css +151 -148
  71. package/front_end/panels/settings/components/SyncSection.ts +2 -1
  72. package/front_end/panels/settings/settings-meta.ts +1 -2
  73. package/front_end/panels/sources/AddSourceMapURLDialog.ts +23 -26
  74. package/front_end/panels/sources/DebuggerPausedMessage.ts +4 -3
  75. package/front_end/panels/sources/ResourceOriginPlugin.ts +3 -2
  76. package/front_end/panels/sources/SourcesNavigator.ts +2 -1
  77. package/front_end/panels/sources/TabbedEditorContainer.ts +3 -2
  78. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +9 -9
  79. package/front_end/panels/timeline/TimelinePanel.ts +60 -11
  80. package/front_end/panels/timeline/TimelineUIUtils.ts +3 -2
  81. package/front_end/panels/timeline/components/DetailsView.ts +5 -4
  82. package/front_end/panels/timeline/components/ExportTraceOptions.ts +33 -34
  83. package/front_end/panels/timeline/components/FieldSettingsDialog.ts +2 -1
  84. package/front_end/panels/timeline/components/LiveMetricsView.ts +5 -4
  85. package/front_end/panels/timeline/components/MetricCompareStrings.ts +25 -24
  86. package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +2 -1
  87. package/front_end/third_party/chromium/README.chromium +2 -2
  88. package/front_end/third_party/puppeteer/README.chromium +2 -2
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +9 -1
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts +2 -2
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.js.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +13 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts +2 -2
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js +5 -2
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +2 -2
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -1
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +1 -12
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +6 -0
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -0
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +2 -2
  113. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -1
  115. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts +2 -1
  117. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +2 -2
  119. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +2 -2
  121. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -1
  123. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  124. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  126. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  127. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  129. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts +2 -2
  130. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts.map +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js +3 -1
  132. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js.map +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts +1 -0
  134. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts.map +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js +1 -0
  136. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js.map +1 -1
  137. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  139. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +28 -3
  140. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21 -10
  141. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +9 -1
  142. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts +2 -2
  145. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts.map +1 -1
  146. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.js.map +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts.map +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +13 -1
  150. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts +2 -2
  153. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js +5 -2
  155. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js.map +1 -1
  156. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +2 -2
  157. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  158. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -1
  159. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  160. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts +1 -12
  161. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +6 -0
  163. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  164. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -0
  165. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +2 -2
  167. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  168. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -1
  169. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  170. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts +2 -1
  171. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  172. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +2 -2
  173. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
  174. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +2 -2
  175. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  176. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +3 -1
  177. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  178. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  179. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  180. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  181. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts +2 -2
  182. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts.map +1 -1
  183. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js +2 -2
  184. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js.map +1 -1
  185. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts +1 -0
  186. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts.map +1 -1
  187. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js +1 -0
  188. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js.map +1 -1
  189. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  190. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  191. package/front_end/third_party/puppeteer/package/lib/types.d.ts +28 -3
  192. package/front_end/third_party/puppeteer/package/package.json +2 -2
  193. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +13 -1
  194. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +7 -2
  195. package/front_end/third_party/puppeteer/package/src/api/Page.ts +14 -1
  196. package/front_end/third_party/puppeteer/package/src/bidi/BrowserContext.ts +8 -5
  197. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +5 -2
  198. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +8 -0
  199. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +11 -2
  200. package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +3 -2
  201. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +5 -5
  202. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  203. package/front_end/third_party/puppeteer/package/src/util/disposable.ts +2 -2
  204. package/front_end/third_party/puppeteer/package/src/util/util.ts +1 -0
  205. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  206. package/front_end/ui/components/docs/tooltip/basic.ts +1 -1
  207. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +280 -0
  208. package/front_end/ui/components/text_editor/text_editor.ts +1 -0
  209. package/front_end/ui/components/tooltips/Tooltip.ts +33 -18
  210. package/front_end/ui/i18n/i18n.ts +31 -0
  211. package/front_end/ui/legacy/Dialog.ts +0 -1
  212. package/front_end/ui/legacy/SettingsUI.ts +0 -14
  213. package/front_end/ui/legacy/SoftDropDown.ts +1 -12
  214. package/front_end/ui/legacy/ViewManager.ts +2 -4
  215. package/front_end/ui/legacy/Widget.ts +33 -17
  216. package/front_end/ui/legacy/XLink.ts +0 -3
  217. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +9 -0
  218. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -1
  219. package/front_end/ui/legacy/components/utils/Linkifier.ts +9 -3
  220. package/front_end/ui/legacy/legacy.ts +0 -2
  221. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -1
  222. package/mcp/mcp.ts +6 -0
  223. package/package.json +1 -1
  224. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +0 -4
  225. package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.html +0 -20
  226. package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.ts +0 -25
  227. package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.html +0 -20
  228. package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.ts +0 -36
  229. package/front_end/ui/components/docs/recorder_create_recording_view/basic.html +0 -20
  230. package/front_end/ui/components/docs/recorder_create_recording_view/basic.ts +0 -27
  231. package/front_end/ui/legacy/ThrottledWidget.ts +0 -48
@@ -1,9 +1,7 @@
1
1
  // Copyright 2023 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
4
 
6
- import '../../../ui/legacy/legacy.js';
7
5
  import '../../../ui/components/icon_button/icon_button.js';
8
6
  import './ControlButton.js';
9
7
 
@@ -11,6 +9,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
11
9
  import * as Badges from '../../../models/badges/badges.js';
12
10
  import * as Buttons from '../../../ui/components/buttons/buttons.js';
13
11
  import * as Input from '../../../ui/components/input/input.js';
12
+ import * as UI from '../../../ui/legacy/legacy.js';
14
13
  import * as Lit from '../../../ui/lit/lit.js';
15
14
  import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
16
15
  import * as Models from '../models/models.js';
@@ -18,7 +17,7 @@ import * as Actions from '../recorder-actions/recorder-actions.js';
18
17
 
19
18
  import createRecordingViewStyles from './createRecordingView.css.js';
20
19
 
21
- const {html, Directives: {ifDefined}} = Lit;
20
+ const {html, Directives: {ref, createRef, repeat}} = Lit;
22
21
 
23
22
  const UIStrings = {
24
23
  /**
@@ -103,112 +102,248 @@ const str_ = i18n.i18n.registerUIStrings(
103
102
  );
104
103
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
105
104
 
106
- declare global {
107
- interface HTMLElementTagNameMap {
108
- 'devtools-create-recording-view': CreateRecordingView;
109
- }
110
- interface HTMLElementEventMap {
111
- recordingstarted: RecordingStartedEvent;
112
- recordingcancelled: RecordingCancelledEvent;
113
- }
114
- }
115
-
116
- export class RecordingStartedEvent extends Event {
117
- static readonly eventName = 'recordingstarted';
105
+ export interface ViewInput {
118
106
  name: string;
119
- selectorAttribute?: string;
120
- selectorTypesToRecord: Models.Schema.SelectorType[];
121
-
122
- constructor(
123
- name: string,
124
- selectorTypesToRecord: Models.Schema.SelectorType[],
125
- selectorAttribute?: string,
126
- ) {
127
- super(RecordingStartedEvent.eventName, {});
128
- this.name = name;
129
- this.selectorAttribute = selectorAttribute || undefined;
130
- this.selectorTypesToRecord = selectorTypesToRecord;
131
- }
107
+ selectorAttribute: string;
108
+ selectorTypes: Array<{
109
+ selectorType: Models.Schema.SelectorType,
110
+ checked: boolean,
111
+ }>;
112
+ error?: Error;
113
+ onRecordingStarted: () => void;
114
+ onRecordingCancelled: () => void;
115
+ onErrorReset: () => void;
116
+ onUpdate: (update: {
117
+ selectorType: Models.Schema.SelectorType,
118
+ checked: boolean,
119
+ }|{
120
+ name: string,
121
+ }|{
122
+ selectorAttribute: string,
123
+ }) => void;
132
124
  }
133
125
 
134
- export class RecordingCancelledEvent extends Event {
135
- static readonly eventName = 'recordingcancelled';
136
- constructor() {
137
- super(RecordingCancelledEvent.eventName);
138
- }
139
- }
140
-
141
- export interface CreateRecordingViewData {
142
- recorderSettings: Models.RecorderSettings.RecorderSettings;
126
+ export interface ViewOutput {
127
+ focusInput?: () => void;
143
128
  }
144
129
 
145
- export class CreateRecordingView extends HTMLElement {
146
- readonly #shadow = this.attachShadow({mode: 'open'});
147
- #defaultRecordingName = '';
148
- #error?: Error;
149
- #recorderSettings?: Models.RecorderSettings.RecorderSettings;
130
+ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
131
+ const {
132
+ name,
133
+ selectorAttribute,
134
+ selectorTypes,
135
+ error,
136
+ onUpdate,
137
+ onRecordingStarted,
138
+ onRecordingCancelled,
139
+ onErrorReset
140
+ } = input;
150
141
 
151
- constructor() {
152
- super();
153
- this.setAttribute('jslog', `${VisualLogging.section('create-recording-view')}`);
154
- }
142
+ const nameInputRef = createRef<HTMLInputElement>();
155
143
 
156
- connectedCallback(): void {
157
- this.#render();
158
- this.#shadow.querySelector('input')?.focus();
159
- }
160
-
161
- set data(data: CreateRecordingViewData) {
162
- this.#recorderSettings = data.recorderSettings;
163
- this.#defaultRecordingName = this.#recorderSettings.defaultTitle;
164
- }
165
-
166
- #onKeyDown(event: KeyboardEvent): void {
167
- if (this.#error) {
168
- this.#error = undefined;
169
- this.#render();
144
+ const onKeyDown = (event: KeyboardEvent): void => {
145
+ if (error) {
146
+ onErrorReset();
170
147
  }
171
148
 
172
149
  const keyboardEvent = event;
173
150
  if (keyboardEvent.key === 'Enter') {
174
- this.startRecording();
151
+ onRecordingStarted();
175
152
  event.stopPropagation();
176
153
  event.preventDefault();
177
154
  }
155
+ };
156
+
157
+ output.focusInput = () => {
158
+ nameInputRef.value?.focus();
159
+ };
160
+
161
+ const selectorTypeToLabel = new Map([
162
+ [Models.Schema.SelectorType.ARIA, i18nString(UIStrings.selectorTypeARIA)],
163
+ [Models.Schema.SelectorType.CSS, i18nString(UIStrings.selectorTypeCSS)],
164
+ [Models.Schema.SelectorType.Text, i18nString(UIStrings.selectorTypeText)],
165
+ [
166
+ Models.Schema.SelectorType.XPath,
167
+ i18nString(UIStrings.selectorTypeXPath),
168
+ ],
169
+ [
170
+ Models.Schema.SelectorType.Pierce,
171
+ i18nString(UIStrings.selectorTypePierce),
172
+ ],
173
+ ]);
174
+
175
+ // clang-format off
176
+ Lit.render(
177
+ html`
178
+ <style>${createRecordingViewStyles}</style>
179
+ <style>${Input.textInputStyles}</style>
180
+ <style>${Input.checkboxStyles}</style>
181
+ <div class="wrapper" jslog=${VisualLogging.section('create-recording-view')}>
182
+ <div class="header-wrapper">
183
+ <h1>${i18nString(UIStrings.createRecording)}</h1>
184
+ <devtools-button
185
+ title=${i18nString(UIStrings.cancelRecording)}
186
+ jslog=${VisualLogging.close().track({click: true})}
187
+ .data=${
188
+ {
189
+ variant: Buttons.Button.Variant.ICON,
190
+ size: Buttons.Button.Size.SMALL,
191
+ iconName: 'cross',
192
+ } as Buttons.Button.ButtonData
193
+ }
194
+ @click=${onRecordingCancelled}
195
+ ></devtools-button>
196
+ </div>
197
+ <label class="row-label" for="user-flow-name">${i18nString(
198
+ UIStrings.recordingName,
199
+ )}</label>
200
+ <input
201
+ value=${name}
202
+ @focus=${() => nameInputRef.value?.select()}
203
+ @keydown=${onKeyDown}
204
+ jslog=${VisualLogging.textField('user-flow-name').track({change: true})}
205
+ class="devtools-text-input"
206
+ id="user-flow-name"
207
+ ${ref(nameInputRef)}
208
+ @input=${(e:Event) => onUpdate({
209
+ name: (e.target as HTMLInputElement).value.trim()
210
+ })}
211
+ />
212
+ <label class="row-label" for="selector-attribute">
213
+ <span>${i18nString(UIStrings.selectorAttribute)}</span>
214
+ <x-link
215
+ class="link" href="https://g.co/devtools/recorder#selector"
216
+ title=${i18nString(UIStrings.learnMore)}
217
+ jslog=${VisualLogging.link('recorder-selector-help').track({click: true})}>
218
+ <devtools-icon name="help">
219
+ </devtools-icon>
220
+ </x-link>
221
+ </label>
222
+ <input
223
+ value=${selectorAttribute}
224
+ placeholder="data-testid"
225
+ @keydown=${onKeyDown}
226
+ jslog=${VisualLogging.textField('selector-attribute').track({change: true})}
227
+ class="devtools-text-input"
228
+ id="selector-attribute"
229
+ @input=${(e:Event) => onUpdate({
230
+ selectorAttribute: (e.target as HTMLInputElement).value.trim()
231
+ })}
232
+ />
233
+ <label class="row-label">
234
+ <span>${i18nString(UIStrings.selectorTypes)}</span>
235
+ <x-link
236
+ class="link" href="https://g.co/devtools/recorder#selector"
237
+ title=${i18nString(UIStrings.learnMore)}
238
+ jslog=${VisualLogging.link('recorder-selector-help').track({click: true})}>
239
+ <devtools-icon name="help">
240
+ </devtools-icon>
241
+ </x-link>
242
+ </label>
243
+ <div class="checkbox-container">
244
+ ${repeat(selectorTypes, item => {
245
+ return html`
246
+ <label class="checkbox-label selector-type">
247
+ <input
248
+ @keydown=${onKeyDown}
249
+ .value=${item.selectorType}
250
+ jslog=${VisualLogging.toggle().track({click: true}).context(`selector-${item.selectorType}`)}
251
+ ?checked=${item.checked}
252
+ type="checkbox"
253
+ @change=${(e:Event) => onUpdate({
254
+ selectorType: item.selectorType,
255
+ checked: (e.target as HTMLInputElement).checked
256
+ })}
257
+ />
258
+ ${selectorTypeToLabel.get(item.selectorType) || item.selectorType}
259
+ </label>
260
+ `;
261
+ })}
262
+ </div>
263
+ ${
264
+ error &&
265
+ html` <div class="error" role="alert"> ${error.message} </div>`
266
+ }
267
+ </div>
268
+ <div class="footer">
269
+ <div class="controls">
270
+ <devtools-control-button
271
+ @click=${onRecordingStarted}
272
+ .label=${i18nString(UIStrings.startRecording)}
273
+ .shape=${'circle'}
274
+ jslog=${VisualLogging.action(Actions.RecorderActions.START_RECORDING).track({click: true})}
275
+ title=${Models.Tooltip.getTooltipForActions(
276
+ i18nString(UIStrings.startRecording),
277
+ Actions.RecorderActions.START_RECORDING,
278
+ )}
279
+ ></devtools-control-button>
280
+ </div>
281
+ </div>
282
+ `,
283
+ target,
284
+ );
285
+ // clang-format on
286
+ };
287
+
288
+ export class CreateRecordingView extends UI.Widget.Widget {
289
+ #error?: Error;
290
+ #name = '';
291
+ #selectorAttribute = '';
292
+ #selectorTypes: Array<{
293
+ selectorType: Models.Schema.SelectorType,
294
+ checked: boolean,
295
+ }> = [];
296
+ #view: typeof DEFAULT_VIEW;
297
+ #output: ViewOutput = {};
298
+ #recorderSettings?: Models.RecorderSettings.RecorderSettings;
299
+
300
+ onRecordingStarted:
301
+ (data: {name: string, selectorTypesToRecord: Models.Schema.SelectorType[], selectorAttribute?: string}) => void =
302
+ () => {};
303
+ onRecordingCancelled = (): void => {};
304
+
305
+ set recorderSettings(value: Models.RecorderSettings.RecorderSettings) {
306
+ this.#recorderSettings = value;
307
+ this.#name = this.#recorderSettings.defaultTitle;
308
+ this.#selectorAttribute = this.#recorderSettings.selectorAttribute;
309
+ this.#selectorTypes = Object.values(Models.Schema.SelectorType).map(selectorType => {
310
+ return {
311
+ selectorType,
312
+ checked: this.#recorderSettings?.getSelectorByType(selectorType) ?? true,
313
+ };
314
+ }),
315
+ this.requestUpdate();
316
+ }
317
+
318
+ constructor(element?: HTMLElement, view?: typeof DEFAULT_VIEW) {
319
+ super(element, {useShadowDom: true});
320
+ this.#view = view || DEFAULT_VIEW;
321
+ }
322
+
323
+ override wasShown(): void {
324
+ super.wasShown();
325
+ this.requestUpdate();
326
+ void this.updateComplete.then(() => this.#output.focusInput?.());
178
327
  }
179
328
 
180
329
  startRecording(): void {
181
- const nameInput = this.#shadow.querySelector<HTMLInputElement>('#user-flow-name');
182
- if (!nameInput) {
183
- throw new Error('input#user-flow-name not found');
184
- }
185
330
  if (!this.#recorderSettings) {
186
331
  throw new Error('settings not set');
187
332
  }
188
333
 
189
- if (!nameInput.value.trim()) {
334
+ if (!this.#name.trim()) {
190
335
  this.#error = new Error(i18nString(UIStrings.recordingNameIsRequired));
191
- this.#render();
336
+ this.requestUpdate();
192
337
  return;
193
338
  }
194
339
 
195
- const selectorTypeElements = this.#shadow.querySelectorAll(
196
- '.selector-type input[type=checkbox]',
197
- );
198
- const selectorTypesToRecord: Models.Schema.SelectorType[] = [];
199
- for (const selectorType of selectorTypeElements) {
200
- const checkbox = selectorType as HTMLInputElement;
201
- const checkboxValue = checkbox.value as Models.Schema.SelectorType;
202
- if (checkbox.checked) {
203
- selectorTypesToRecord.push(checkboxValue);
204
- }
205
- }
340
+ const selectorTypesToRecord = this.#selectorTypes.filter(item => item.checked).map(item => item.selectorType);
206
341
 
207
342
  if (!selectorTypesToRecord.includes(Models.Schema.SelectorType.CSS) &&
208
343
  !selectorTypesToRecord.includes(Models.Schema.SelectorType.XPath) &&
209
344
  !selectorTypesToRecord.includes(Models.Schema.SelectorType.Pierce)) {
210
345
  this.#error = new Error(i18nString(UIStrings.includeNecessarySelectors));
211
- this.#render();
346
+ this.requestUpdate();
212
347
  return;
213
348
  }
214
349
 
@@ -219,156 +354,54 @@ export class CreateRecordingView extends HTMLElement {
219
354
  );
220
355
  }
221
356
 
222
- const selectorAttributeEl = this.#shadow.querySelector(
223
- '#selector-attribute',
224
- ) as HTMLInputElement;
225
- const selectorAttribute = selectorAttributeEl.value.trim();
226
- this.#recorderSettings.selectorAttribute = selectorAttribute;
357
+ const selectorAttribute = this.#selectorAttribute.trim();
358
+ if (selectorAttribute) {
359
+ this.#recorderSettings.selectorAttribute = selectorAttribute;
360
+ }
361
+
362
+ this.onRecordingStarted({
363
+ name: this.#name,
364
+ selectorTypesToRecord,
365
+ selectorAttribute: this.#selectorAttribute ? this.#selectorAttribute : undefined,
366
+ });
227
367
 
228
- this.dispatchEvent(
229
- new RecordingStartedEvent(
230
- nameInput.value.trim(),
231
- selectorTypesToRecord,
232
- selectorAttribute,
233
- ),
234
- );
235
368
  Badges.UserBadges.instance().recordAction(Badges.BadgeAction.RECORDER_RECORDING_STARTED);
236
369
  }
237
370
 
238
- #dispatchRecordingCancelled(): void {
239
- this.dispatchEvent(new RecordingCancelledEvent());
240
- }
241
-
242
- #onInputFocus = (): void => {
243
- (this.#shadow.querySelector('#user-flow-name') as HTMLInputElement)?.select();
244
- };
245
-
246
- #render(): void {
247
- const selectorTypeToLabel = new Map([
248
- [Models.Schema.SelectorType.ARIA, i18nString(UIStrings.selectorTypeARIA)],
249
- [Models.Schema.SelectorType.CSS, i18nString(UIStrings.selectorTypeCSS)],
250
- [Models.Schema.SelectorType.Text, i18nString(UIStrings.selectorTypeText)],
251
- [
252
- Models.Schema.SelectorType.XPath,
253
- i18nString(UIStrings.selectorTypeXPath),
254
- ],
255
- [
256
- Models.Schema.SelectorType.Pierce,
257
- i18nString(UIStrings.selectorTypePierce),
258
- ],
259
- ]);
260
- // clang-format off
261
- Lit.render(
262
- html`
263
- <style>${createRecordingViewStyles}</style>
264
- <style>${Input.textInputStyles}</style>
265
- <style>${Input.checkboxStyles}</style>
266
- <div class="wrapper">
267
- <div class="header-wrapper">
268
- <h1>${i18nString(UIStrings.createRecording)}</h1>
269
- <devtools-button
270
- title=${i18nString(UIStrings.cancelRecording)}
271
- jslog=${VisualLogging.close().track({click: true})}
272
- .data=${
273
- {
274
- variant: Buttons.Button.Variant.ICON,
275
- size: Buttons.Button.Size.SMALL,
276
- iconName: 'cross',
277
- } as Buttons.Button.ButtonData
278
- }
279
- @click=${this.#dispatchRecordingCancelled}
280
- ></devtools-button>
281
- </div>
282
- <label class="row-label" for="user-flow-name">${i18nString(
283
- UIStrings.recordingName,
284
- )}</label>
285
- <input
286
- value=${this.#defaultRecordingName}
287
- @focus=${this.#onInputFocus}
288
- @keydown=${this.#onKeyDown}
289
- jslog=${VisualLogging.textField('user-flow-name').track({change: true})}
290
- class="devtools-text-input"
291
- id="user-flow-name"
292
- />
293
- <label class="row-label" for="selector-attribute">
294
- <span>${i18nString(UIStrings.selectorAttribute)}</span>
295
- <x-link
296
- class="link" href="https://g.co/devtools/recorder#selector"
297
- title=${i18nString(UIStrings.learnMore)}
298
- jslog=${VisualLogging.link('recorder-selector-help').track({click: true})}>
299
- <devtools-icon name="help">
300
- </devtools-icon>
301
- </x-link>
302
- </label>
303
- <input
304
- value=${ifDefined(this.#recorderSettings?.selectorAttribute)}
305
- placeholder="data-testid"
306
- @keydown=${this.#onKeyDown}
307
- jslog=${VisualLogging.textField('selector-attribute').track({change: true})}
308
- class="devtools-text-input"
309
- id="selector-attribute"
310
- />
311
- <label class="row-label">
312
- <span>${i18nString(UIStrings.selectorTypes)}</span>
313
- <x-link
314
- class="link" href="https://g.co/devtools/recorder#selector"
315
- title=${i18nString(UIStrings.learnMore)}
316
- jslog=${VisualLogging.link('recorder-selector-help').track({click: true})}>
317
- <devtools-icon name="help">
318
- </devtools-icon>
319
- </x-link>
320
- </label>
321
- <div class="checkbox-container">
322
- ${Object.values(Models.Schema.SelectorType).map(selectorType => {
323
- const checked =
324
- this.#recorderSettings?.getSelectorByType(selectorType);
325
- return html`
326
- <label class="checkbox-label selector-type">
327
- <input
328
- @keydown=${this.#onKeyDown}
329
- .value=${selectorType}
330
- jslog=${VisualLogging.toggle().track({click: true}).context(`selector-${selectorType}`)}
331
- ?checked=${checked}
332
- type="checkbox"
333
- />
334
- ${selectorTypeToLabel.get(selectorType) || selectorType}
335
- </label>
336
- `;
337
- })}
338
- </div>
339
-
340
- ${
341
- this.#error &&
342
- html`
343
- <div class="error" role="alert">
344
- ${this.#error.message}
345
- </div>
346
- `
347
- }
348
- </div>
349
- <div class="footer">
350
- <div class="controls">
351
- <devtools-control-button
352
- @click=${this.startRecording}
353
- .label=${i18nString(UIStrings.startRecording)}
354
- .shape=${'circle'}
355
- jslog=${VisualLogging.action(Actions.RecorderActions.START_RECORDING).track({click: true})}
356
- title=${Models.Tooltip.getTooltipForActions(
357
- i18nString(UIStrings.startRecording),
358
- Actions.RecorderActions.START_RECORDING,
359
- )}
360
- ></devtools-control-button>
361
- </div>
362
- </div>
363
- `,
364
- this.#shadow,
365
- { host: this },
366
- );
367
- // clang-format on
371
+ override performUpdate(): void {
372
+ this.#view(
373
+ {
374
+ name: this.#name,
375
+ selectorAttribute: this.#selectorAttribute,
376
+ selectorTypes: this.#selectorTypes,
377
+ error: this.#error,
378
+ onRecordingCancelled: this.onRecordingCancelled,
379
+ onUpdate: update => {
380
+ if ('name' in update) {
381
+ this.#name = update.name;
382
+ } else if ('selectorAttribute' in update) {
383
+ this.#selectorAttribute = update.selectorAttribute;
384
+ } else {
385
+ this.#selectorTypes = this.#selectorTypes.map(item => {
386
+ if (item.selectorType === update.selectorType) {
387
+ return {
388
+ ...item,
389
+ checked: update.checked,
390
+ };
391
+ }
392
+ return item;
393
+ });
394
+ }
395
+ this.requestUpdate();
396
+ },
397
+ onRecordingStarted: (): void => {
398
+ this.startRecording();
399
+ },
400
+ onErrorReset: () => {
401
+ this.#error = undefined;
402
+ this.requestUpdate();
403
+ },
404
+ },
405
+ this.#output, this.contentElement);
368
406
  }
369
407
  }
370
-
371
- customElements.define(
372
- 'devtools-create-recording-view',
373
- CreateRecordingView,
374
- );
@@ -14,6 +14,7 @@ import * as Root from '../../core/root/root.js';
14
14
  import * as SDK from '../../core/sdk/sdk.js';
15
15
  import * as Buttons from '../../ui/components/buttons/buttons.js';
16
16
  import * as Input from '../../ui/components/input/input.js';
17
+ import * as uiI18n from '../../ui/i18n/i18n.js';
17
18
  import * as UI from '../../ui/legacy/legacy.js';
18
19
  import {Directives, html, nothing, render, type TemplateResult} from '../../ui/lit/lit.js';
19
20
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
@@ -113,7 +114,7 @@ const UIStrings = {
113
114
 
114
115
  const str_ = i18n.i18n.registerUIStrings('panels/security/CookieControlsView.ts', UIStrings);
115
116
  export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
116
- export const i18nFormatString = i18n.i18n.getFormatLocalizedString.bind(undefined, str_);
117
+ export const i18nFormatString = uiI18n.getFormatLocalizedString.bind(undefined, str_);
117
118
 
118
119
  export interface ViewInput {
119
120
  thirdPartyControlsDict: Root.Runtime.HostConfig['thirdPartyCookieControls'];
@@ -12,6 +12,7 @@ import * as SDK from '../../core/sdk/sdk.js';
12
12
  import * as Protocol from '../../generated/protocol.js';
13
13
  import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
14
14
  import type * as TextUtils from '../../models/text_utils/text_utils.js';
15
+ import * as uiI18n from '../../ui/i18n/i18n.js';
15
16
  import * as UI from '../../ui/legacy/legacy.js';
16
17
  import * as Lit from '../../ui/lit/lit.js';
17
18
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
@@ -448,7 +449,7 @@ export class CookieReportView extends UI.Widget.VBox {
448
449
  'https://github.com/privacysandbox/privacy-sandbox-dev-support/blob/main/3pc-migration-readiness.md',
449
450
  i18nString(UIStrings.guidance), undefined, undefined, 'readiness-list-link');
450
451
 
451
- return html`${i18n.i18n.getFormatLocalizedString(str_, UIStrings.gitHubResource, {
452
+ return html`${uiI18n.getFormatLocalizedString(str_, UIStrings.gitHubResource, {
452
453
  PH1: githubLink,
453
454
  })}`;
454
455
  }
@@ -461,7 +462,7 @@ export class CookieReportView extends UI.Widget.VBox {
461
462
  (domain.charAt(0) === '.' ? domain.substring(1) : domain),
462
463
  i18nString(UIStrings.reportedIssues), undefined, undefined, 'compatibility-lookup-link');
463
464
 
464
- return html`${i18n.i18n.getFormatLocalizedString(str_, UIStrings.gracePeriod, {
465
+ return html`${uiI18n.getFormatLocalizedString(str_, UIStrings.gracePeriod, {
465
466
  PH1: gracePeriodLink,
466
467
  })}`;
467
468
  }