chrome-devtools-frontend 1.0.1672557 → 1.0.1675430

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 (177) hide show
  1. package/.agents/skills/devtools-ux-writing-refactor/SKILL.md +26 -9
  2. package/front_end/core/common/ParsedURL.ts +5 -1
  3. package/front_end/core/common/SettingRegistration.ts +30 -34
  4. package/front_end/core/common/Settings.ts +4 -64
  5. package/front_end/core/host/UserMetrics.ts +127 -117
  6. package/front_end/core/protocol_client/PuppeteerDevToolsConnection.ts +42 -9
  7. package/front_end/core/root/Runtime.ts +14 -0
  8. package/front_end/core/sdk/NetworkManager.ts +0 -35
  9. package/front_end/core/sdk/SourceMap.ts +1 -19
  10. package/front_end/core/sdk/SourceMapManager.ts +75 -48
  11. package/front_end/core/sdk/SourceMapScopesInfo.ts +0 -62
  12. package/front_end/core/sdk/TargetManager.ts +18 -0
  13. package/front_end/devtools_compatibility.js +1 -1
  14. package/front_end/entrypoints/main/MainImpl.ts +1 -0
  15. package/front_end/foundation/Universe.ts +44 -29
  16. package/front_end/generated/InspectorBackendCommands.ts +4 -3
  17. package/front_end/generated/SupportedCSSProperties.ts +16 -1
  18. package/front_end/generated/protocol-mapping.d.ts +8 -0
  19. package/front_end/generated/protocol-proxy-api.d.ts +6 -0
  20. package/front_end/generated/protocol.ts +16 -2
  21. package/front_end/models/ai_assistance/AiSetting.ts +66 -3
  22. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -5
  23. package/front_end/models/bindings/CompilerScriptMapping.ts +1 -1
  24. package/front_end/models/emulation/DeviceModeModel.ts +82 -102
  25. package/front_end/models/emulation/EmulatedDevices.ts +18 -66
  26. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -4
  27. package/front_end/models/persistence/AutomaticFileSystemManager.ts +2 -2
  28. package/front_end/models/persistence/IsolatedFileSystemManager.ts +20 -29
  29. package/front_end/models/trace/ModelImpl.ts +5 -0
  30. package/front_end/models/trace/Processor.ts +5 -0
  31. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +7 -1
  32. package/front_end/models/trace/handlers/MetaHandler.ts +8 -4
  33. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +11 -0
  34. package/front_end/models/workspace/FileManager.ts +13 -6
  35. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -10
  36. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +3 -45
  37. package/front_end/panels/application/BackgroundServiceView.ts +42 -40
  38. package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
  39. package/front_end/panels/application/WebMCPView.ts +13 -5
  40. package/front_end/panels/application/components/AdsView.ts +24 -1
  41. package/front_end/panels/application/components/adsView.css +27 -21
  42. package/front_end/panels/autofill/AutofillView.ts +12 -12
  43. package/front_end/panels/autofill/autofill-meta.ts +2 -2
  44. package/front_end/panels/common/ExtensionServer.ts +7 -1
  45. package/front_end/panels/common/common.ts +0 -1
  46. package/front_end/panels/console/ConsoleInsightTeaser.ts +7 -6
  47. package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
  48. package/front_end/panels/elements/ClassesPaneWidget.ts +2 -2
  49. package/front_end/panels/elements/ElementsTreeElement.ts +602 -327
  50. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  51. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  52. package/front_end/panels/elements/components/AdornerManager.ts +1 -0
  53. package/front_end/panels/emulation/AdvancedApp.ts +3 -3
  54. package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -11
  55. package/front_end/panels/emulation/DeviceModeView.ts +234 -75
  56. package/front_end/panels/emulation/InspectedPagePlaceholder.ts +1 -1
  57. package/front_end/panels/emulation/deviceModeView.css +4 -21
  58. package/front_end/panels/emulation/emulation-meta.ts +4 -30
  59. package/front_end/panels/emulation/emulation.ts +0 -3
  60. package/front_end/panels/explain/components/ConsoleInsight.ts +11 -7
  61. package/front_end/panels/js_timeline/js_timeline-meta.ts +8 -8
  62. package/front_end/panels/layer_viewer/LayerDetailsView.ts +30 -30
  63. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +6 -6
  64. package/front_end/panels/layer_viewer/LayerViewHost.ts +1 -1
  65. package/front_end/panels/layer_viewer/Layers3DView.ts +11 -11
  66. package/front_end/panels/layer_viewer/PaintProfilerView.ts +8 -8
  67. package/front_end/panels/layer_viewer/TransformController.ts +3 -3
  68. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +11 -11
  69. package/front_end/panels/layers/LayersPanel.ts +2 -2
  70. package/front_end/panels/layers/layers-meta.ts +2 -2
  71. package/front_end/panels/lighthouse/LighthouseController.ts +3 -7
  72. package/front_end/panels/mobile_throttling/CPUThrottlingSelector.ts +313 -0
  73. package/front_end/panels/mobile_throttling/NetworkPanelIndicator.ts +0 -10
  74. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +21 -10
  75. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +1 -58
  76. package/front_end/panels/mobile_throttling/mobile_throttling.ts +2 -9
  77. package/front_end/panels/network/NetworkConfigView.ts +1 -71
  78. package/front_end/panels/network/networkConfigView.css +1 -2
  79. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +3 -3
  80. package/front_end/panels/profiler/HeapDetachedElementsView.ts +5 -5
  81. package/front_end/panels/profiler/HeapProfileView.ts +32 -32
  82. package/front_end/panels/profiler/HeapProfilerPanel.ts +2 -2
  83. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +33 -37
  84. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +26 -27
  85. package/front_end/panels/profiler/HeapSnapshotView.ts +48 -48
  86. package/front_end/panels/profiler/IsolateSelector.ts +10 -10
  87. package/front_end/panels/profiler/ModuleUIStrings.ts +25 -25
  88. package/front_end/panels/profiler/ProfileLauncherView.ts +6 -6
  89. package/front_end/panels/profiler/ProfilesPanel.ts +6 -6
  90. package/front_end/panels/profiler/WritableProfileHeader.ts +6 -6
  91. package/front_end/panels/profiler/profiler-meta.ts +7 -7
  92. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +7 -0
  93. package/front_end/panels/recorder/RecorderPanel.ts +1 -1
  94. package/front_end/panels/settings/AISettingsTab.ts +27 -23
  95. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -2
  96. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +12 -17
  97. package/front_end/panels/timeline/TimelinePanel.ts +20 -35
  98. package/front_end/panels/timeline/components/LiveMetricsView.ts +27 -6
  99. package/front_end/panels/timeline/components/NetworkTrackWidget.ts +1 -1
  100. package/front_end/panels/timeline/components/components.ts +0 -4
  101. package/front_end/panels/timeline/components/liveMetricsView.css +7 -0
  102. package/front_end/third_party/chromium/README.chromium +1 -1
  103. package/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +0 -0
  104. package/front_end/third_party/source-map-scopes-codec/package/LICENSE +0 -0
  105. package/front_end/third_party/source-map-scopes-codec/package/README.md +0 -0
  106. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +0 -0
  107. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -1
  108. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +0 -0
  109. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +0 -0
  110. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +0 -0
  111. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +0 -0
  112. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +0 -0
  113. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +0 -0
  114. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +0 -0
  115. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +0 -0
  116. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +0 -0
  117. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +0 -0
  118. package/front_end/third_party/source-map-scopes-codec/package/deno.json +1 -1
  119. package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
  120. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +2 -0
  121. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -1
  122. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +2 -0
  123. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +0 -0
  124. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +0 -0
  125. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +0 -0
  126. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js +0 -0
  127. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +0 -0
  128. package/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +0 -0
  129. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +0 -0
  130. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +0 -0
  131. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +0 -0
  132. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +0 -0
  133. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +0 -0
  134. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +0 -0
  135. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +0 -0
  136. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +0 -0
  137. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +0 -0
  138. package/front_end/third_party/source-map-scopes-codec/package/src/mod.js +0 -0
  139. package/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +0 -0
  140. package/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +0 -0
  141. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js +0 -0
  142. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js.map +0 -0
  143. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +0 -0
  144. package/front_end/third_party/source-map-scopes-codec/package/src/util.js +0 -0
  145. package/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +0 -0
  146. package/front_end/third_party/source-map-scopes-codec/package/src/util.ts +0 -0
  147. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +0 -0
  148. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +0 -0
  149. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +0 -0
  150. package/front_end/ui/comments/CommentAnchorResolver.ts +132 -0
  151. package/front_end/ui/comments/comments.ts +9 -0
  152. package/front_end/ui/components/dialogs/ShortcutDialog.ts +2 -0
  153. package/front_end/ui/components/settings/SettingCheckbox.ts +4 -12
  154. package/front_end/ui/components/settings/settingCheckbox.css +0 -7
  155. package/front_end/ui/legacy/Treeoutline.ts +14 -14
  156. package/front_end/ui/legacy/UIUtils.ts +2 -47
  157. package/front_end/ui/legacy/Widget.ts +10 -2
  158. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +40 -0
  159. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +1 -1
  160. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -0
  161. package/front_end/ui/lit/Directives.ts +80 -0
  162. package/front_end/ui/lit/lit.ts +1 -0
  163. package/front_end/ui/lit/render.ts +8 -0
  164. package/front_end/ui/settings/SettingUIRegistration.ts +4 -0
  165. package/front_end/ui/visual_logging/Debugging.ts +1 -5
  166. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  167. package/front_end/ui/visual_logging/LoggingConfig.ts +21 -0
  168. package/front_end/ui/visual_logging/visual_logging.ts +9 -0
  169. package/mcp/mcp.ts +1 -0
  170. package/package.json +1 -1
  171. package/front_end/panels/common/ThrottlingUtils.ts +0 -51
  172. package/front_end/panels/emulation/DeviceModeWrapper.ts +0 -248
  173. package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +0 -92
  174. package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +0 -235
  175. package/front_end/panels/timeline/components/NetworkThrottlingSelector.ts +0 -245
  176. package/front_end/panels/timeline/components/cpuThrottlingSelector.css +0 -30
  177. package/front_end/panels/timeline/components/networkThrottlingSelector.css +0 -24
@@ -104,6 +104,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
104
104
  #availableSize: Geometry.Size;
105
105
  #preferredSize: Geometry.Size;
106
106
  #initialized: boolean;
107
+ #autoFitScaleOnInitialize: boolean;
107
108
  #appliedDeviceSize: Geometry.Size;
108
109
  #appliedDeviceScaleFactor: number;
109
110
  #appliedUserAgentType: UA;
@@ -113,7 +114,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
113
114
  #heightSetting: Common.Settings.Setting<number>;
114
115
  #uaSetting: Common.Settings.Setting<UA>;
115
116
  readonly #deviceScaleFactorSetting: Common.Settings.Setting<number>;
116
- readonly #deviceOutlineSetting: Common.Settings.Setting<boolean>;
117
+
117
118
  readonly #toolbarControlsEnabledSetting: Common.Settings.Setting<boolean>;
118
119
  #type: Type;
119
120
  #device: EmulatedDevice|null;
@@ -123,26 +124,29 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
123
124
  #touchMobile: boolean;
124
125
  #emulationModel: SDK.EmulationModel.EmulationModel|null;
125
126
  #onModelAvailable: (() => void)|null;
126
- #outlineRect?: Rect;
127
127
  #screenOrientationLocked: boolean;
128
128
  readonly #targetManager: SDK.TargetManager.TargetManager;
129
129
  readonly #settings: Common.Settings.Settings;
130
130
  readonly #multitargetNetworkManager: SDK.NetworkManager.MultitargetNetworkManager;
131
+ readonly #fileManager: Workspace.FileManager.FileManager;
131
132
 
132
133
  constructor(
133
134
  targetManager: SDK.TargetManager.TargetManager,
134
135
  settings: Common.Settings.Settings,
135
136
  multitargetNetworkManager: SDK.NetworkManager.MultitargetNetworkManager,
137
+ fileManager: Workspace.FileManager.FileManager,
136
138
  ) {
137
139
  super();
138
140
  this.#targetManager = targetManager;
139
141
  this.#settings = settings;
140
142
  this.#multitargetNetworkManager = multitargetNetworkManager;
143
+ this.#fileManager = fileManager;
141
144
  this.#screenRect = new Rect(0, 0, 1, 1);
142
145
  this.#visiblePageRect = new Rect(0, 0, 1, 1);
143
146
  this.#availableSize = new Geometry.Size(1, 1);
144
147
  this.#preferredSize = new Geometry.Size(1, 1);
145
148
  this.#initialized = false;
149
+ this.#autoFitScaleOnInitialize = false;
146
150
  this.#appliedDeviceSize = new Geometry.Size(1, 1);
147
151
  this.#appliedDeviceScaleFactor = globalThis.devicePixelRatio;
148
152
  this.#appliedUserAgentType = UA.DESKTOP;
@@ -178,9 +182,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
178
182
  this.#deviceScaleFactorSetting = this.#settings.createSetting('emulation.device-scale-factor', 0);
179
183
  this.#deviceScaleFactorSetting.addChangeListener(this.deviceScaleFactorSettingChanged, this);
180
184
 
181
- this.#deviceOutlineSetting = this.#settings.moduleSetting('emulation.show-device-outline');
182
- this.#deviceOutlineSetting.addChangeListener(this.deviceOutlineSettingChanged, this);
183
-
184
185
  this.#toolbarControlsEnabledSetting = this.#settings.createSetting('emulation.toolbar-controls-enabled', true,
185
186
  Common.Settings.SettingStorageType.SESSION);
186
187
 
@@ -208,6 +209,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
208
209
  Common.Settings.Settings.instance(),
209
210
  // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
210
211
  SDK.NetworkManager.MultitargetNetworkManager.instance(),
212
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
213
+ Workspace.FileManager.FileManager.instance(),
211
214
  ));
212
215
  }
213
216
 
@@ -311,10 +314,21 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
311
314
  return this.#scaleSetting;
312
315
  }
313
316
 
317
+ #updateFitScale(): void {
318
+ if (this.#type === Type.Device && this.#device && this.#mode) {
319
+ const orientation = this.#device.orientationByName(this.#mode.orientation);
320
+ this.#scaleSetting.set(this.calculateFitScale(orientation.width, orientation.height, this.currentInsets()));
321
+ }
322
+ }
323
+
314
324
  setAvailableSize(availableSize: Geometry.Size, preferredSize: Geometry.Size): void {
315
325
  this.#availableSize = availableSize;
316
326
  this.#preferredSize = preferredSize;
317
327
  this.#initialized = true;
328
+ if (this.#autoFitScaleOnInitialize) {
329
+ this.#autoFitScaleOnInitialize = false;
330
+ this.#updateFitScale();
331
+ }
318
332
  this.calculateAndEmulate(false);
319
333
  }
320
334
 
@@ -326,15 +340,19 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
326
340
  console.assert(Boolean(device) && Boolean(mode), 'Must pass device and mode for device emulation');
327
341
  this.#mode = mode;
328
342
  this.#device = device;
329
- if (this.#initialized) {
330
- const orientation = device.orientationByName(mode.orientation);
331
- this.#scaleSetting.set(
332
- scale ||
333
- this.calculateFitScale(orientation.width, orientation.height, this.currentOutline(), this.currentInsets()));
343
+ if (scale !== undefined) {
344
+ this.#autoFitScaleOnInitialize = false;
345
+ this.#scaleSetting.set(scale);
346
+ } else if (this.#initialized) {
347
+ this.#autoFitScaleOnInitialize = false;
348
+ this.#updateFitScale();
349
+ } else {
350
+ this.#autoFitScaleOnInitialize = true;
334
351
  }
335
352
  } else {
336
353
  this.#device = null;
337
354
  this.#mode = null;
355
+ this.#autoFitScaleOnInitialize = false;
338
356
  }
339
357
 
340
358
  if (type !== Type.None) {
@@ -386,23 +404,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
386
404
  return this.#type;
387
405
  }
388
406
 
389
- screenImage(): string {
390
- return (this.#device && this.#mode) ? this.#device.modeImage(this.#mode) : '';
391
- }
392
-
393
- outlineImage(): string {
394
- return (this.#device && this.#mode && this.#deviceOutlineSetting.get()) ? this.#device.outlineImage(this.#mode) :
395
- '';
396
- }
397
-
398
- canShowDeviceFrame(): boolean {
399
- return Boolean(this.#device && this.#mode && this.#device.outlineImage(this.#mode));
400
- }
401
-
402
- outlineRect(): Rect|null {
403
- return this.#outlineRect || null;
404
- }
405
-
406
407
  screenRect(): Rect {
407
408
  return this.#screenRect;
408
409
  }
@@ -471,10 +472,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
471
472
  return this.#deviceScaleFactorSetting;
472
473
  }
473
474
 
474
- deviceOutlineSetting(): Common.Settings.Setting<boolean> {
475
- return this.#deviceOutlineSetting;
476
- }
477
-
478
475
  toolbarControlsEnabledSetting(): Common.Settings.Setting<boolean> {
479
476
  return this.#toolbarControlsEnabledSetting;
480
477
  }
@@ -590,10 +587,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
590
587
  this.calculateAndEmulate(false);
591
588
  }
592
589
 
593
- private deviceOutlineSettingChanged(): void {
594
- this.calculateAndEmulate(false);
595
- }
596
-
597
590
  private preferredScaledWidth(): number {
598
591
  return Math.floor(this.#preferredSize.width / (this.#scaleSetting.get() || 1));
599
592
  }
@@ -602,18 +595,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
602
595
  return Math.floor(this.#preferredSize.height / (this.#scaleSetting.get() || 1));
603
596
  }
604
597
 
605
- private currentOutline(): Insets {
606
- let outline: Insets = new Insets(0, 0, 0, 0);
607
- if (this.#type !== Type.Device || !this.#device || !this.#mode) {
608
- return outline;
609
- }
610
- const orientation = this.#device.orientationByName(this.#mode.orientation);
611
- if (this.#deviceOutlineSetting.get()) {
612
- outline = orientation.outlineInsets || outline;
613
- }
614
- return outline;
615
- }
616
-
617
598
  private currentInsets(): Insets {
618
599
  if (this.#type !== Type.Device || !this.#mode) {
619
600
  return new Insets(0, 0, 0, 0);
@@ -666,25 +647,22 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
666
647
  }
667
648
  if (this.#type === Type.Device && this.#device && this.#mode) {
668
649
  const orientation = this.#device.orientationByName(this.#mode.orientation);
669
- const outline = this.currentOutline();
670
650
  const insets = this.currentInsets();
671
- this.#fitScale = this.calculateFitScale(orientation.width, orientation.height, outline, insets);
651
+ this.#fitScale = this.calculateFitScale(orientation.width, orientation.height, insets);
672
652
  if (mobile) {
673
653
  this.#appliedUserAgentType = this.#device.touch() ? UA.MOBILE : UA.MOBILE_NO_TOUCH;
674
654
  } else {
675
655
  this.#appliedUserAgentType = this.#device.touch() ? UA.DESKTOP_TOUCH : UA.DESKTOP;
676
656
  }
677
- this.applyDeviceMetrics(
678
- new Geometry.Size(orientation.width, orientation.height), insets, outline, this.#scaleSetting.get(),
679
- this.#device.deviceScaleFactor, mobile, this.getScreenOrientationType(), resetPageScaleFactor);
657
+ this.applyDeviceMetrics(new Geometry.Size(orientation.width, orientation.height), insets,
658
+ this.#scaleSetting.get(), this.#device.deviceScaleFactor, mobile,
659
+ this.getScreenOrientationType(), resetPageScaleFactor);
680
660
  this.applyUserAgent(this.#device.userAgent, this.#device.userAgentMetadata);
681
661
  this.applyTouch(this.#device.touch(), mobile);
682
662
  } else if (this.#type === Type.None) {
683
663
  this.#fitScale = this.calculateFitScale(this.#availableSize.width, this.#availableSize.height);
684
664
  this.#appliedUserAgentType = UA.DESKTOP;
685
- this.applyDeviceMetrics(
686
- this.#availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1, 0, mobile, null,
687
- resetPageScaleFactor);
665
+ this.applyDeviceMetrics(this.#availableSize, new Insets(0, 0, 0, 0), 1, 0, mobile, null, resetPageScaleFactor);
688
666
  this.applyUserAgent('', null);
689
667
  this.applyTouch(false, false);
690
668
  } else if (this.#type === Type.Responsive) {
@@ -699,12 +677,12 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
699
677
  const defaultDeviceScaleFactor = mobile ? defaultMobileScaleFactor : 0;
700
678
  this.#fitScale = this.calculateFitScale(this.#widthSetting.get(), this.#heightSetting.get());
701
679
  this.#appliedUserAgentType = this.#uaSetting.get();
702
- this.applyDeviceMetrics(
703
- new Geometry.Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0),
704
- this.#scaleSetting.get(), this.#deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
705
- screenHeight >= screenWidth ? Protocol.Emulation.ScreenOrientationType.PortraitPrimary :
706
- Protocol.Emulation.ScreenOrientationType.LandscapePrimary,
707
- resetPageScaleFactor);
680
+ this.applyDeviceMetrics(new Geometry.Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0),
681
+ this.#scaleSetting.get(),
682
+ this.#deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
683
+ screenHeight >= screenWidth ? Protocol.Emulation.ScreenOrientationType.PortraitPrimary :
684
+ Protocol.Emulation.ScreenOrientationType.LandscapePrimary,
685
+ resetPageScaleFactor);
708
686
  this.applyUserAgent(
709
687
  mobile ? DeviceModeModel.defaultMobileUserAgent() : '',
710
688
  mobile ? DeviceModeModel.defaultMobileUserAgentMetadata() : null);
@@ -720,14 +698,11 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
720
698
  this.dispatchEventToListeners(Events.UPDATED);
721
699
  }
722
700
 
723
- private calculateFitScale(screenWidth: number, screenHeight: number, outline?: Insets, insets?: Insets): number {
724
- const outlineWidth = outline ? outline.left + outline.right : 0;
725
- const outlineHeight = outline ? outline.top + outline.bottom : 0;
701
+ private calculateFitScale(screenWidth: number, screenHeight: number, insets?: Insets): number {
726
702
  const insetsWidth = insets ? insets.left + insets.right : 0;
727
703
  const insetsHeight = insets ? insets.top + insets.bottom : 0;
728
- let scale = Math.min(
729
- screenWidth ? this.#preferredSize.width / (screenWidth + outlineWidth) : 1,
730
- screenHeight ? this.#preferredSize.height / (screenHeight + outlineHeight) : 1);
704
+ let scale = Math.min(screenWidth ? this.#preferredSize.width / screenWidth : 1,
705
+ screenHeight ? this.#preferredSize.height / screenHeight : 1);
731
706
  scale = Math.min(Math.floor(scale * 100), 100);
732
707
 
733
708
  let sharpScale = scale;
@@ -760,10 +735,9 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
760
735
  this.#multitargetNetworkManager.setUserAgentOverride(userAgent, userAgent ? userAgentMetadata : null);
761
736
  }
762
737
 
763
- private applyDeviceMetrics(
764
- screenSize: Geometry.Size, insets: Insets, outline: Insets, scale: number, deviceScaleFactor: number,
765
- mobile: boolean, screenOrientation: Protocol.Emulation.ScreenOrientationType|null,
766
- resetPageScaleFactor: boolean): void {
738
+ private applyDeviceMetrics(screenSize: Geometry.Size, insets: Insets, scale: number, deviceScaleFactor: number,
739
+ mobile: boolean, screenOrientation: Protocol.Emulation.ScreenOrientationType|null,
740
+ resetPageScaleFactor: boolean): void {
767
741
  screenSize.width = Math.max(1, Math.floor(screenSize.width));
768
742
  screenSize.height = Math.max(1, Math.floor(screenSize.height));
769
743
 
@@ -777,12 +751,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
777
751
 
778
752
  this.#appliedDeviceSize = screenSize;
779
753
  this.#appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
780
- this.#screenRect = new Rect(
781
- Math.max(0, (this.#availableSize.width - screenSize.width * scale) / 2), outline.top * scale,
782
- screenSize.width * scale, screenSize.height * scale);
783
- this.#outlineRect = new Rect(
784
- this.#screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale,
785
- (outline.top + screenSize.height + outline.bottom) * scale);
754
+ this.#screenRect = new Rect(Math.max(0, (this.#availableSize.width - screenSize.width * scale) / 2), 0,
755
+ screenSize.width * scale, screenSize.height * scale);
786
756
  this.#visiblePageRect = new Rect(
787
757
  positionX * scale, positionY * scale,
788
758
  Math.min(pageWidth * scale, this.#availableSize.width - this.#screenRect.left - positionX * scale),
@@ -904,32 +874,21 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
904
874
  pageImage.src = 'data:image/png;base64,' + screenshot;
905
875
  pageImage.onload = async () => {
906
876
  const scale = pageImage.naturalWidth / this.screenRect().width;
907
- const outlineRectFromModel = this.outlineRect();
908
- if (!outlineRectFromModel) {
909
- throw new Error('Unable to take screenshot: no outlineRect available.');
910
- }
911
- const outlineRect = outlineRectFromModel.scale(scale);
912
877
  const screenRect = this.screenRect().scale(scale);
913
878
  const visiblePageRect = this.visiblePageRect().scale(scale);
914
- const contentLeft = screenRect.left + visiblePageRect.left - outlineRect.left;
915
- const contentTop = screenRect.top + visiblePageRect.top - outlineRect.top;
879
+ const contentLeft = visiblePageRect.left;
880
+ const contentTop = visiblePageRect.top;
916
881
 
917
- const canvas = new OffscreenCanvas(Math.floor(outlineRect.width),
882
+ const canvas = new OffscreenCanvas(Math.floor(screenRect.width),
918
883
  // Cap the height to not hit the GPU limit.
919
884
  // https://crbug.com/1260828
920
- Math.min((1 << 14), Math.floor(outlineRect.height)));
885
+ Math.min((1 << 14), Math.floor(screenRect.height)));
921
886
  const ctx = canvas.getContext('2d', {willReadFrequently: true});
922
887
  if (!ctx) {
923
888
  throw new Error('Could not get 2d context from canvas.');
924
889
  }
925
890
  ctx.imageSmoothingEnabled = false;
926
891
 
927
- if (this.outlineImage()) {
928
- await this.paintImage(ctx, this.outlineImage(), outlineRect.relativeTo(outlineRect));
929
- }
930
- if (this.screenImage()) {
931
- await this.paintImage(ctx, this.screenImage(), screenRect.relativeTo(outlineRect));
932
- }
933
892
  ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
934
893
  void this.saveScreenshot(canvas);
935
894
  };
@@ -985,17 +944,41 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
985
944
 
986
945
  private async saveScreenshot(canvas: OffscreenCanvas): Promise<void> {
987
946
  const url = this.inspectedURL();
988
- let fileName = '';
947
+ let baseName = '';
989
948
  if (url) {
990
- const withoutFragment = Platform.StringUtilities.removeURLFragment(url);
991
- fileName = Platform.StringUtilities.trimURL(withoutFragment);
949
+ const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
950
+ if (parsedURL) {
951
+ const host = parsedURL.host;
952
+ const path = parsedURL.path.replace(/^\/+/, '').replace(/\/+$/, '');
953
+ baseName = host;
954
+ if (path) {
955
+ baseName += '-' + path.replaceAll('/', '-');
956
+ }
957
+ baseName = baseName.replace(/[^a-z0-9._-]/gi, '_');
958
+ }
992
959
  }
993
960
 
961
+ if (!baseName) {
962
+ baseName = 'screenshot';
963
+ }
964
+
965
+ let suffix = '';
994
966
  const device = this.device();
995
967
  if (device && this.type() === Type.Device) {
996
- fileName += `(${device.title})`;
968
+ suffix += `(${device.title})`;
969
+ }
970
+ suffix += '.png';
971
+
972
+ // The Windows save dialog / Chrome wrapper limits the suggested filename
973
+ // to 63 characters (due to a 64-byte null-terminated buffer).
974
+ // Capping the total filename length at 63 avoids truncation of the extension.
975
+ const maxBaseNameLength = Math.max(0, 63 - suffix.length);
976
+ baseName = Platform.StringUtilities.truncateToCodeUnitLength(baseName, maxBaseNameLength);
977
+
978
+ let fileName = baseName + suffix;
979
+ if (fileName.length > 63) {
980
+ fileName = Platform.StringUtilities.truncateToCodeUnitLength(fileName, 59) + '.png';
997
981
  }
998
- fileName += '.png';
999
982
  const blob = await canvas.convertToBlob({type: 'image/png'});
1000
983
  const dataUrl = await new Promise<string>((resolve, reject) => {
1001
984
  const reader = new FileReader();
@@ -1005,11 +988,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1005
988
  });
1006
989
  const base64 = dataUrl.slice(dataUrl.indexOf(',') + 1);
1007
990
  const contentData = new TextUtils.ContentData.ContentData(base64, /* isBase64=*/ true, 'image/png');
1008
- // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
1009
- await Workspace.FileManager.FileManager.instance().save(fileName as Platform.DevToolsPath.RawPathString,
1010
- contentData, /* forceSaveAs=*/ true);
1011
- // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
1012
- Workspace.FileManager.FileManager.instance().close(fileName as Platform.DevToolsPath.RawPathString);
991
+ await this.#fileManager.save(fileName as Platform.DevToolsPath.RawPathString, contentData, /* forceSaveAs=*/ true);
992
+ this.#fileManager.close(fileName as Platform.DevToolsPath.RawPathString);
1013
993
  }
1014
994
 
1015
995
  private applyTouch(touchEnabled: boolean, mobile: boolean): void {
@@ -48,12 +48,6 @@ const str_ = i18n.i18n.registerUIStrings('models/emulation/EmulatedDevices.ts',
48
48
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
49
49
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
50
50
 
51
- export function computeRelativeImageURL(cssURLValue: string): string {
52
- return cssURLValue.replace(/@url\(([^\)]*?)\)/g, (_match: string, url: string) => {
53
- return new URL(`../../emulated_devices/${url}`, import.meta.url).toString();
54
- });
55
- }
56
-
57
51
  export class EmulatedDevice {
58
52
  title: string;
59
53
  type: Type;
@@ -75,8 +69,8 @@ export class EmulatedDevice {
75
69
  constructor() {
76
70
  this.title = '';
77
71
  this.type = Type.Unknown;
78
- this.vertical = {width: 0, height: 0, outlineInsets: null, outlineImage: null, hinge: null};
79
- this.horizontal = {width: 0, height: 0, outlineInsets: null, outlineImage: null, hinge: null};
72
+ this.vertical = {width: 0, height: 0, hinge: null};
73
+ this.horizontal = {width: 0, height: 0, hinge: null};
80
74
  this.deviceScaleFactor = 1;
81
75
  this.capabilities = [Capability.TOUCH, Capability.MOBILE];
82
76
  this.userAgent = '';
@@ -85,8 +79,8 @@ export class EmulatedDevice {
85
79
 
86
80
  this.isDualScreen = false;
87
81
  this.isFoldableScreen = false;
88
- this.verticalSpanned = {width: 0, height: 0, outlineInsets: null, outlineImage: null, hinge: null};
89
- this.horizontalSpanned = {width: 0, height: 0, outlineInsets: null, outlineImage: null, hinge: null};
82
+ this.verticalSpanned = {width: 0, height: 0, hinge: null};
83
+ this.horizontalSpanned = {width: 0, height: 0, hinge: null};
90
84
 
91
85
  this.#show = Show.Default;
92
86
  this.#showByDefault = true;
@@ -202,15 +196,6 @@ export class EmulatedDevice {
202
196
  throw new Error('Emulated device has wrong height: ' + result.height);
203
197
  }
204
198
 
205
- const outlineInsets = parseValue(json['outline'], 'insets', 'object', null);
206
- if (outlineInsets) {
207
- result.outlineInsets = parseInsets(outlineInsets);
208
- if (result.outlineInsets.left < 0 || result.outlineInsets.top < 0) {
209
- throw new Error('Emulated device has wrong outline insets');
210
- }
211
- result.outlineImage = (parseValue(json['outline'], 'image', 'string') as string);
212
- }
213
-
214
199
  if (json['hinge']) {
215
200
  result.hinge = parseHinge(parseValue(json, 'hinge', 'object', undefined));
216
201
  }
@@ -282,9 +267,10 @@ export class EmulatedDevice {
282
267
  if (mode.insets.top < 0 || mode.insets.left < 0 || mode.insets.right < 0 || mode.insets.bottom < 0 ||
283
268
  mode.insets.top + mode.insets.bottom > orientation.height ||
284
269
  mode.insets.left + mode.insets.right > orientation.width) {
285
- throw new Error('Emulated device mode \'' + mode.title + '\'has wrong mode insets');
270
+ throw new Error(
271
+ 'Emulated device mode \'' + mode.title + '\'has wrong mode insets',
272
+ );
286
273
  }
287
- mode.image = (parseValue(modes[i], 'image', 'string', null) as string);
288
274
  const safeAreaInsets = parseValue(modes[i], 'safe-area-insets', 'object', null);
289
275
  if (safeAreaInsets) {
290
276
  mode.safeAreaInsets = parseInsets(safeAreaInsets);
@@ -419,7 +405,6 @@ export class EmulatedDevice {
419
405
  right: this.modes[i].insets.right,
420
406
  bottom: this.modes[i].insets.bottom,
421
407
  },
422
- image: this.modes[i].image || undefined,
423
408
  };
424
409
  const safeAreaInsets = this.modes[i].safeAreaInsets;
425
410
  if (safeAreaInsets) {
@@ -469,17 +454,7 @@ export class EmulatedDevice {
469
454
  const json = {} as any;
470
455
  json['width'] = orientation.width;
471
456
  json['height'] = orientation.height;
472
- if (orientation.outlineInsets) {
473
- json.outline = {
474
- insets: {
475
- left: orientation.outlineInsets.left,
476
- top: orientation.outlineInsets.top,
477
- right: orientation.outlineInsets.right,
478
- bottom: orientation.outlineInsets.bottom,
479
- },
480
- image: orientation.outlineImage,
481
- } as {image: string | null, insets: {left: number, right: number, top: number, bottom: number}};
482
- }
457
+
483
458
  if (orientation.hinge) {
484
459
  json.hinge = {
485
460
  width: orientation.hinge.width,
@@ -515,21 +490,6 @@ export class EmulatedDevice {
515
490
  return json;
516
491
  }
517
492
 
518
- modeImage(mode: Mode): string {
519
- if (!mode.image) {
520
- return '';
521
- }
522
- return computeRelativeImageURL(mode.image);
523
- }
524
-
525
- outlineImage(mode: Mode): string {
526
- const orientation = this.orientationByName(mode.orientation);
527
- if (!orientation.outlineImage) {
528
- return '';
529
- }
530
- return computeRelativeImageURL(orientation.outlineImage);
531
- }
532
-
533
493
  orientationByName(name: string): Orientation {
534
494
  switch (name) {
535
495
  case VerticalSpanned:
@@ -688,8 +648,16 @@ export class EmulatedDevicesList extends Common.ObjectWrapper.ObjectWrapper<Even
688
648
  if (device) {
689
649
  result.add(device);
690
650
  if (!device.modes.length) {
691
- device.modes.push({title: '', orientation: Horizontal, insets: new Insets(0, 0, 0, 0), image: null});
692
- device.modes.push({title: '', orientation: Vertical, insets: new Insets(0, 0, 0, 0), image: null});
651
+ device.modes.push({
652
+ title: '',
653
+ orientation: Horizontal,
654
+ insets: new Insets(0, 0, 0, 0),
655
+ });
656
+ device.modes.push({
657
+ title: '',
658
+ orientation: Vertical,
659
+ insets: new Insets(0, 0, 0, 0),
660
+ });
693
661
  }
694
662
  } else {
695
663
  success = false;
@@ -769,7 +737,6 @@ export interface Mode {
769
737
  title: string;
770
738
  orientation: string;
771
739
  insets: Insets;
772
- image: string|null;
773
740
  safeAreaInsets?: Insets;
774
741
  cutout?: Cutout;
775
742
  }
@@ -791,14 +758,11 @@ export type Cutout = BaseCutout&({shape: CutoutShape.RECTANGLE}|{shape: CutoutSh
791
758
  export interface Orientation {
792
759
  width: number;
793
760
  height: number;
794
- outlineInsets: Insets|null;
795
- outlineImage: string|null;
796
761
  hinge: SDK.OverlayModel.Hinge|null;
797
762
  }
798
763
  export interface JSONMode {
799
764
  title: string;
800
765
  orientation: string;
801
- image?: string;
802
766
  insets: {
803
767
  left: number,
804
768
  right: number,
@@ -2136,10 +2100,6 @@ const emulatedDevices = [
2136
2100
  'title': 'Nest Hub Max',
2137
2101
  'screen': {
2138
2102
  'horizontal': {
2139
- 'outline': {
2140
- 'image': '@url(optimized/google-nest-hub-max-horizontal.avif)',
2141
- 'insets': {'left': 92, 'top': 96, 'right': 91, 'bottom': 248},
2142
- },
2143
2103
  'width': 1280,
2144
2104
  'height': 800,
2145
2105
  },
@@ -2249,19 +2209,11 @@ const emulatedDevices = [
2249
2209
  'title': 'Moto G4',
2250
2210
  'screen': {
2251
2211
  'horizontal': {
2252
- 'outline': {
2253
- 'image': '@url(optimized/MotoG4-landscape.avif)',
2254
- 'insets': {'left': 91, 'top': 30, 'right': 74, 'bottom': 30},
2255
- },
2256
2212
  'width': 640,
2257
2213
  'height': 360,
2258
2214
  },
2259
2215
  'device-pixel-ratio': 3,
2260
2216
  'vertical': {
2261
- 'outline': {
2262
- 'image': '@url(optimized/MotoG4-portrait.avif)',
2263
- 'insets': {'left': 30, 'top': 91, 'right': 30, 'bottom': 74},
2264
- },
2265
2217
  'width': 360,
2266
2218
  'height': 640,
2267
2219
  },
@@ -7810,6 +7810,10 @@ export const NativeFunctions = [
7810
7810
  name: "MediaStreamTrackEvent",
7811
7811
  signatures: [["type","eventInitDict"]]
7812
7812
  },
7813
+ {
7814
+ name: "setConstraints",
7815
+ signatures: [["?constraints"]]
7816
+ },
7813
7817
  {
7814
7818
  name: "webkitGetUserMedia",
7815
7819
  signatures: [["constraints","successCallback","errorCallback"]]
@@ -7818,10 +7822,6 @@ export const NativeFunctions = [
7818
7822
  name: "OverconstrainedError",
7819
7823
  signatures: [["constraint","?message"]]
7820
7824
  },
7821
- {
7822
- name: "setConstraints",
7823
- signatures: [["?constraints"]]
7824
- },
7825
7825
  {
7826
7826
  name: "appendEncodedChunks",
7827
7827
  signatures: [["chunks"]]
@@ -113,12 +113,12 @@ export class AutomaticFileSystemManager extends Common.ObjectWrapper.ObjectWrapp
113
113
  */
114
114
  static removeInstance(): void {
115
115
  if (Root.DevToolsContext.globalInstance().has(AutomaticFileSystemManager)) {
116
- Root.DevToolsContext.globalInstance().get(AutomaticFileSystemManager).#dispose();
116
+ Root.DevToolsContext.globalInstance().get(AutomaticFileSystemManager).dispose();
117
117
  Root.DevToolsContext.globalInstance().delete(AutomaticFileSystemManager);
118
118
  }
119
119
  }
120
120
 
121
- #dispose(): void {
121
+ dispose(): void {
122
122
  this.#inspectorFrontendHost.events.removeEventListener(
123
123
  Host.InspectorFrontendHostAPI.Events.FileSystemRemoved, this.#fileSystemRemoved, this);
124
124
  this.#projectSettingsModel.removeEventListener(