chrome-devtools-frontend 1.0.1672388 → 1.0.1674545

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 (232) hide show
  1. package/eslint.config.mjs +3 -3
  2. package/front_end/core/common/SettingRegistration.ts +1 -26
  3. package/front_end/core/common/Settings.ts +4 -53
  4. package/front_end/core/host/UserMetrics.ts +127 -117
  5. package/front_end/core/protocol_client/PuppeteerDevToolsConnection.ts +42 -9
  6. package/front_end/core/root/Runtime.ts +7 -2
  7. package/front_end/core/sdk/NetworkManager.ts +0 -35
  8. package/front_end/core/sdk/SourceMap.ts +1 -19
  9. package/front_end/core/sdk/SourceMapManager.ts +75 -48
  10. package/front_end/core/sdk/SourceMapScopesInfo.ts +0 -62
  11. package/front_end/devtools_compatibility.js +1 -1
  12. package/front_end/generated/InspectorBackendCommands.ts +4 -3
  13. package/front_end/generated/{SupportedCSSProperties.js → SupportedCSSProperties.ts} +32 -1
  14. package/front_end/generated/protocol-mapping.d.ts +8 -0
  15. package/front_end/generated/protocol-proxy-api.d.ts +6 -0
  16. package/front_end/generated/protocol.ts +16 -2
  17. package/front_end/models/ai_assistance/AiSetting.ts +66 -3
  18. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +1 -1
  19. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +4 -3
  20. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +1 -1
  21. package/front_end/models/bindings/CompilerScriptMapping.ts +1 -1
  22. package/front_end/models/emulation/DeviceModeModel.ts +25 -34
  23. package/front_end/models/emulation/EmulatedDevices.ts +1 -1
  24. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -4
  25. package/front_end/models/trace/ModelImpl.ts +5 -0
  26. package/front_end/models/trace/Processor.ts +47 -10
  27. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +18 -19
  28. package/front_end/models/trace/handlers/MetaHandler.ts +46 -9
  29. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +11 -0
  30. package/front_end/models/trace/insights/CLSCulprits.ts +1 -2
  31. package/front_end/models/trace/insights/CharacterSet.ts +1 -1
  32. package/front_end/models/trace/insights/Common.ts +21 -2
  33. package/front_end/models/trace/insights/DocumentLatency.ts +1 -1
  34. package/front_end/models/trace/insights/LCPBreakdown.ts +7 -6
  35. package/front_end/models/trace/insights/LCPDiscovery.ts +1 -1
  36. package/front_end/models/trace/insights/ModernHTTP.ts +7 -3
  37. package/front_end/models/trace/insights/NetworkDependencyTree.ts +1 -1
  38. package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
  39. package/front_end/models/trace/insights/ThirdParties.ts +5 -2
  40. package/front_end/models/trace/insights/types.ts +11 -6
  41. package/front_end/models/trace/types/Configuration.ts +5 -0
  42. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -10
  43. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +3 -45
  44. package/front_end/panels/application/BackgroundServiceView.ts +42 -40
  45. package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
  46. package/front_end/panels/common/ExtensionServer.ts +7 -1
  47. package/front_end/panels/common/common.ts +0 -1
  48. package/front_end/panels/console/ConsoleInsightTeaser.ts +7 -6
  49. package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
  50. package/front_end/panels/elements/ClassesPaneWidget.ts +2 -2
  51. package/front_end/panels/elements/ElementsTreeElement.ts +56 -5
  52. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  53. package/front_end/panels/elements/components/AdornerManager.ts +1 -0
  54. package/front_end/panels/emulation/AdvancedApp.ts +3 -3
  55. package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -11
  56. package/front_end/panels/emulation/DeviceModeView.ts +234 -75
  57. package/front_end/panels/emulation/InspectedPagePlaceholder.ts +1 -1
  58. package/front_end/panels/emulation/deviceModeView.css +4 -21
  59. package/front_end/panels/emulation/emulation-meta.ts +4 -30
  60. package/front_end/panels/emulation/emulation.ts +0 -3
  61. package/front_end/panels/explain/components/ConsoleInsight.ts +11 -7
  62. package/front_end/panels/layers/LayersPanel.ts +2 -2
  63. package/front_end/panels/layers/layers-meta.ts +2 -2
  64. package/front_end/panels/lighthouse/LighthouseController.ts +3 -7
  65. package/front_end/panels/mobile_throttling/CPUThrottlingSelector.ts +313 -0
  66. package/front_end/panels/mobile_throttling/NetworkPanelIndicator.ts +0 -10
  67. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +23 -10
  68. package/front_end/panels/mobile_throttling/mobile_throttling.ts +3 -0
  69. package/front_end/panels/network/NetworkConfigView.ts +1 -71
  70. package/front_end/panels/network/networkConfigView.css +1 -2
  71. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +3 -3
  72. package/front_end/panels/profiler/HeapDetachedElementsView.ts +5 -5
  73. package/front_end/panels/profiler/HeapProfileView.ts +32 -32
  74. package/front_end/panels/profiler/HeapProfilerPanel.ts +2 -2
  75. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +33 -37
  76. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +26 -27
  77. package/front_end/panels/profiler/HeapSnapshotView.ts +48 -48
  78. package/front_end/panels/profiler/IsolateSelector.ts +10 -10
  79. package/front_end/panels/profiler/ModuleUIStrings.ts +25 -25
  80. package/front_end/panels/profiler/ProfileLauncherView.ts +6 -6
  81. package/front_end/panels/profiler/ProfilesPanel.ts +6 -6
  82. package/front_end/panels/profiler/WritableProfileHeader.ts +6 -6
  83. package/front_end/panels/profiler/profiler-meta.ts +7 -7
  84. package/front_end/panels/recorder/RecorderPanel.ts +1 -1
  85. package/front_end/panels/settings/AISettingsTab.ts +27 -23
  86. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +463 -13
  87. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +12 -17
  88. package/front_end/panels/timeline/TimelinePanel.ts +22 -35
  89. package/front_end/panels/timeline/components/CWVMetrics.ts +16 -3
  90. package/front_end/panels/timeline/components/LiveMetricsView.ts +27 -6
  91. package/front_end/panels/timeline/components/NetworkTrackWidget.ts +1 -1
  92. package/front_end/panels/timeline/components/components.ts +0 -4
  93. package/front_end/panels/timeline/components/cwvMetrics.css +4 -0
  94. package/front_end/panels/timeline/components/liveMetricsView.css +7 -17
  95. package/front_end/panels/timeline/components/metricValueStyles.css +17 -0
  96. package/front_end/third_party/chromium/README.chromium +1 -1
  97. package/front_end/third_party/puppeteer/README.chromium +2 -2
  98. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +64 -15
  99. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +65 -16
  100. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +50 -7
  101. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts +2 -1
  104. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js +5 -5
  106. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts +2 -1
  108. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js +8 -6
  110. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.d.ts.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.js +3 -0
  113. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +16 -1
  116. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.d.ts +5 -1
  118. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.d.ts.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js +11 -6
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js.map +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.d.ts.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.js +5 -0
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.js.map +1 -1
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +10 -0
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +4 -3
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts +27 -2
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts.map +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js +12 -1
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js.map +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +2 -2
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +2 -2
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js +2 -0
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts +2 -1
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts.map +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js +5 -4
  143. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  145. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  146. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/types.d.ts +64 -15
  149. package/front_end/third_party/puppeteer/package/package.json +2 -2
  150. package/front_end/third_party/puppeteer/package/src/api/Page.ts +50 -7
  151. package/front_end/third_party/puppeteer/package/src/bidi/BidiOverCdp.ts +9 -7
  152. package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +9 -6
  153. package/front_end/third_party/puppeteer/package/src/bidi/Dialog.ts +4 -0
  154. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +24 -1
  155. package/front_end/third_party/puppeteer/package/src/cdp/Connection.ts +11 -6
  156. package/front_end/third_party/puppeteer/package/src/cdp/Dialog.ts +7 -0
  157. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +11 -0
  158. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +7 -3
  159. package/front_end/third_party/puppeteer/package/src/common/Debug.ts +30 -5
  160. package/front_end/third_party/puppeteer/package/src/common/util.ts +2 -2
  161. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +2 -0
  162. package/front_end/third_party/puppeteer/package/src/node/ScreenRecorder.ts +6 -4
  163. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  164. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  165. package/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +0 -0
  166. package/front_end/third_party/source-map-scopes-codec/package/LICENSE +0 -0
  167. package/front_end/third_party/source-map-scopes-codec/package/README.md +0 -0
  168. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +0 -0
  169. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -1
  170. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +0 -0
  171. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +0 -0
  172. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +0 -0
  173. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +0 -0
  174. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +0 -0
  175. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +0 -0
  176. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +0 -0
  177. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +0 -0
  178. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +0 -0
  179. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +0 -0
  180. package/front_end/third_party/source-map-scopes-codec/package/deno.json +1 -1
  181. package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
  182. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +2 -0
  183. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -1
  184. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +2 -0
  185. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +0 -0
  186. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +0 -0
  187. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +0 -0
  188. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js +0 -0
  189. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +0 -0
  190. package/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +0 -0
  191. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +0 -0
  192. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +0 -0
  193. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +0 -0
  194. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +0 -0
  195. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +0 -0
  196. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +0 -0
  197. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +0 -0
  198. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +0 -0
  199. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +0 -0
  200. package/front_end/third_party/source-map-scopes-codec/package/src/mod.js +0 -0
  201. package/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +0 -0
  202. package/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +0 -0
  203. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js +0 -0
  204. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js.map +0 -0
  205. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +0 -0
  206. package/front_end/third_party/source-map-scopes-codec/package/src/util.js +0 -0
  207. package/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +0 -0
  208. package/front_end/third_party/source-map-scopes-codec/package/src/util.ts +0 -0
  209. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +0 -0
  210. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +0 -0
  211. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +0 -0
  212. package/front_end/ui/components/dialogs/ShortcutDialog.ts +2 -0
  213. package/front_end/ui/components/settings/SettingCheckbox.ts +4 -12
  214. package/front_end/ui/components/settings/settingCheckbox.css +0 -7
  215. package/front_end/ui/legacy/Treeoutline.ts +14 -14
  216. package/front_end/ui/legacy/UIUtils.ts +2 -47
  217. package/front_end/ui/legacy/Widget.ts +10 -2
  218. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +1 -1
  219. package/front_end/ui/lit/Directives.ts +80 -0
  220. package/front_end/ui/lit/lit.ts +1 -0
  221. package/front_end/ui/lit/render.ts +8 -0
  222. package/front_end/ui/visual_logging/KnownContextValues.ts +18 -0
  223. package/mcp/mcp.ts +1 -0
  224. package/package.json +1 -1
  225. package/front_end/panels/common/ThrottlingUtils.ts +0 -51
  226. package/front_end/panels/emulation/DeviceModeWrapper.ts +0 -248
  227. package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +0 -235
  228. package/front_end/panels/timeline/components/NetworkThrottlingSelector.ts +0 -245
  229. package/front_end/panels/timeline/components/cpuThrottlingSelector.css +0 -30
  230. package/front_end/panels/timeline/components/networkThrottlingSelector.css +0 -24
  231. /package/front_end/core/host/{UserMetricsEnums.d.ts → UserMetricsEnums.ts} +0 -0
  232. /package/front_end/generated/{ARIAProperties.js → ARIAProperties.ts} +0 -0
@@ -5,6 +5,9 @@
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
+ import * as Root from '../../core/root/root.js';
9
+ import * as SDK from '../../core/sdk/sdk.js';
10
+ import type * as Protocol from '../../generated/protocol.js';
8
11
  import * as EmulationModel from '../../models/emulation/emulation.js';
9
12
  import * as Geometry from '../../models/geometry/geometry.js';
10
13
  import * as UI from '../../ui/legacy/legacy.js';
@@ -13,6 +16,7 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
13
16
 
14
17
  import {DeviceModeToolbar} from './DeviceModeToolbar.js';
15
18
  import deviceModeViewStyles from './deviceModeView.css.js';
19
+ import {InspectedPagePlaceholder} from './InspectedPagePlaceholder.js';
16
20
  import {MediaQueryInspector} from './MediaQueryInspector.js';
17
21
 
18
22
  const {classMap, ref, styleMap} = Directives;
@@ -59,19 +63,15 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
59
63
 
60
64
  export interface DeviceModeViewInput {
61
65
  model: EmulationModel.DeviceModeModel.DeviceModeModel;
66
+ showDeviceMode: boolean;
62
67
  showMediaInspectorSetting: Common.Settings.Setting<boolean>;
63
68
  showRulersSetting: Common.Settings.Setting<boolean>;
64
- outlineImage: string;
65
- outlineImageLoaded: boolean;
66
- screenImage: string;
67
- screenImageLoaded: boolean;
68
69
  resizable: boolean;
69
70
  showRulers: boolean;
70
71
  showMediaInspector: boolean;
71
72
  scale: number;
72
73
  cachedCssScreenRect?: EmulationModel.DeviceModeModel.Rect;
73
74
  cachedCssVisiblePageRect?: EmulationModel.DeviceModeModel.Rect;
74
- cachedOutlineRect?: EmulationModel.DeviceModeModel.Rect;
75
75
  onApplyPresetSize: (size: number, e: Event) => void;
76
76
  bottomRightResizer: UI.ResizerWidget.ResizerWidget;
77
77
  bottomLeftResizer: UI.ResizerWidget.ResizerWidget;
@@ -84,8 +84,6 @@ export interface DeviceModeViewInput {
84
84
  leftResizerRef: (el?: Element) => void;
85
85
  bottomResizerRef: (el?: Element) => void;
86
86
  onDoubleclickBottomResizer: () => void;
87
- onOutlineImageLoaded: (success: boolean) => void;
88
- onScreenImageLoaded: (success: boolean) => void;
89
87
  }
90
88
 
91
89
  export type DeviceModeViewView = (
@@ -133,12 +131,11 @@ export const DEFAULT_DEVICE_MODE_VIEW: DeviceModeViewView = (
133
131
  '4K',
134
132
  ];
135
133
  // clang-format off
136
- render(html`
137
- ${UI.Widget.widget(DeviceModeToolbar, {model: input.model})}
134
+ render(input.showDeviceMode
135
+ ? html`${UI.Widget.widget(DeviceModeToolbar, {model: input.model})}
138
136
  <div class=${classMap({
139
137
  'device-mode-content-clip': true,
140
138
  vbox: true,
141
- 'device-mode-outline-visible': Boolean(input.outlineImage),
142
139
  'device-mode-rulers-visible': input.showRulers,
143
140
  })}>
144
141
  <div class="device-mode-presets-container" jslog=${VisualLogging.responsivePresets()}>
@@ -163,17 +160,6 @@ export const DEFAULT_DEVICE_MODE_VIEW: DeviceModeViewView = (
163
160
  }) : nothing}
164
161
  </div>
165
162
  <div class="device-mode-content-area">
166
- <img class="device-mode-outline-image fill"
167
- ?hidden=${!input.outlineImage || !input.outlineImageLoaded}
168
- style=${styleMap(input.cachedOutlineRect ? {
169
- left: `${input.cachedOutlineRect.left}px`,
170
- top: `${input.cachedOutlineRect.top}px`,
171
- width: `${input.cachedOutlineRect.width}px`,
172
- height: `${input.cachedOutlineRect.height}px`,
173
- } : {})}
174
- srcset=${input.outlineImage || nothing}
175
- @load=${(): void => input.onOutlineImageLoaded(true)}
176
- @error=${(): void => input.onOutlineImageLoaded(false)}>
177
163
  <div class="device-mode-screen-area"
178
164
  style=${styleMap(input.cachedCssScreenRect ? {
179
165
  left: `${input.cachedCssScreenRect.left}px`,
@@ -181,11 +167,6 @@ export const DEFAULT_DEVICE_MODE_VIEW: DeviceModeViewView = (
181
167
  width: `${input.cachedCssScreenRect.width}px`,
182
168
  height: `${input.cachedCssScreenRect.height}px`,
183
169
  } : {})}>
184
- <img class="device-mode-screen-image"
185
- ?hidden=${!input.screenImage || !input.screenImageLoaded}
186
- srcset=${input.screenImage || nothing}
187
- @load=${(): void => input.onScreenImageLoaded(true)}
188
- @error=${(): void => input.onScreenImageLoaded(false)}>
189
170
  <div class="device-mode-resizer device-mode-bottom-right-resizer"
190
171
  ?hidden=${!input.resizable}
191
172
  jslog=${VisualLogging.slider('device-mode-resizer').track({drag: true})}
@@ -224,7 +205,9 @@ export const DEFAULT_DEVICE_MODE_VIEW: DeviceModeViewView = (
224
205
  top: `${input.cachedCssVisiblePageRect.top}px`,
225
206
  width: `${input.cachedCssVisiblePageRect.width}px`,
226
207
  height: `${input.cachedCssVisiblePageRect.height}px`,
227
- } : {})}><slot></slot></div>
208
+ } : {})}>
209
+ ${widget(() => InspectedPagePlaceholder.instance(), {minimumSize: new Geometry.Size(1, 1)})}
210
+ </div>
228
211
  </div>
229
212
  ${input.showRulers ? html`
230
213
  <devtools-widget class="device-mode-ruler-top device-mode-ruler"
@@ -246,7 +229,9 @@ export const DEFAULT_DEVICE_MODE_VIEW: DeviceModeViewView = (
246
229
  ` : nothing}
247
230
  </div>
248
231
  </div>
249
- `, target, {
232
+ `
233
+ : widget(() => InspectedPagePlaceholder.instance(), {minimumSize: new Geometry.Size(150, 150)}),
234
+ target, {
250
235
  container: {
251
236
  classes: ['device-mode-view'],
252
237
  },
@@ -276,14 +261,11 @@ export class DeviceModeView extends UI.Widget.VBox {
276
261
  private resizeStart?: Geometry.Size;
277
262
  private cachedCssScreenRect?: EmulationModel.DeviceModeModel.Rect;
278
263
  private cachedCssVisiblePageRect?: EmulationModel.DeviceModeModel.Rect;
279
- private cachedOutlineRect?: EmulationModel.DeviceModeModel.Rect;
280
264
  private cachedMediaInspectorVisible?: boolean;
281
265
  private cachedShowRulers?: boolean;
282
266
  private cachedScale?: number;
283
- #outlineImageLoaded = false;
284
- #lastOutlineImageSrc?: string;
285
- #screenImageLoaded = false;
286
- #lastScreenImageSrc?: string;
267
+ readonly #toggleDeviceModeAction: UI.ActionRegistration.Action;
268
+ readonly #showDeviceModeSetting: Common.Settings.Setting<boolean>;
287
269
  #view: DeviceModeViewView;
288
270
 
289
271
  constructor(element?: HTMLElement, view: DeviceModeViewView = DEFAULT_DEVICE_MODE_VIEW) {
@@ -300,27 +282,27 @@ export class DeviceModeView extends UI.Widget.VBox {
300
282
  this.showRulersSetting = Common.Settings.Settings.instance().moduleSetting('emulation.show-rulers');
301
283
  this.showRulersSetting.addChangeListener(this.updateUI, this);
302
284
 
285
+ this.#toggleDeviceModeAction =
286
+ UI.ActionRegistry.ActionRegistry.instance().getAction('emulation.toggle-device-mode');
287
+ const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
288
+ this.#showDeviceModeSetting = model.enabledSetting();
289
+ this.#showDeviceModeSetting.setRequiresUserAction(Boolean(Root.Runtime.Runtime.queryParam('hasOtherClients')));
290
+ this.#showDeviceModeSetting.addChangeListener(this.requestUpdate.bind(this));
291
+ SDK.TargetManager.TargetManager.instance().addModelListener(SDK.OverlayModel.OverlayModel,
292
+ SDK.OverlayModel.Events.SCREENSHOT_REQUESTED,
293
+ this.screenshotRequestedFromOverlay, this);
294
+
303
295
  this.performUpdate();
304
296
  UI.ZoomManager.ZoomManager.instance().addEventListener(UI.ZoomManager.Events.ZOOM_CHANGED, this.zoomChanged, this);
305
297
  }
306
298
 
307
299
  override performUpdate(): void {
308
- if (this.#lastOutlineImageSrc !== this.model.outlineImage()) {
309
- this.#lastOutlineImageSrc = this.model.outlineImage();
310
- this.#outlineImageLoaded = false;
311
- }
312
- if (this.#lastScreenImageSrc !== this.model.screenImage()) {
313
- this.#lastScreenImageSrc = this.model.screenImage();
314
- this.#screenImageLoaded = false;
315
- }
300
+ this.#toggleDeviceModeAction.setToggled(this.#showDeviceModeSetting.get());
316
301
  const input: DeviceModeViewInput = {
317
302
  model: this.model,
303
+ showDeviceMode: this.#showDeviceModeSetting.get(),
318
304
  showMediaInspectorSetting: this.showMediaInspectorSetting,
319
305
  showRulersSetting: this.showRulersSetting,
320
- outlineImage: this.model.outlineImage(),
321
- outlineImageLoaded: this.#outlineImageLoaded,
322
- screenImage: this.model.screenImage(),
323
- screenImageLoaded: this.#screenImageLoaded,
324
306
  resizable: this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive,
325
307
  showRulers: this.showRulersSetting.get() && this.model.type() !== EmulationModel.DeviceModeModel.Type.None,
326
308
  showMediaInspector:
@@ -328,7 +310,6 @@ export class DeviceModeView extends UI.Widget.VBox {
328
310
  scale: this.model.scale(),
329
311
  cachedCssScreenRect: this.cachedCssScreenRect,
330
312
  cachedCssVisiblePageRect: this.cachedCssVisiblePageRect,
331
- cachedOutlineRect: this.cachedOutlineRect,
332
313
  onApplyPresetSize: (width: number, e: Event): void => {
333
314
  this.model.emulate(EmulationModel.DeviceModeModel.Type.Responsive, null, null);
334
315
  this.model.setWidthAndScaleToFit(width);
@@ -345,24 +326,40 @@ export class DeviceModeView extends UI.Widget.VBox {
345
326
  leftResizerRef: this.leftResizerRef,
346
327
  bottomResizerRef: this.bottomResizerRef,
347
328
  onDoubleclickBottomResizer: (): void => this.model.setHeight(0),
348
- onOutlineImageLoaded: (success: boolean): void => this.onOutlineImageLoaded(success),
349
- onScreenImageLoaded: (success: boolean): void => this.onScreenImageLoaded(success),
350
329
  };
351
330
  this.#view(input, undefined, this.contentElement);
352
331
  }
353
332
 
354
- private onOutlineImageLoaded(success: boolean): void {
355
- if (this.#outlineImageLoaded !== success) {
356
- this.#outlineImageLoaded = success;
357
- this.requestUpdate();
333
+ static #setNonEmulatedAvailableSize(): void {
334
+ const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
335
+ if (model.type() !== EmulationModel.DeviceModeModel.Type.None) {
336
+ return;
358
337
  }
338
+
339
+ const zoomFactor = UI.ZoomManager.ZoomManager.instance().zoomFactor();
340
+ const rect = InspectedPagePlaceholder.instance().element.getBoundingClientRect();
341
+ const availableSize =
342
+ new Geometry.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
343
+ model.setAvailableSize(availableSize, availableSize);
359
344
  }
360
345
 
361
- private onScreenImageLoaded(success: boolean): void {
362
- if (this.#screenImageLoaded !== success) {
363
- this.#screenImageLoaded = success;
364
- this.requestUpdate();
346
+ static captureScreenshot(fullSize?: boolean, clip?: Protocol.Page.Viewport): boolean {
347
+ const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
348
+
349
+ this.#setNonEmulatedAvailableSize();
350
+ if (fullSize) {
351
+ void model.captureFullSizeScreenshot();
352
+ } else if (clip) {
353
+ void model.captureAreaScreenshot(clip);
354
+ } else {
355
+ void model.captureScreenshot();
365
356
  }
357
+ return true;
358
+ }
359
+
360
+ private screenshotRequestedFromOverlay(event: Common.EventTarget.EventTargetEvent<Protocol.Page.Viewport>): void {
361
+ const clip = event.data;
362
+ DeviceModeView.captureScreenshot(false, clip);
366
363
  }
367
364
 
368
365
  private createResizer(widthFactor: number, heightFactor: number): UI.ResizerWidget.ResizerWidget {
@@ -375,10 +372,20 @@ export class DeviceModeView extends UI.Widget.VBox {
375
372
  cursor = 'nesw-resize';
376
373
  }
377
374
  resizer.setCursor(cursor);
378
- resizer.addEventListener(UI.ResizerWidget.Events.RESIZE_START, this.onResizeStart, this);
379
375
  resizer.addEventListener(
380
- UI.ResizerWidget.Events.RESIZE_UPDATE_XY, this.onResizeUpdate.bind(this, widthFactor, heightFactor));
381
- resizer.addEventListener(UI.ResizerWidget.Events.RESIZE_END, this.onResizeEnd, this);
376
+ UI.ResizerWidget.Events.RESIZE_START,
377
+ this.onResizeStart,
378
+ this,
379
+ );
380
+ resizer.addEventListener(
381
+ UI.ResizerWidget.Events.RESIZE_UPDATE_XY,
382
+ this.onResizeUpdate.bind(this, widthFactor, heightFactor),
383
+ );
384
+ resizer.addEventListener(
385
+ UI.ResizerWidget.Events.RESIZE_END,
386
+ this.onResizeEnd,
387
+ this,
388
+ );
382
389
  return resizer;
383
390
  }
384
391
 
@@ -456,15 +463,6 @@ export class DeviceModeView extends UI.Widget.VBox {
456
463
  this.cachedCssVisiblePageRect = cssVisiblePageRect;
457
464
  }
458
465
 
459
- const outlineRectFromModel = this.model.outlineRect();
460
- if (outlineRectFromModel) {
461
- const outlineRect = outlineRectFromModel.scale(1 / zoomFactor);
462
- if (!this.cachedOutlineRect || !outlineRect.isEqual(this.cachedOutlineRect)) {
463
- callDoResize = true;
464
- this.cachedOutlineRect = outlineRect;
465
- }
466
- }
467
-
468
466
  const mediaInspectorVisible =
469
467
  this.showMediaInspectorSetting.get() && this.model.type() !== EmulationModel.DeviceModeModel.Type.None;
470
468
  if (mediaInspectorVisible !== this.cachedMediaInspectorVisible) {
@@ -485,12 +483,14 @@ export class DeviceModeView extends UI.Widget.VBox {
485
483
  }
486
484
 
487
485
  this.requestUpdate();
488
- if (callDoResize) {
489
- this.doResize();
490
- }
491
- if (contentAreaResized) {
492
- this.contentAreaResized();
493
- }
486
+ void this.updateComplete.then(() => {
487
+ if (callDoResize) {
488
+ this.doResize();
489
+ }
490
+ if (contentAreaResized) {
491
+ this.contentAreaResized();
492
+ }
493
+ });
494
494
  }
495
495
 
496
496
  private contentAreaResized(): void {
@@ -498,8 +498,8 @@ export class DeviceModeView extends UI.Widget.VBox {
498
498
  if (!contentArea) {
499
499
  return;
500
500
  }
501
- const zoomFactor = UI.ZoomManager.ZoomManager.instance().zoomFactor();
502
501
  const rect = contentArea.getBoundingClientRect();
502
+ const zoomFactor = UI.ZoomManager.ZoomManager.instance().zoomFactor();
503
503
  const handleWidth = this.contentElement.querySelector<HTMLElement>('.device-mode-right-resizer')?.offsetWidth || 20;
504
504
  const handleHeight =
505
505
  this.contentElement.querySelector<HTMLElement>('.device-mode-bottom-resizer')?.offsetHeight || 20;
@@ -673,3 +673,162 @@ export class Ruler extends Common.ObjectWrapper.eventMixin<RulerEventTypes, type
673
673
  this.#view(viewInput, undefined, this.contentElement);
674
674
  }
675
675
  }
676
+
677
+ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
678
+ handleAction(context: UI.Context.Context, actionId: string): boolean {
679
+ switch (actionId) {
680
+ case 'emulation.capture-screenshot':
681
+ return DeviceModeView.captureScreenshot();
682
+
683
+ case 'emulation.capture-node-screenshot': {
684
+ const node = context.flavor(SDK.DOMModel.DOMNode);
685
+ if (!node) {
686
+ return true;
687
+ }
688
+ async function captureClip(): Promise<void> {
689
+ if (!node) {
690
+ return;
691
+ }
692
+
693
+ // Resolve to a remote object to ensure the node is alive in the context.
694
+ const object = await node.resolveToObject();
695
+ if (!object) {
696
+ return;
697
+ }
698
+
699
+ // Get the Box Model via CDP.
700
+ // This returns the quads relative to the target's viewport.
701
+ // We use the 'border' quad to include the border and padding in the screenshot,
702
+ // matching the 'width' and 'height' properties which are also Border Box dimensions.
703
+ const nodeBoxModel = await node.boxModel();
704
+ if (!nodeBoxModel) {
705
+ throw new Error(`Unable to get box model of the node: ${new Error().stack}`);
706
+ }
707
+ const nodeBorderQuad = nodeBoxModel.border;
708
+ // Calculate the rendered bounding box from the border quad to account for CSS scaling and transforms (e.g. zoom or transform: scale).
709
+ const {minX, maxX, minY, maxY} = getQuadBoundingBox(nodeBorderQuad);
710
+
711
+ // Get Layout Metrics to account for the Visual Viewport scroll and zoom.
712
+ const metrics = await node.domModel().target().pageAgent().invoke_getLayoutMetrics();
713
+ if (metrics.getError()) {
714
+ throw new Error(`Unable to get metrics: ${new Error().stack}`);
715
+ }
716
+
717
+ const scrollX = metrics.cssVisualViewport.pageX;
718
+ const scrollY = metrics.cssVisualViewport.pageY;
719
+
720
+ // Calculate the global offset for OOPiFs (Out-of-Process iframes).
721
+ // This accounts for the position of the target's frame within the main page.
722
+ const {x: oopifOffsetX, y: oopifOffsetY} = await getOopifOffset(node.domModel().target());
723
+
724
+ // Assemble the final Clip.
725
+ // The absolute coordinates are: Global (OOPiF) + Viewport Scroll + Local Node Position (Border Box).
726
+ const clip = {
727
+ x: oopifOffsetX + scrollX + minX,
728
+ y: oopifOffsetY + scrollY + minY,
729
+ width: maxX - minX,
730
+ height: maxY - minY,
731
+ scale: 1,
732
+ };
733
+
734
+ // Apply Zoom factor.
735
+ const zoom = metrics.cssVisualViewport.zoom ?? 1;
736
+ clip.x *= zoom;
737
+ clip.y *= zoom;
738
+ clip.width *= zoom;
739
+ clip.height *= zoom;
740
+ DeviceModeView.captureScreenshot(false, clip);
741
+ }
742
+ void captureClip();
743
+ return true;
744
+ }
745
+
746
+ case 'emulation.capture-full-height-screenshot':
747
+ return DeviceModeView.captureScreenshot(true);
748
+
749
+ case 'emulation.toggle-device-mode': {
750
+ const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
751
+ model.toggleDeviceMode();
752
+ return true;
753
+ }
754
+ }
755
+ return false;
756
+ }
757
+ }
758
+
759
+ /**
760
+ * Calculate the offset of the "Local Root" frame relative to the "Global Root" (the main frame).
761
+ * This involves traversing the CDP Targets for OOPiFs.
762
+ */
763
+ async function getOopifOffset(target: SDK.Target.Target|null): Promise<{x: number, y: number}> {
764
+ if (!target) {
765
+ return {x: 0, y: 0};
766
+ }
767
+
768
+ // Get the parent target. If there's no parent (we are at root) or it's not a frame, we are done.
769
+ const parentTarget = target.parentTarget();
770
+ if (!parentTarget || parentTarget.type() !== SDK.Target.Type.FRAME) {
771
+ return {x: 0, y: 0};
772
+ }
773
+
774
+ // Identify the current frame's ID to find its owner in the parent.
775
+ const frameId = target.model(SDK.ResourceTreeModel.ResourceTreeModel)?.mainFrame?.id;
776
+ if (!frameId) {
777
+ return {x: 0, y: 0};
778
+ }
779
+
780
+ // Get the DOMModel of the parent to query the frame owner element.
781
+ const parentDOMModel = parentTarget.model(SDK.DOMModel.DOMModel);
782
+ if (!parentDOMModel) {
783
+ return {x: 0, y: 0};
784
+ }
785
+
786
+ // Retrieve the frame owner node (e.g. the <iframe> element) in the parent's document.
787
+ const frameOwnerDeferred = await parentDOMModel.getOwnerNodeForFrame(frameId);
788
+ const frameOwner = await frameOwnerDeferred?.resolvePromise();
789
+ if (!frameOwner) {
790
+ return {x: 0, y: 0};
791
+ }
792
+
793
+ // Get the content box of the iframe element.
794
+ // This is relative to the parent target's viewport.
795
+ const boxModel = await frameOwner.boxModel();
796
+ if (!boxModel) {
797
+ return {x: 0, y: 0};
798
+ }
799
+
800
+ // content is a Quad [x1, y1, x2, y2, x3, y3, x4, y4]
801
+ const contentQuad = boxModel.content;
802
+ const iframeContentX = contentQuad[0];
803
+ const iframeContentY = contentQuad[1];
804
+
805
+ // Get the scroll position of the parent target to convert viewport-relative coordinates
806
+ // to document-relative coordinates.
807
+ const parentMetrics = await parentTarget.pageAgent().invoke_getLayoutMetrics();
808
+ if (parentMetrics.getError()) {
809
+ return {x: 0, y: 0};
810
+ }
811
+
812
+ const scrollX = parentMetrics.cssVisualViewport.pageX;
813
+ const scrollY = parentMetrics.cssVisualViewport.pageY;
814
+
815
+ // Recursively add the offset of the parent target itself (if it is also an OOPiF).
816
+ const parentOffset = await getOopifOffset(parentTarget);
817
+
818
+ return {
819
+ x: iframeContentX + scrollX + parentOffset.x,
820
+ y: iframeContentY + scrollY + parentOffset.y,
821
+ };
822
+ }
823
+
824
+ /**
825
+ * Calculate the axis-aligned bounding box for a Quad [x1, y1, x2, y2, x3, y3, x4, y4].
826
+ * This accounts for CSS scaling and transforms (e.g. zoom, transform: scale).
827
+ */
828
+ function getQuadBoundingBox(quad: Protocol.DOM.Quad): {minX: number, maxX: number, minY: number, maxY: number} {
829
+ const minX = Math.min(quad[0], quad[2], quad[4], quad[6]);
830
+ const maxX = Math.max(quad[0], quad[2], quad[4], quad[6]);
831
+ const minY = Math.min(quad[1], quad[3], quad[5], quad[7]);
832
+ const maxY = Math.max(quad[1], quad[3], quad[5], quad[7]);
833
+ return {minX, maxX, minY, maxY};
834
+ }
@@ -20,7 +20,7 @@ export class InspectedPagePlaceholder extends Common.ObjectWrapper.eventMixin<Ev
20
20
  }
21
21
 
22
22
  static instance(opts: {
23
- forceNew: null,
23
+ forceNew: boolean|null,
24
24
  } = {forceNew: null}): InspectedPagePlaceholder {
25
25
  const {forceNew} = opts;
26
26
  if (!inspectedPagePlaceholderInstance || forceNew) {
@@ -83,7 +83,7 @@ devtools-toolbar.device-mode-toolbar-options {
83
83
  box-shadow: inset 0 -1px var(--sys-color-divider);
84
84
  }
85
85
 
86
- .device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-media-container {
86
+ .device-mode-content-clip .device-mode-media-container {
87
87
  margin-bottom: 20px;
88
88
  }
89
89
 
@@ -157,25 +157,17 @@ devtools-toolbar.device-mode-toolbar-options {
157
157
  background-color: var(--sys-color-inverse-surface);
158
158
  }
159
159
 
160
- .device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-screen-area {
160
+ .device-mode-content-clip .device-mode-screen-area {
161
161
  --override-screen-area-box-shadow: hsl(240deg 3% 84%) 0 0 0 0.5px, hsl(0deg 0% 80% / 40%) 0 0 20px;
162
162
 
163
163
  box-shadow: var(--override-screen-area-box-shadow);
164
164
  }
165
165
 
166
- .theme-with-dark-background .device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-screen-area,
167
- :host-context(.theme-with-dark-background) .device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-screen-area {
166
+ .theme-with-dark-background .device-mode-content-clip .device-mode-screen-area,
167
+ :host-context(.theme-with-dark-background) .device-mode-content-clip .device-mode-screen-area {
168
168
  --override-screen-area-box-shadow: rgb(40 40 42) 0 0 0 0.5px, rgb(51 51 51 / 40%) 0 0 20px;
169
169
  }
170
170
 
171
- .device-mode-screen-image {
172
- position: absolute;
173
- left: 0;
174
- top: 0;
175
- width: 100%;
176
- height: 100%;
177
- }
178
-
179
171
  .device-mode-resizer {
180
172
  position: absolute;
181
173
  display: flex;
@@ -316,15 +308,6 @@ devtools-toolbar.device-mode-toolbar-options {
316
308
  bottom: 0;
317
309
  }
318
310
 
319
- .device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-top .device-mode-ruler-content {
320
- border-top: 1px solid var(--sys-color-token-subtle);
321
- }
322
-
323
- .device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-left .device-mode-ruler-content {
324
- border-left: 1px solid var(--sys-color-token-subtle);
325
- border-top: 1px solid var(--sys-color-token-subtle);
326
- }
327
-
328
311
  .device-mode-ruler-inner {
329
312
  position: absolute;
330
313
  }
@@ -51,14 +51,6 @@ const UIStrings = {
51
51
  * @description Command that hides measuring rulers next to the emulated device.
52
52
  */
53
53
  hideRulers: 'Hide rulers in the device mode toolbar',
54
- /**
55
- * @description Command that shows a frame around the emulated device.
56
- */
57
- showDeviceFrame: 'Show device frame',
58
- /**
59
- * @description Command that hides a frame around the emulated device.
60
- */
61
- hideDeviceFrame: 'Hide device frame',
62
54
 
63
55
  } as const;
64
56
  const str_ = i18n.i18n.registerUIStrings('panels/emulation/emulation-meta.ts', UIStrings);
@@ -79,7 +71,7 @@ UI.ActionRegistration.registerActionExtension({
79
71
  toggleable: true,
80
72
  async loadActionDelegate() {
81
73
  const Emulation = await loadEmulationModule();
82
- return new Emulation.DeviceModeWrapper.ActionDelegate();
74
+ return new Emulation.DeviceModeView.ActionDelegate();
83
75
  },
84
76
  condition: Root.Runtime.conditions.canDock,
85
77
  title: i18nLazyString(UIStrings.toggleDeviceToolbar),
@@ -101,7 +93,7 @@ UI.ActionRegistration.registerActionExtension({
101
93
  category: UI.ActionRegistration.ActionCategory.SCREENSHOT,
102
94
  async loadActionDelegate() {
103
95
  const Emulation = await loadEmulationModule();
104
- return new Emulation.DeviceModeWrapper.ActionDelegate();
96
+ return new Emulation.DeviceModeView.ActionDelegate();
105
97
  },
106
98
  condition: Root.Runtime.conditions.canDock,
107
99
  title: i18nLazyString(UIStrings.captureScreenshot),
@@ -112,7 +104,7 @@ UI.ActionRegistration.registerActionExtension({
112
104
  category: UI.ActionRegistration.ActionCategory.SCREENSHOT,
113
105
  async loadActionDelegate() {
114
106
  const Emulation = await loadEmulationModule();
115
- return new Emulation.DeviceModeWrapper.ActionDelegate();
107
+ return new Emulation.DeviceModeView.ActionDelegate();
116
108
  },
117
109
  condition: Root.Runtime.conditions.canDock,
118
110
  title: i18nLazyString(UIStrings.captureFullSizeScreenshot),
@@ -123,7 +115,7 @@ UI.ActionRegistration.registerActionExtension({
123
115
  category: UI.ActionRegistration.ActionCategory.SCREENSHOT,
124
116
  async loadActionDelegate() {
125
117
  const Emulation = await loadEmulationModule();
126
- return new Emulation.DeviceModeWrapper.ActionDelegate();
118
+ return new Emulation.DeviceModeView.ActionDelegate();
127
119
  },
128
120
  condition: Root.Runtime.conditions.canDock,
129
121
  title: i18nLazyString(UIStrings.captureNodeScreenshot),
@@ -165,24 +157,6 @@ Common.Settings.registerSettingExtension({
165
157
  tags: [i18nLazyString(UIStrings.device)],
166
158
  });
167
159
 
168
- Common.Settings.registerSettingExtension({
169
- category: Common.Settings.SettingCategory.MOBILE,
170
- settingName: 'emulation.show-device-outline',
171
- settingType: Common.Settings.SettingType.BOOLEAN,
172
- defaultValue: false,
173
- options: [
174
- {
175
- value: true,
176
- title: i18nLazyString(UIStrings.showDeviceFrame),
177
- },
178
- {
179
- value: false,
180
- title: i18nLazyString(UIStrings.hideDeviceFrame),
181
- },
182
- ],
183
- tags: [i18nLazyString(UIStrings.device)],
184
- });
185
-
186
160
  UI.Toolbar.registerToolbarItem({
187
161
  actionId: 'emulation.toggle-device-mode',
188
162
  condition: Root.Runtime.conditions.canDock,
@@ -7,12 +7,10 @@ import './InspectedPagePlaceholder.js';
7
7
  import './MediaQueryInspector.js';
8
8
  import './DeviceModeToolbar.js';
9
9
  import './DeviceModeView.js';
10
- import './DeviceModeWrapper.js';
11
10
 
12
11
  import * as AdvancedApp from './AdvancedApp.js';
13
12
  import * as DeviceModeToolbar from './DeviceModeToolbar.js';
14
13
  import * as DeviceModeView from './DeviceModeView.js';
15
- import * as DeviceModeWrapper from './DeviceModeWrapper.js';
16
14
  import * as InspectedPagePlaceholder from './InspectedPagePlaceholder.js';
17
15
  import * as MediaQueryInspector from './MediaQueryInspector.js';
18
16
 
@@ -20,7 +18,6 @@ export {
20
18
  AdvancedApp,
21
19
  DeviceModeToolbar,
22
20
  DeviceModeView,
23
- DeviceModeWrapper,
24
21
  InspectedPagePlaceholder,
25
22
  MediaQueryInspector,
26
23
  };
@@ -780,7 +780,7 @@ export class ConsoleInsight extends UI.Widget.Widget {
780
780
  // Rating sub-form state.
781
781
  #selectedRating?: boolean;
782
782
 
783
- #consoleInsightsEnabledSetting: Common.Settings.Setting<boolean>|undefined;
783
+ #consoleInsightsEnabledSetting: AiAssistanceModel.AiSetting.AiSetting<boolean>;
784
784
  #aidaPreconditions: Host.AidaClient.AidaAccessPreconditions;
785
785
  #boundOnAidaAvailabilityChange:
786
786
  (ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>) => void;
@@ -861,10 +861,12 @@ export class ConsoleInsight extends UI.Widget.Widget {
861
861
 
862
862
  // off -> entrypoints are shown, and point to the AI setting panel where the setting can be turned on
863
863
  // on -> entrypoints are shown, and console insights can be generated
864
- #getConsoleInsightsEnabledSetting(): Common.Settings.Setting<boolean>|undefined {
865
- const result = Common.Settings.Settings.instance().maybeResolve(
866
- AiAssistanceModel.AiUtils.consoleInsightsEnabledSettingDescriptor);
867
- return 'setting' in result ? (result.setting as Common.Settings.Setting<boolean>) : undefined;
864
+ #getConsoleInsightsEnabledSetting(): AiAssistanceModel.AiSetting.AiSetting<boolean> {
865
+ return new AiAssistanceModel.AiSetting.AiSetting(
866
+ AiAssistanceModel.AiUtils.consoleInsightsEnabledSettingDescriptor,
867
+ Host.AidaClient.HostConfigTracker.instance(),
868
+ Common.Settings.Settings.instance(),
869
+ );
868
870
  }
869
871
 
870
872
  // off -> consent reminder is shown, unless the 'console-insights-enabled'-setting has been enabled in the current DevTools session
@@ -876,7 +878,8 @@ export class ConsoleInsight extends UI.Widget.Widget {
876
878
  override wasShown(): void {
877
879
  super.wasShown();
878
880
  this.focus();
879
- this.#consoleInsightsEnabledSetting?.addChangeListener(this.#onConsoleInsightsSettingChanged, this);
881
+ this.#consoleInsightsEnabledSetting.addEventListener(AiAssistanceModel.AiSetting.Events.CHANGED,
882
+ this.#onConsoleInsightsSettingChanged, this);
880
883
  const blockedByAge = Root.Runtime.hostConfig.aidaAvailability?.blockedByAge === true;
881
884
  if (this.#state.type === State.LOADING && this.#consoleInsightsEnabledSetting?.getIfNotDisabled() === true &&
882
885
  !blockedByAge && this.#state.consentOnboardingCompleted) {
@@ -899,7 +902,8 @@ export class ConsoleInsight extends UI.Widget.Widget {
899
902
 
900
903
  override willHide(): void {
901
904
  super.willHide();
902
- this.#consoleInsightsEnabledSetting?.removeChangeListener(this.#onConsoleInsightsSettingChanged, this);
905
+ this.#consoleInsightsEnabledSetting.removeEventListener(AiAssistanceModel.AiSetting.Events.CHANGED,
906
+ this.#onConsoleInsightsSettingChanged, this);
903
907
  Host.AidaClient.HostConfigTracker.instance().removeEventListener(
904
908
  Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
905
909
  }
@@ -14,11 +14,11 @@ import {Events, LayerTreeModel} from './LayerTreeModel.js';
14
14
 
15
15
  const UIStrings = {
16
16
  /**
17
- * @description Text for the details of something
17
+ * @description Title of the details tab in the Layers panel.
18
18
  */
19
19
  details: 'Details',
20
20
  /**
21
- * @description Title of the Profiler tool
21
+ * @description Title of the profiler tab in the Layers panel.
22
22
  */
23
23
  profiler: 'Profiler',
24
24
  } as const;