chrome-devtools-frontend 1.0.1674545 → 1.0.1676824

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 (258) hide show
  1. package/.agents/skills/devtools-ux-writing-refactor/SKILL.md +26 -9
  2. package/WATCHLISTS +0 -4
  3. package/front_end/core/common/ParsedURL.ts +5 -1
  4. package/front_end/core/common/SettingRegistration.ts +29 -8
  5. package/front_end/core/common/Settings.ts +0 -77
  6. package/front_end/core/root/Runtime.ts +4 -5
  7. package/front_end/core/sdk/CSSMetadata.ts +5 -9
  8. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +8 -28
  9. package/front_end/core/sdk/DebuggerModel.ts +50 -30
  10. package/front_end/core/sdk/ResourceTreeModel.ts +20 -1
  11. package/front_end/core/sdk/Script.ts +9 -53
  12. package/front_end/core/sdk/TargetManager.ts +18 -0
  13. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +213 -23
  14. package/front_end/entrypoints/main/MainImpl.ts +32 -0
  15. package/front_end/foundation/Universe.ts +44 -29
  16. package/front_end/generated/InspectorBackendCommands.ts +3 -1
  17. package/front_end/generated/SupportedCSSProperties.ts +21 -4
  18. package/front_end/generated/protocol-mapping.d.ts +14 -0
  19. package/front_end/generated/protocol-proxy-api.d.ts +10 -0
  20. package/front_end/generated/protocol.ts +35 -0
  21. package/front_end/models/ai_assistance/AiAgent2.ts +11 -0
  22. package/front_end/models/ai_assistance/AiConversation.ts +22 -5
  23. package/front_end/models/ai_assistance/README.md +52 -26
  24. package/front_end/models/ai_assistance/agents/AiAgent.ts +54 -8
  25. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
  26. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -192
  27. package/front_end/models/ai_assistance/agents/StorageAgent.ts +8 -87
  28. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -1
  29. package/front_end/models/ai_assistance/ai_assistance.ts +16 -0
  30. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +124 -0
  31. package/front_end/models/ai_assistance/contexts/StorageContext.ts +111 -0
  32. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +69 -1
  33. package/front_end/models/ai_assistance/skills/README.md +63 -1
  34. package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
  35. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +4 -0
  36. package/front_end/models/ai_assistance/skills/performance.md +8 -0
  37. package/front_end/models/ai_assistance/skills/sources.md +16 -0
  38. package/front_end/models/ai_assistance/skills/storage.md +31 -0
  39. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +101 -0
  40. package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +83 -0
  41. package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +106 -0
  42. package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +104 -0
  43. package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +81 -0
  44. package/front_end/models/ai_assistance/tools/ListSources.ts +116 -0
  45. package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +90 -0
  46. package/front_end/models/ai_assistance/tools/Tool.ts +22 -1
  47. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +14 -0
  48. package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -0
  49. package/front_end/models/bindings/CompilerScriptMapping.ts +4 -0
  50. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
  51. package/front_end/models/bindings/ResourceScriptMapping.ts +3 -201
  52. package/front_end/models/bindings/SASSSourceMapping.ts +6 -0
  53. package/front_end/models/breakpoints/BreakpointManager.ts +2 -49
  54. package/front_end/models/emulation/DeviceModeModel.ts +60 -71
  55. package/front_end/models/emulation/EmulatedDevices.ts +18 -66
  56. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +27 -0
  57. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +10 -2
  58. package/front_end/models/issues_manager/descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
  59. package/front_end/models/issues_manager/descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
  60. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
  61. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  62. package/front_end/models/persistence/AutomaticFileSystemManager.ts +2 -2
  63. package/front_end/models/persistence/IsolatedFileSystem.ts +7 -8
  64. package/front_end/models/persistence/IsolatedFileSystemManager.ts +22 -31
  65. package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
  66. package/front_end/models/persistence/persistence-meta.ts +9 -9
  67. package/front_end/models/trace/types/TraceEvents.ts +36 -0
  68. package/front_end/models/workspace/FileManager.ts +13 -6
  69. package/front_end/panels/accessibility/ARIAAttributesView.ts +3 -3
  70. package/front_end/panels/accessibility/AccessibilityNodeView.ts +36 -36
  71. package/front_end/panels/accessibility/AccessibilityStrings.ts +168 -168
  72. package/front_end/panels/accessibility/SourceOrderView.ts +7 -7
  73. package/front_end/panels/accessibility/accessibility-meta.ts +2 -2
  74. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -5
  75. package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +2 -3
  76. package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
  77. package/front_end/panels/ai_assistance/components/ChatMessage.ts +27 -2
  78. package/front_end/panels/application/IndexedDBViews.ts +65 -63
  79. package/front_end/panels/application/WebMCPView.ts +29 -12
  80. package/front_end/panels/application/components/AdsView.ts +24 -1
  81. package/front_end/panels/application/components/adsView.css +27 -21
  82. package/front_end/panels/autofill/AutofillView.ts +12 -12
  83. package/front_end/panels/autofill/autofill-meta.ts +2 -2
  84. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +5 -5
  85. package/front_end/panels/common/BadgeNotification.ts +8 -8
  86. package/front_end/panels/common/ExtensionServer.ts +21 -1
  87. package/front_end/panels/common/GdpSignUpDialog.ts +16 -16
  88. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +5 -6
  89. package/front_end/panels/common/PersistenceUtils.ts +2 -2
  90. package/front_end/panels/common/common.ts +0 -97
  91. package/front_end/panels/console/ConsoleInsightTeaser.ts +2 -2
  92. package/front_end/panels/console/ConsolePinPane.ts +2 -2
  93. package/front_end/panels/console/ConsoleView.ts +20 -19
  94. package/front_end/panels/elements/ElementsTreeElement.ts +550 -327
  95. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  96. package/front_end/panels/elements/LayoutPane.ts +2 -8
  97. package/front_end/panels/event_listeners/EventListenersView.ts +8 -4
  98. package/front_end/panels/issues/AffectedTrackingSitesView.ts +25 -14
  99. package/front_end/panels/js_timeline/js_timeline-meta.ts +8 -8
  100. package/front_end/panels/layer_viewer/LayerDetailsView.ts +30 -30
  101. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +6 -6
  102. package/front_end/panels/layer_viewer/LayerViewHost.ts +1 -1
  103. package/front_end/panels/layer_viewer/Layers3DView.ts +11 -11
  104. package/front_end/panels/layer_viewer/PaintProfilerView.ts +8 -8
  105. package/front_end/panels/layer_viewer/TransformController.ts +3 -3
  106. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +11 -11
  107. package/front_end/panels/media/PlayerMessagesView.ts +149 -68
  108. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +1 -58
  109. package/front_end/panels/mobile_throttling/mobile_throttling.ts +0 -10
  110. package/front_end/panels/network/NetworkPanel.ts +1 -1
  111. package/front_end/panels/network/RequestPayloadView.ts +1 -0
  112. package/front_end/panels/profiler/HeapSnapshotView.ts +0 -2
  113. package/front_end/panels/profiler/heapProfiler.css +0 -9
  114. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +7 -0
  115. package/front_end/panels/recorder/RecorderPanel.ts +2 -3
  116. package/front_end/panels/screencast/ScreencastView.ts +148 -138
  117. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -2
  118. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -2
  119. package/front_end/panels/sources/DebuggerPlugin.ts +9 -58
  120. package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
  121. package/front_end/panels/sources/UISourceCodeFrame.ts +3 -8
  122. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +4 -2
  123. package/front_end/panels/timeline/TimelineController.ts +36 -64
  124. package/front_end/panels/timeline/TimelinePanel.ts +11 -8
  125. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -2
  126. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -2
  127. package/front_end/panels/timeline/timelinePanel.css +0 -10
  128. package/front_end/panels/utils/utils.ts +7 -7
  129. package/front_end/services/tracing/PerformanceTracing.ts +5 -17
  130. package/front_end/third_party/chromium/README.chromium +1 -1
  131. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  132. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  133. package/front_end/third_party/codemirror.next/package.json +2 -2
  134. package/front_end/third_party/codemirror.next/rebuild.sh +4 -1
  135. package/front_end/ui/comments/CommentAnchorResolver.ts +558 -0
  136. package/front_end/ui/comments/CommentManager.ts +640 -0
  137. package/front_end/ui/comments/CommentsOverlayWidget.ts +121 -0
  138. package/front_end/ui/comments/comments.ts +13 -0
  139. package/front_end/ui/comments/commentsOverlay.css +49 -0
  140. package/front_end/{panels/common → ui/components/dialogs}/FreDialog.ts +6 -6
  141. package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +96 -0
  142. package/front_end/ui/components/dialogs/dialogs.ts +4 -0
  143. package/front_end/ui/components/settings/SettingCheckbox.ts +3 -3
  144. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionDisclaimer.ts +13 -13
  145. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +7 -6
  146. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionTeaser.ts +43 -46
  147. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -26
  148. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationTeaser.ts +10 -10
  149. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationUpgradeDialog.ts +5 -5
  150. package/front_end/ui/components/text_editor/text_editor.ts +4 -0
  151. package/front_end/ui/legacy/Toolbar.ts +1 -1
  152. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +40 -0
  153. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +11 -3
  154. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +270 -162
  155. package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +5 -0
  156. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -16
  157. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +5 -12
  158. package/front_end/ui/legacy/components/source_frame/JSONView.ts +8 -1
  159. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -2
  160. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -0
  161. package/front_end/ui/settings/SettingUIRegistration.ts +59 -6
  162. package/front_end/ui/visual_logging/Debugging.ts +1 -5
  163. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  164. package/front_end/ui/visual_logging/LoggingConfig.ts +21 -0
  165. package/front_end/ui/visual_logging/visual_logging.ts +9 -0
  166. package/mcp/mcp.ts +6 -1
  167. package/package.json +1 -1
  168. package/front_end/Images/toolbarResizerVertical.png +0 -0
  169. package/front_end/emulated_devices/MotoG4-landscape.svg +0 -155
  170. package/front_end/emulated_devices/MotoG4-portrait.svg +0 -155
  171. package/front_end/emulated_devices/Nexus5X-landscape.svg +0 -19
  172. package/front_end/emulated_devices/Nexus5X-portrait.svg +0 -19
  173. package/front_end/emulated_devices/Nexus6P-landscape.svg +0 -50
  174. package/front_end/emulated_devices/Nexus6P-portrait.svg +0 -54
  175. package/front_end/emulated_devices/google-nest-hub-horizontal.png +0 -0
  176. package/front_end/emulated_devices/google-nest-hub-max-horizontal.png +0 -0
  177. package/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png +0 -0
  178. package/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png +0 -0
  179. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png +0 -0
  180. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png +0 -0
  181. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png +0 -0
  182. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png +0 -0
  183. package/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png +0 -0
  184. package/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png +0 -0
  185. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png +0 -0
  186. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png +0 -0
  187. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png +0 -0
  188. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png +0 -0
  189. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png +0 -0
  190. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png +0 -0
  191. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png +0 -0
  192. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png +0 -0
  193. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png +0 -0
  194. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png +0 -0
  195. package/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png +0 -0
  196. package/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png +0 -0
  197. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png +0 -0
  198. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png +0 -0
  199. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png +0 -0
  200. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png +0 -0
  201. package/front_end/emulated_devices/iPad-landscape.svg +0 -73
  202. package/front_end/emulated_devices/iPad-portrait.svg +0 -76
  203. package/front_end/emulated_devices/iPhone5-landscape.svg +0 -99
  204. package/front_end/emulated_devices/iPhone5-portrait.svg +0 -83
  205. package/front_end/emulated_devices/iPhone6-landscape.svg +0 -111
  206. package/front_end/emulated_devices/iPhone6-portrait.svg +0 -116
  207. package/front_end/emulated_devices/iPhone6Plus-landscape.svg +0 -118
  208. package/front_end/emulated_devices/iPhone6Plus-portrait.svg +0 -116
  209. package/front_end/emulated_devices/optimized/MotoG4-landscape.avif +0 -0
  210. package/front_end/emulated_devices/optimized/MotoG4-portrait.avif +0 -0
  211. package/front_end/emulated_devices/optimized/Nexus5X-landscape.avif +0 -0
  212. package/front_end/emulated_devices/optimized/Nexus5X-portrait.avif +0 -0
  213. package/front_end/emulated_devices/optimized/Nexus6P-landscape.avif +0 -0
  214. package/front_end/emulated_devices/optimized/Nexus6P-portrait.avif +0 -0
  215. package/front_end/emulated_devices/optimized/README.md +0 -9
  216. package/front_end/emulated_devices/optimized/google-nest-hub-horizontal.avif +0 -0
  217. package/front_end/emulated_devices/optimized/google-nest-hub-max-horizontal.avif +0 -0
  218. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-1x.avif +0 -0
  219. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-2x.avif +0 -0
  220. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-1x.avif +0 -0
  221. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-2x.avif +0 -0
  222. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-1x.avif +0 -0
  223. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-2x.avif +0 -0
  224. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-1x.avif +0 -0
  225. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-2x.avif +0 -0
  226. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-1x.avif +0 -0
  227. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-2x.avif +0 -0
  228. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-1x.avif +0 -0
  229. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-2x.avif +0 -0
  230. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-1x.avif +0 -0
  231. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-2x.avif +0 -0
  232. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-1x.avif +0 -0
  233. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-2x.avif +0 -0
  234. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-1x.avif +0 -0
  235. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-2x.avif +0 -0
  236. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-1x.avif +0 -0
  237. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-2x.avif +0 -0
  238. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-1x.avif +0 -0
  239. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-2x.avif +0 -0
  240. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-1x.avif +0 -0
  241. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-2x.avif +0 -0
  242. package/front_end/emulated_devices/optimized/iPad-landscape.avif +0 -0
  243. package/front_end/emulated_devices/optimized/iPad-portrait.avif +0 -0
  244. package/front_end/emulated_devices/optimized/iPhone5-landscape.avif +0 -0
  245. package/front_end/emulated_devices/optimized/iPhone5-portrait.avif +0 -0
  246. package/front_end/emulated_devices/optimized/iPhone6-landscape.avif +0 -0
  247. package/front_end/emulated_devices/optimized/iPhone6-portrait.avif +0 -0
  248. package/front_end/emulated_devices/optimized/iPhone6Plus-landscape.avif +0 -0
  249. package/front_end/emulated_devices/optimized/iPhone6Plus-portrait.avif +0 -0
  250. package/front_end/emulated_devices/optimized/optimized_images.gni +0 -53
  251. package/front_end/models/ai_assistance/agents/README.md +0 -136
  252. package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +0 -92
  253. /package/front_end/{panels/common → ui/components/dialogs}/freDialog.css +0 -0
  254. /package/front_end/{panels/common/common.css → ui/components/dialogs/typeToAllowDialog.css} +0 -0
  255. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionDisclaimer.css +0 -0
  256. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionTeaser.css +0 -0
  257. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationTeaser.css +0 -0
  258. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationUpgradeDialog.css +0 -0
@@ -3,12 +3,9 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
- import * as i18n from '../../core/i18n/i18n.js';
7
6
  import * as Platform from '../../core/platform/platform.js';
8
- import * as Root from '../../core/root/root.js';
9
7
  import * as SDK from '../../core/sdk/sdk.js';
10
8
  import * as TextUtils from '../../core/text_utils/text_utils.js';
11
- import * as Protocol from '../../generated/protocol.js';
12
9
  import * as Formatter from '../formatter/formatter.js';
13
10
  import * as Workspace from '../workspace/workspace.js';
14
11
 
@@ -17,21 +14,6 @@ import {type DebuggerSourceMapping, DebuggerWorkspaceBinding} from './DebuggerWo
17
14
  import {NetworkProject} from './NetworkProject.js';
18
15
  import {metadataForURL} from './ResourceUtils.js';
19
16
 
20
- const UIStrings = {
21
- /**
22
- * @description Error text displayed in the Console panel when editing a live script fails. LiveEdit is the name of the feature for editing code that is already running.
23
- * @example {warning} PH1
24
- */
25
- liveEditFailed: '`LiveEdit` failed: {PH1}',
26
- /**
27
- * @description Error text displayed in the Console panel when compiling a live-edited script fails. LiveEdit is the name of the feature for editing code that is already running.
28
- * @example {connection lost} PH1
29
- */
30
- liveEditCompileFailed: '`LiveEdit` compile failed: {PH1}',
31
- } as const;
32
- const str_ = i18n.i18n.registerUIStrings('models/bindings/ResourceScriptMapping.ts', UIStrings);
33
- const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
34
-
35
17
  export class ResourceScriptMapping implements DebuggerSourceMapping {
36
18
  readonly debuggerModel: SDK.DebuggerModel.DebuggerModel;
37
19
  #workspace: Workspace.Workspace.WorkspaceImpl;
@@ -96,9 +78,6 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
96
78
  if (!scriptFile) {
97
79
  return null;
98
80
  }
99
- if ((scriptFile.hasDivergedFromVM() && !scriptFile.isMergingToVM()) || scriptFile.isDivergingFromVM()) {
100
- return null;
101
- }
102
81
  if (scriptFile.script !== script) {
103
82
  return null;
104
83
  }
@@ -205,8 +184,7 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
205
184
  }
206
185
 
207
186
  private addScript(script: SDK.Script.Script): void {
208
- // Ignore live edit scripts here.
209
- if (script.isLiveEdit() || script.isBreakpointCondition) {
187
+ if (script.isBreakpointCondition) {
210
188
  return;
211
189
  }
212
190
 
@@ -272,10 +250,6 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
272
250
  if (!uiSourceCode) {
273
251
  continue;
274
252
  }
275
- const scriptFile = this.#uiSourceCodeToScriptFile.get(uiSourceCode);
276
- if (scriptFile) {
277
- scriptFile.dispose();
278
- }
279
253
 
280
254
  this.#uiSourceCodeToScriptFile.delete(uiSourceCode);
281
255
  this.#scriptToUISourceCode.delete(script);
@@ -325,177 +299,17 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
325
299
  }
326
300
  }
327
301
 
328
- export class ResourceScriptFile extends Common.ObjectWrapper.ObjectWrapper<ResourceScriptFile.EventTypes> {
302
+ export class ResourceScriptFile {
329
303
  readonly #resourceScriptMapping: ResourceScriptMapping;
330
304
  readonly uiSourceCode: Workspace.UISourceCode.UISourceCode;
331
305
  readonly script: SDK.Script.Script|null;
332
- #scriptSource?: string|null;
333
- #isDivergingFromVM?: boolean;
334
- #hasDivergedFromVM?: boolean;
335
- #isMergingToVM?: boolean;
336
- #updateMutex = new Common.Mutex.Mutex();
306
+
337
307
  constructor(
338
308
  resourceScriptMapping: ResourceScriptMapping, uiSourceCode: Workspace.UISourceCode.UISourceCode,
339
309
  script: SDK.Script.Script) {
340
- super();
341
310
  this.#resourceScriptMapping = resourceScriptMapping;
342
311
  this.uiSourceCode = uiSourceCode;
343
312
  this.script = this.uiSourceCode.contentType().isScript() ? script : null;
344
-
345
- this.uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this.workingCopyChanged, this);
346
- this.uiSourceCode.addEventListener(
347
- Workspace.UISourceCode.Events.WorkingCopyCommitted, this.workingCopyCommitted, this);
348
- }
349
-
350
- private isDiverged(): boolean {
351
- if (this.uiSourceCode.isDirty()) {
352
- return true;
353
- }
354
- if (!this.script) {
355
- return false;
356
- }
357
- if (typeof this.#scriptSource === 'undefined' || this.#scriptSource === null) {
358
- return false;
359
- }
360
- const workingCopy = this.uiSourceCode.workingCopy();
361
- if (!workingCopy) {
362
- return false;
363
- }
364
-
365
- // Match ignoring sourceURL.
366
- if (!workingCopy.startsWith(this.#scriptSource.trimEnd())) {
367
- return true;
368
- }
369
- const suffix = this.uiSourceCode.workingCopy().substr(this.#scriptSource.length);
370
- return Boolean(suffix.length) && !suffix.match(SDK.Script.sourceURLRegex);
371
- }
372
-
373
- private workingCopyChanged(): void {
374
- void this.update();
375
- }
376
-
377
- private workingCopyCommitted(): void {
378
- // This feature flag is for turning down live edit. If it's not present, we keep the feature enabled.
379
- if (Root.Runtime.hostConfig.devToolsLiveEdit?.enabled === false) {
380
- return;
381
- }
382
-
383
- if (this.uiSourceCode.project().canSetFileContent()) {
384
- return;
385
- }
386
- if (!this.script) {
387
- return;
388
- }
389
-
390
- const source = this.uiSourceCode.workingCopy();
391
- void this.script.editSource(source).then(({status, exceptionDetails}) => {
392
- void this.scriptSourceWasSet(source, status, exceptionDetails);
393
- });
394
- }
395
-
396
- async scriptSourceWasSet(
397
- source: string, status: Protocol.Debugger.SetScriptSourceResponseStatus,
398
- exceptionDetails?: Protocol.Runtime.ExceptionDetails): Promise<void> {
399
- if (status === Protocol.Debugger.SetScriptSourceResponseStatus.Ok) {
400
- this.#scriptSource = source;
401
- }
402
- await this.update();
403
-
404
- if (status === Protocol.Debugger.SetScriptSourceResponseStatus.Ok) {
405
- return;
406
- }
407
-
408
- if (!exceptionDetails) {
409
- // TODO(crbug.com/1334484): Instead of to the console, report these errors in an "info bar" at the bottom
410
- // of the text editor, similar to e.g. source mapping errors.
411
- // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
412
- Common.Console.Console.instance().addMessage(
413
- i18nString(UIStrings.liveEditFailed, {PH1: getErrorText(status)}), Common.Console.MessageLevel.WARNING);
414
- return;
415
- }
416
- const messageText = i18nString(UIStrings.liveEditCompileFailed, {PH1: exceptionDetails.text});
417
- this.uiSourceCode.addLineMessage(
418
- Workspace.UISourceCode.Message.Level.ERROR, messageText, exceptionDetails.lineNumber,
419
- exceptionDetails.columnNumber);
420
-
421
- function getErrorText(status: Protocol.Debugger.SetScriptSourceResponseStatus): string {
422
- switch (status) {
423
- case Protocol.Debugger.SetScriptSourceResponseStatus.BlockedByActiveFunction:
424
- return 'Functions that are on the stack (currently being executed) can’t be edited';
425
- case Protocol.Debugger.SetScriptSourceResponseStatus.BlockedByActiveGenerator:
426
- return 'Async functions/generators that are active can’t be edited';
427
- case Protocol.Debugger.SetScriptSourceResponseStatus.BlockedByTopLevelEsModuleChange:
428
- return 'The top level of JavaScript modules can’t be edited';
429
- case Protocol.Debugger.SetScriptSourceResponseStatus.CompileError:
430
- case Protocol.Debugger.SetScriptSourceResponseStatus.Ok:
431
- throw new Error('Compile errors and Ok status must not be reported on the console');
432
- }
433
- }
434
- }
435
-
436
- private async update(): Promise<void> {
437
- // Do not interleave "divergeFromVM" with "mergeToVM" calls.
438
- const release = await this.#updateMutex.acquire();
439
- const diverged = this.isDiverged();
440
- if (diverged && !this.#hasDivergedFromVM) {
441
- await this.divergeFromVM();
442
- } else if (!diverged && this.#hasDivergedFromVM) {
443
- await this.mergeToVM();
444
- }
445
- release();
446
- }
447
-
448
- private async divergeFromVM(): Promise<void> {
449
- if (this.script) {
450
- this.#isDivergingFromVM = true;
451
- await this.#resourceScriptMapping.debuggerWorkspaceBinding.updateLocations(this.script);
452
- this.#isDivergingFromVM = undefined;
453
- this.#hasDivergedFromVM = true;
454
- this.dispatchEventToListeners(ResourceScriptFile.Events.DID_DIVERGE_FROM_VM);
455
- }
456
- }
457
-
458
- private async mergeToVM(): Promise<void> {
459
- if (this.script) {
460
- this.#hasDivergedFromVM = undefined;
461
- this.#isMergingToVM = true;
462
- await this.#resourceScriptMapping.debuggerWorkspaceBinding.updateLocations(this.script);
463
- this.#isMergingToVM = undefined;
464
- this.dispatchEventToListeners(ResourceScriptFile.Events.DID_MERGE_TO_VM);
465
- }
466
- }
467
-
468
- hasDivergedFromVM(): boolean {
469
- return Boolean(this.#hasDivergedFromVM);
470
- }
471
-
472
- isDivergingFromVM(): boolean {
473
- return Boolean(this.#isDivergingFromVM);
474
- }
475
-
476
- isMergingToVM(): boolean {
477
- return Boolean(this.#isMergingToVM);
478
- }
479
-
480
- checkMapping(): void {
481
- if (!this.script || typeof this.#scriptSource !== 'undefined') {
482
- this.mappingCheckedForTest();
483
- return;
484
- }
485
- void this.script.requestContentData().then(content => {
486
- this.#scriptSource = TextUtils.ContentData.ContentData.textOr(content, null);
487
- void this.update().then(() => this.mappingCheckedForTest());
488
- });
489
- }
490
-
491
- private mappingCheckedForTest(): void {
492
- }
493
-
494
- dispose(): void {
495
- this.uiSourceCode.removeEventListener(
496
- Workspace.UISourceCode.Events.WorkingCopyChanged, this.workingCopyChanged, this);
497
- this.uiSourceCode.removeEventListener(
498
- Workspace.UISourceCode.Events.WorkingCopyCommitted, this.workingCopyCommitted, this);
499
313
  }
500
314
 
501
315
  addSourceMapURL(sourceMapURL: Platform.DevToolsPath.UrlString): void {
@@ -527,15 +341,3 @@ export class ResourceScriptFile extends Common.ObjectWrapper.ObjectWrapper<Resou
527
341
  return sources && 'missingSymbolFiles' in sources ? sources.missingSymbolFiles : null;
528
342
  }
529
343
  }
530
-
531
- export namespace ResourceScriptFile {
532
- export const enum Events {
533
- DID_MERGE_TO_VM = 'DidMergeToVM',
534
- DID_DIVERGE_FROM_VM = 'DidDivergeFromVM',
535
- }
536
-
537
- export interface EventTypes {
538
- [Events.DID_MERGE_TO_VM]: void;
539
- [Events.DID_DIVERGE_FROM_VM]: void;
540
- }
541
- }
@@ -140,6 +140,12 @@ export class SASSSourceMapping implements SourceMapping {
140
140
  return [];
141
141
  }
142
142
 
143
+ static sourceMapURLsForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
144
+ Platform.DevToolsPath.UrlString[] {
145
+ const binding = uiSourceCodeToBinding.get(uiSourceCode);
146
+ return binding?.getReferringSourceMaps().map(sourceMap => sourceMap.url()) ?? [];
147
+ }
148
+
143
149
  dispose(): void {
144
150
  Common.EventTarget.removeEventListeners(this.#eventListeners);
145
151
  this.#project.dispose();
@@ -8,7 +8,7 @@ import {assertNotNullOrUndefined} from '../../core/platform/platform.js';
8
8
  import * as Root from '../../core/root/root.js';
9
9
  import * as SDK from '../../core/sdk/sdk.js';
10
10
  import type * as TextUtils from '../../core/text_utils/text_utils.js';
11
- import * as Protocol from '../../generated/protocol.js';
11
+ import type * as Protocol from '../../generated/protocol.js';
12
12
  import * as Bindings from '../bindings/bindings.js';
13
13
  import * as Formatter from '../formatter/formatter.js';
14
14
  import * as SourceMapScopes from '../source_map_scopes/source_map_scopes.js';
@@ -608,7 +608,6 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
608
608
 
609
609
  debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerWasEnabled, this.#onDebuggerEnabled, this);
610
610
  debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerWasDisabled, this.#onDebuggerDisabled, this);
611
- debuggerModel.addEventListener(SDK.DebuggerModel.Events.ScriptSourceWasEdited, this.#onScriptWasEdited, this);
612
611
  }
613
612
 
614
613
  modelRemoved(debuggerModel: SDK.DebuggerModel.DebuggerModel): void {
@@ -622,7 +621,6 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
622
621
  #removeDebuggerModelListeners(debuggerModel: SDK.DebuggerModel.DebuggerModel): void {
623
622
  debuggerModel.removeEventListener(SDK.DebuggerModel.Events.DebuggerWasEnabled, this.#onDebuggerEnabled, this);
624
623
  debuggerModel.removeEventListener(SDK.DebuggerModel.Events.DebuggerWasDisabled, this.#onDebuggerDisabled, this);
625
- debuggerModel.removeEventListener(SDK.DebuggerModel.Events.ScriptSourceWasEdited, this.#onScriptWasEdited, this);
626
624
  }
627
625
 
628
626
  #onDebuggerEnabled(event: Common.EventTarget.EventTargetEvent<SDK.DebuggerModel.DebuggerModel>): void {
@@ -639,29 +637,6 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
639
637
  model?.cleanUpAfterDebuggerIsGone();
640
638
  }
641
639
 
642
- async #onScriptWasEdited(
643
- event: Common.EventTarget
644
- .EventTargetEvent<{script: SDK.Script.Script, status: Protocol.Debugger.SetScriptSourceResponseStatus}>):
645
- Promise<void> {
646
- const {source: debuggerModel, data: {script, status}} = event;
647
- if (status !== Protocol.Debugger.SetScriptSourceResponseStatus.Ok) {
648
- return;
649
- }
650
-
651
- // V8 throws away breakpoints on all functions in a live edited script. Here we attempt to re-set them again at the
652
- // same position. This is because we don't know what was edited and how the breakpoint should move, e.g. if the file
653
- // was originally changed on the filesystem (via workspace).
654
- // If the live edit originated in DevTools (in CodeMirror), then the `DebuggerPlugin` will remove the breakpoint
655
- // wholesale and re-apply based on the diff.
656
-
657
- console.assert(debuggerModel instanceof SDK.DebuggerModel.DebuggerModel);
658
- const model = this.#modelBreakpoints.get(debuggerModel as SDK.DebuggerModel.DebuggerModel);
659
- if (model?.wasSetIn(script.scriptId)) {
660
- await model.resetBreakpoint();
661
- void this.#updateModel(model);
662
- }
663
- }
664
-
665
640
  modelBreakpoint(debuggerModel: SDK.DebuggerModel.DebuggerModel): ModelBreakpoint|undefined {
666
641
  return this.#modelBreakpoints.get(debuggerModel);
667
642
  }
@@ -966,11 +941,6 @@ export class ModelBreakpoint {
966
941
  #cancelCallback = false;
967
942
  #currentState: Breakpoint.State|null = null;
968
943
  #breakpointIds: Protocol.Debugger.BreakpointId[] = [];
969
- /**
970
- * We track all the script IDs this ModelBreakpoint was actually set in. This allows us
971
- * to properly reset this ModelBreakpoint after a script was live edited.
972
- */
973
- #resolvedScriptIds = new Set<Protocol.Runtime.ScriptId>();
974
944
 
975
945
  constructor(
976
946
  debuggerModel: SDK.DebuggerModel.DebuggerModel, breakpoint: Breakpoint,
@@ -991,7 +961,6 @@ export class ModelBreakpoint {
991
961
 
992
962
  this.#uiLocations.clear();
993
963
  this.#liveLocations.disposeAll();
994
- this.#resolvedScriptIds.clear();
995
964
  }
996
965
 
997
966
  async scheduleUpdateInDebugger(): Promise<ScheduleUpdateResult> {
@@ -1021,16 +990,6 @@ export class ModelBreakpoint {
1021
990
  return result;
1022
991
  }
1023
992
 
1024
- private scriptDiverged(): boolean {
1025
- for (const uiSourceCode of this.#breakpoint.getUiSourceCodes()) {
1026
- const scriptFile = this.#debuggerWorkspaceBinding.scriptFile(uiSourceCode, this.#debuggerModel);
1027
- if (scriptFile?.hasDivergedFromVM()) {
1028
- return true;
1029
- }
1030
- }
1031
- return false;
1032
- }
1033
-
1034
993
  async #updateInDebugger(): Promise<DebuggerUpdateResult> {
1035
994
  if (this.#debuggerModel.target().isDisposed()) {
1036
995
  this.cleanUpAfterDebuggerIsGone();
@@ -1042,7 +1001,7 @@ export class ModelBreakpoint {
1042
1001
 
1043
1002
  // Calculate the new state.
1044
1003
  let newState: Breakpoint.State|null = null;
1045
- if (!this.#breakpoint.getIsRemoved() && this.#breakpoint.enabled() && !this.scriptDiverged()) {
1004
+ if (!this.#breakpoint.getIsRemoved() && this.#breakpoint.enabled()) {
1046
1005
  let debuggerLocations: SDK.DebuggerModel.Location[] = [];
1047
1006
  for (const uiSourceCode of this.#breakpoint.getUiSourceCodes()) {
1048
1007
  const {lineNumber: uiLineNumber, columnNumber: uiColumnNumber} =
@@ -1226,7 +1185,6 @@ export class ModelBreakpoint {
1226
1185
  }
1227
1186
 
1228
1187
  private async addResolvedLocation(location: SDK.DebuggerModel.Location): Promise<ResolveLocationResult> {
1229
- this.#resolvedScriptIds.add(location.scriptId);
1230
1188
  const uiLocation = await this.#debuggerWorkspaceBinding.rawLocationToUILocation(location);
1231
1189
  if (!uiLocation) {
1232
1190
  return ResolveLocationResult.OK;
@@ -1249,11 +1207,6 @@ export class ModelBreakpoint {
1249
1207
  this.didRemoveFromDebugger();
1250
1208
  }
1251
1209
  }
1252
-
1253
- /** @returns true, iff this `ModelBreakpoint` was set (at some point) in `scriptId` */
1254
- wasSetIn(scriptId: Protocol.Runtime.ScriptId): boolean {
1255
- return this.#resolvedScriptIds.has(scriptId);
1256
- }
1257
1210
  }
1258
1211
 
1259
1212
  /**
@@ -124,21 +124,23 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
124
124
  #touchMobile: boolean;
125
125
  #emulationModel: SDK.EmulationModel.EmulationModel|null;
126
126
  #onModelAvailable: (() => void)|null;
127
- #outlineRect?: Rect;
128
127
  #screenOrientationLocked: boolean;
129
128
  readonly #targetManager: SDK.TargetManager.TargetManager;
130
129
  readonly #settings: Common.Settings.Settings;
131
130
  readonly #multitargetNetworkManager: SDK.NetworkManager.MultitargetNetworkManager;
131
+ readonly #fileManager: Workspace.FileManager.FileManager;
132
132
 
133
133
  constructor(
134
134
  targetManager: SDK.TargetManager.TargetManager,
135
135
  settings: Common.Settings.Settings,
136
136
  multitargetNetworkManager: SDK.NetworkManager.MultitargetNetworkManager,
137
+ fileManager: Workspace.FileManager.FileManager,
137
138
  ) {
138
139
  super();
139
140
  this.#targetManager = targetManager;
140
141
  this.#settings = settings;
141
142
  this.#multitargetNetworkManager = multitargetNetworkManager;
143
+ this.#fileManager = fileManager;
142
144
  this.#screenRect = new Rect(0, 0, 1, 1);
143
145
  this.#visiblePageRect = new Rect(0, 0, 1, 1);
144
146
  this.#availableSize = new Geometry.Size(1, 1);
@@ -207,6 +209,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
207
209
  Common.Settings.Settings.instance(),
208
210
  // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
209
211
  SDK.NetworkManager.MultitargetNetworkManager.instance(),
212
+ // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
213
+ Workspace.FileManager.FileManager.instance(),
210
214
  ));
211
215
  }
212
216
 
@@ -313,8 +317,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
313
317
  #updateFitScale(): void {
314
318
  if (this.#type === Type.Device && this.#device && this.#mode) {
315
319
  const orientation = this.#device.orientationByName(this.#mode.orientation);
316
- this.#scaleSetting.set(
317
- this.calculateFitScale(orientation.width, orientation.height, this.currentOutline(), this.currentInsets()));
320
+ this.#scaleSetting.set(this.calculateFitScale(orientation.width, orientation.height, this.currentInsets()));
318
321
  }
319
322
  }
320
323
 
@@ -401,18 +404,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
401
404
  return this.#type;
402
405
  }
403
406
 
404
- screenImage(): string {
405
- return (this.#device && this.#mode) ? this.#device.modeImage(this.#mode) : '';
406
- }
407
-
408
- canShowDeviceFrame(): boolean {
409
- return Boolean(this.#device && this.#mode && this.#device.outlineImage(this.#mode));
410
- }
411
-
412
- outlineRect(): Rect|null {
413
- return this.#outlineRect || null;
414
- }
415
-
416
407
  screenRect(): Rect {
417
408
  return this.#screenRect;
418
409
  }
@@ -604,10 +595,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
604
595
  return Math.floor(this.#preferredSize.height / (this.#scaleSetting.get() || 1));
605
596
  }
606
597
 
607
- private currentOutline(): Insets {
608
- return new Insets(0, 0, 0, 0);
609
- }
610
-
611
598
  private currentInsets(): Insets {
612
599
  if (this.#type !== Type.Device || !this.#mode) {
613
600
  return new Insets(0, 0, 0, 0);
@@ -660,25 +647,22 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
660
647
  }
661
648
  if (this.#type === Type.Device && this.#device && this.#mode) {
662
649
  const orientation = this.#device.orientationByName(this.#mode.orientation);
663
- const outline = this.currentOutline();
664
650
  const insets = this.currentInsets();
665
- this.#fitScale = this.calculateFitScale(orientation.width, orientation.height, outline, insets);
651
+ this.#fitScale = this.calculateFitScale(orientation.width, orientation.height, insets);
666
652
  if (mobile) {
667
653
  this.#appliedUserAgentType = this.#device.touch() ? UA.MOBILE : UA.MOBILE_NO_TOUCH;
668
654
  } else {
669
655
  this.#appliedUserAgentType = this.#device.touch() ? UA.DESKTOP_TOUCH : UA.DESKTOP;
670
656
  }
671
- this.applyDeviceMetrics(
672
- new Geometry.Size(orientation.width, orientation.height), insets, outline, this.#scaleSetting.get(),
673
- 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);
674
660
  this.applyUserAgent(this.#device.userAgent, this.#device.userAgentMetadata);
675
661
  this.applyTouch(this.#device.touch(), mobile);
676
662
  } else if (this.#type === Type.None) {
677
663
  this.#fitScale = this.calculateFitScale(this.#availableSize.width, this.#availableSize.height);
678
664
  this.#appliedUserAgentType = UA.DESKTOP;
679
- this.applyDeviceMetrics(
680
- this.#availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1, 0, mobile, null,
681
- resetPageScaleFactor);
665
+ this.applyDeviceMetrics(this.#availableSize, new Insets(0, 0, 0, 0), 1, 0, mobile, null, resetPageScaleFactor);
682
666
  this.applyUserAgent('', null);
683
667
  this.applyTouch(false, false);
684
668
  } else if (this.#type === Type.Responsive) {
@@ -693,12 +677,12 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
693
677
  const defaultDeviceScaleFactor = mobile ? defaultMobileScaleFactor : 0;
694
678
  this.#fitScale = this.calculateFitScale(this.#widthSetting.get(), this.#heightSetting.get());
695
679
  this.#appliedUserAgentType = this.#uaSetting.get();
696
- this.applyDeviceMetrics(
697
- new Geometry.Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0),
698
- this.#scaleSetting.get(), this.#deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
699
- screenHeight >= screenWidth ? Protocol.Emulation.ScreenOrientationType.PortraitPrimary :
700
- Protocol.Emulation.ScreenOrientationType.LandscapePrimary,
701
- 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);
702
686
  this.applyUserAgent(
703
687
  mobile ? DeviceModeModel.defaultMobileUserAgent() : '',
704
688
  mobile ? DeviceModeModel.defaultMobileUserAgentMetadata() : null);
@@ -714,14 +698,11 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
714
698
  this.dispatchEventToListeners(Events.UPDATED);
715
699
  }
716
700
 
717
- private calculateFitScale(screenWidth: number, screenHeight: number, outline?: Insets, insets?: Insets): number {
718
- const outlineWidth = outline ? outline.left + outline.right : 0;
719
- const outlineHeight = outline ? outline.top + outline.bottom : 0;
701
+ private calculateFitScale(screenWidth: number, screenHeight: number, insets?: Insets): number {
720
702
  const insetsWidth = insets ? insets.left + insets.right : 0;
721
703
  const insetsHeight = insets ? insets.top + insets.bottom : 0;
722
- let scale = Math.min(
723
- screenWidth ? this.#preferredSize.width / (screenWidth + outlineWidth) : 1,
724
- 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);
725
706
  scale = Math.min(Math.floor(scale * 100), 100);
726
707
 
727
708
  let sharpScale = scale;
@@ -754,10 +735,9 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
754
735
  this.#multitargetNetworkManager.setUserAgentOverride(userAgent, userAgent ? userAgentMetadata : null);
755
736
  }
756
737
 
757
- private applyDeviceMetrics(
758
- screenSize: Geometry.Size, insets: Insets, outline: Insets, scale: number, deviceScaleFactor: number,
759
- mobile: boolean, screenOrientation: Protocol.Emulation.ScreenOrientationType|null,
760
- 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 {
761
741
  screenSize.width = Math.max(1, Math.floor(screenSize.width));
762
742
  screenSize.height = Math.max(1, Math.floor(screenSize.height));
763
743
 
@@ -771,12 +751,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
771
751
 
772
752
  this.#appliedDeviceSize = screenSize;
773
753
  this.#appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
774
- this.#screenRect = new Rect(
775
- Math.max(0, (this.#availableSize.width - screenSize.width * scale) / 2), outline.top * scale,
776
- screenSize.width * scale, screenSize.height * scale);
777
- this.#outlineRect = new Rect(
778
- this.#screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale,
779
- (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);
780
756
  this.#visiblePageRect = new Rect(
781
757
  positionX * scale, positionY * scale,
782
758
  Math.min(pageWidth * scale, this.#availableSize.width - this.#screenRect.left - positionX * scale),
@@ -898,29 +874,21 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
898
874
  pageImage.src = 'data:image/png;base64,' + screenshot;
899
875
  pageImage.onload = async () => {
900
876
  const scale = pageImage.naturalWidth / this.screenRect().width;
901
- const outlineRectFromModel = this.outlineRect();
902
- if (!outlineRectFromModel) {
903
- throw new Error('Unable to take screenshot: no outlineRect available.');
904
- }
905
- const outlineRect = outlineRectFromModel.scale(scale);
906
877
  const screenRect = this.screenRect().scale(scale);
907
878
  const visiblePageRect = this.visiblePageRect().scale(scale);
908
- const contentLeft = screenRect.left + visiblePageRect.left - outlineRect.left;
909
- const contentTop = screenRect.top + visiblePageRect.top - outlineRect.top;
879
+ const contentLeft = visiblePageRect.left;
880
+ const contentTop = visiblePageRect.top;
910
881
 
911
- const canvas = new OffscreenCanvas(Math.floor(outlineRect.width),
882
+ const canvas = new OffscreenCanvas(Math.floor(screenRect.width),
912
883
  // Cap the height to not hit the GPU limit.
913
884
  // https://crbug.com/1260828
914
- Math.min((1 << 14), Math.floor(outlineRect.height)));
885
+ Math.min((1 << 14), Math.floor(screenRect.height)));
915
886
  const ctx = canvas.getContext('2d', {willReadFrequently: true});
916
887
  if (!ctx) {
917
888
  throw new Error('Could not get 2d context from canvas.');
918
889
  }
919
890
  ctx.imageSmoothingEnabled = false;
920
891
 
921
- if (this.screenImage()) {
922
- await this.paintImage(ctx, this.screenImage(), screenRect.relativeTo(outlineRect));
923
- }
924
892
  ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
925
893
  void this.saveScreenshot(canvas);
926
894
  };
@@ -976,17 +944,41 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
976
944
 
977
945
  private async saveScreenshot(canvas: OffscreenCanvas): Promise<void> {
978
946
  const url = this.inspectedURL();
979
- let fileName = '';
947
+ let baseName = '';
980
948
  if (url) {
981
- const withoutFragment = Platform.StringUtilities.removeURLFragment(url);
982
- 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
+ }
983
959
  }
984
960
 
961
+ if (!baseName) {
962
+ baseName = 'screenshot';
963
+ }
964
+
965
+ let suffix = '';
985
966
  const device = this.device();
986
967
  if (device && this.type() === Type.Device) {
987
- 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';
988
981
  }
989
- fileName += '.png';
990
982
  const blob = await canvas.convertToBlob({type: 'image/png'});
991
983
  const dataUrl = await new Promise<string>((resolve, reject) => {
992
984
  const reader = new FileReader();
@@ -996,11 +988,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
996
988
  });
997
989
  const base64 = dataUrl.slice(dataUrl.indexOf(',') + 1);
998
990
  const contentData = new TextUtils.ContentData.ContentData(base64, /* isBase64=*/ true, 'image/png');
999
- // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
1000
- await Workspace.FileManager.FileManager.instance().save(fileName as Platform.DevToolsPath.RawPathString,
1001
- contentData, /* forceSaveAs=*/ true);
1002
- // eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
1003
- 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);
1004
993
  }
1005
994
 
1006
995
  private applyTouch(touchEnabled: boolean, mobile: boolean): void {