chrome-devtools-frontend 1.0.1708524 → 1.0.1711155

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 (217) hide show
  1. package/AUTHORS +3 -0
  2. package/front_end/core/common/Color.ts +6 -0
  3. package/front_end/core/common/ParsedURL.ts +20 -19
  4. package/front_end/core/common/VersionController.ts +0 -53
  5. package/front_end/core/root/Runtime.ts +0 -41
  6. package/front_end/core/sdk/CSSModel.ts +57 -0
  7. package/front_end/core/sdk/CSSPropertyParser.ts +10 -17
  8. package/front_end/core/sdk/DOMModel.ts +6 -4
  9. package/front_end/core/sdk/DebuggerModel.ts +90 -56
  10. package/front_end/core/sdk/NetworkRequest.ts +37 -15
  11. package/front_end/core/sdk/OverlayModel.ts +47 -0
  12. package/front_end/core/sdk/PageFunctions.ts +1 -1
  13. package/front_end/core/sdk/PageResourceLoader.ts +26 -6
  14. package/front_end/core/sdk/SourceMap.ts +38 -1
  15. package/front_end/core/sdk/SourceMapScopesInfo.ts +89 -0
  16. package/front_end/core/text_utils/TextUtils.ts +1 -1
  17. package/front_end/entrypoints/devtools_app/devtools_app.ts +1 -0
  18. package/front_end/entrypoints/main/MainImpl.ts +2 -21
  19. package/front_end/generated/InspectorBackendCommands.ts +3 -1
  20. package/front_end/generated/SupportedCSSProperties.ts +1 -1
  21. package/front_end/generated/protocol-mapping.d.ts +7 -0
  22. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  23. package/front_end/generated/protocol.ts +20 -3
  24. package/front_end/models/ai_assistance/AiAgent2.ts +126 -2
  25. package/front_end/models/ai_assistance/AiConversation.ts +2 -2
  26. package/front_end/models/ai_assistance/AiUtils.ts +4 -0
  27. package/front_end/models/ai_assistance/agents/AiAgent.ts +71 -17
  28. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +2 -2
  29. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +4 -1
  30. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +257 -2
  31. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +1 -1
  32. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -0
  33. package/front_end/models/ai_assistance/ai_assistance.ts +2 -2
  34. package/front_end/models/ai_assistance/contexts/LighthouseContext.snapshot.txt +52 -0
  35. package/front_end/models/ai_assistance/contexts/{AccessibilityContext.ts → LighthouseContext.ts} +25 -5
  36. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +11 -0
  37. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +47 -19
  38. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +8 -18
  39. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +2 -2
  40. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +81 -103
  41. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +202 -15
  42. package/front_end/models/ai_assistance/skills/accessibility.md +1 -0
  43. package/front_end/models/ai_assistance/skills/lighthouse.md +1 -0
  44. package/front_end/models/ai_assistance/skills/styling.md +1 -0
  45. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +6 -0
  46. package/front_end/models/ai_assistance/tools/GetCookieValues.ts +3 -0
  47. package/front_end/models/ai_assistance/tools/GetDetailedCallTree.ts +2 -0
  48. package/front_end/models/ai_assistance/tools/GetElementAccessibilityDetails.ts +2 -0
  49. package/front_end/models/ai_assistance/tools/GetInsightDetails.ts +2 -0
  50. package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +2 -1
  51. package/front_end/models/ai_assistance/tools/GetNetworkRequestDetails.ts +2 -0
  52. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +2 -0
  53. package/front_end/models/ai_assistance/tools/GetStorageBreakdown.ts +2 -0
  54. package/front_end/models/ai_assistance/tools/GetStorageValues.ts +3 -0
  55. package/front_end/models/ai_assistance/tools/GetStyles.ts +2 -0
  56. package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +3 -1
  57. package/front_end/models/ai_assistance/tools/GetTraceFunctionCode.ts +2 -0
  58. package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +2 -0
  59. package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +2 -0
  60. package/front_end/models/ai_assistance/tools/GetTraceResourceContent.ts +2 -0
  61. package/front_end/models/ai_assistance/tools/ListCookies.ts +2 -0
  62. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -0
  63. package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +2 -0
  64. package/front_end/models/ai_assistance/tools/ListSources.ts +13 -5
  65. package/front_end/models/ai_assistance/tools/ListStorageKeys.ts +2 -0
  66. package/front_end/models/ai_assistance/tools/RecordPerformanceTrace.ts +2 -0
  67. package/front_end/models/ai_assistance/tools/ResolveDevtoolsNodePath.ts +2 -0
  68. package/front_end/models/ai_assistance/tools/RunLighthouse.ts +14 -9
  69. package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +2 -0
  70. package/front_end/models/ai_assistance/tools/Tool.ts +53 -0
  71. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +41 -10
  72. package/front_end/models/bindings/SourceMapStepping.ts +122 -0
  73. package/front_end/models/bindings/StylesSourceMapping.ts +3 -0
  74. package/front_end/models/bindings/bindings.ts +2 -0
  75. package/front_end/models/emulation/DeviceModeModel.ts +91 -63
  76. package/front_end/models/har/HARFormat.ts +2 -7
  77. package/front_end/models/har/Importer.ts +2 -3
  78. package/front_end/models/javascript_metadata/NativeFunctions.ts +52 -48
  79. package/front_end/models/lighthouse/LighthouseReporterTypes.ts +5 -1
  80. package/front_end/models/persistence/Automapping.ts +8 -3
  81. package/front_end/models/source_map_scopes/NamesResolver.ts +30 -5
  82. package/front_end/models/trace/LanternComputationData.ts +8 -0
  83. package/front_end/models/trace/Processor.ts +2 -1
  84. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +7 -2
  85. package/front_end/models/trace/lantern/graph/NetworkNode.ts +14 -0
  86. package/front_end/models/trace/lantern/graph/PageDependencyGraph.ts +2 -2
  87. package/front_end/models/trace/lantern/metrics/TotalBlockingTime.ts +1 -1
  88. package/front_end/models/trace/lantern/simulation/ConnectionPool.ts +4 -4
  89. package/front_end/models/trace/lantern/simulation/Simulator.ts +6 -2
  90. package/front_end/models/trace/lantern/simulation/TCPConnection.ts +12 -12
  91. package/front_end/models/trace/lantern/types/Lantern.ts +8 -0
  92. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +14 -12
  93. package/front_end/panels/ai_assistance/components/ChatInput.ts +1 -1
  94. package/front_end/panels/ai_assistance/components/ChatMessage.ts +121 -13
  95. package/front_end/panels/ai_assistance/components/chatMessage.css +47 -0
  96. package/front_end/panels/application/BackgroundServiceView.ts +31 -33
  97. package/front_end/panels/application/BounceTrackingMitigationsTreeElement.ts +1 -1
  98. package/front_end/panels/application/CookieItemsView.ts +10 -10
  99. package/front_end/panels/application/DOMStorageItemsView.ts +7 -8
  100. package/front_end/panels/application/ExtensionStorageItemsView.ts +4 -5
  101. package/front_end/panels/application/IndexedDBModel.ts +8 -20
  102. package/front_end/panels/application/IndexedDBViews.ts +31 -37
  103. package/front_end/panels/application/KeyValueStorageItemsView.ts +5 -5
  104. package/front_end/panels/application/ServiceWorkerCacheTreeElement.ts +6 -6
  105. package/front_end/panels/application/ServiceWorkerCacheViews.ts +17 -17
  106. package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +8 -8
  107. package/front_end/panels/application/ServiceWorkersView.ts +44 -52
  108. package/front_end/panels/application/StorageBucketsTreeElement.ts +3 -10
  109. package/front_end/panels/application/StorageItemsToolbar.ts +6 -6
  110. package/front_end/panels/application/StorageView.ts +36 -34
  111. package/front_end/panels/application/TrustTokensTreeElement.ts +1 -2
  112. package/front_end/panels/application/WebMCPView.ts +50 -50
  113. package/front_end/panels/comments/CommentsPane.ts +266 -0
  114. package/front_end/panels/comments/comments-meta.ts +47 -0
  115. package/front_end/panels/comments/comments.ts +9 -0
  116. package/front_end/panels/comments/commentsPane.css +206 -0
  117. package/front_end/panels/common/CommentThreadWidget.ts +0 -17
  118. package/front_end/panels/common/CommentsOverlayWidget.ts +0 -4
  119. package/front_end/panels/common/CommentsStatusBarPill.ts +3 -1
  120. package/front_end/panels/common/ExtensionServer.ts +52 -50
  121. package/front_end/panels/common/commentThreadWidget.css +0 -4
  122. package/front_end/panels/console/ConsoleViewMessage.ts +1 -2
  123. package/front_end/panels/console/ConsoleViewport.ts +1 -1
  124. package/front_end/panels/console/SymbolizedErrorWidget.ts +18 -9
  125. package/front_end/panels/elements/CSSValueTraceView.ts +4 -4
  126. package/front_end/panels/elements/ComputedStyleWidget.ts +46 -42
  127. package/front_end/panels/elements/DOMPath.ts +17 -1
  128. package/front_end/panels/elements/DOMTreeContextMenu.ts +15 -0
  129. package/front_end/panels/elements/DOMTreeWidget.ts +37 -23
  130. package/front_end/panels/elements/ElementsPanel.ts +14 -11
  131. package/front_end/panels/elements/ElementsTreeElement.ts +24 -18
  132. package/front_end/panels/elements/EventListenersWidget.ts +5 -3
  133. package/front_end/panels/elements/InspectElementModeController.ts +6 -3
  134. package/front_end/panels/elements/LayoutPane.ts +3 -3
  135. package/front_end/panels/elements/PropertyRenderer.ts +132 -87
  136. package/front_end/panels/elements/StandaloneStylesContainer.ts +7 -3
  137. package/front_end/panels/elements/StylePropertiesSection.ts +49 -4
  138. package/front_end/panels/elements/StylePropertyTreeElement.ts +59 -51
  139. package/front_end/panels/elements/StylePropertyUtils.ts +11 -3
  140. package/front_end/panels/elements/StylesContainer.ts +2 -1
  141. package/front_end/panels/elements/StylesSidebarPane.ts +75 -16
  142. package/front_end/panels/elements/components/CSSPropertyDocsView.ts +2 -1
  143. package/front_end/panels/elements/elements-meta.ts +24 -75
  144. package/front_end/panels/emulation/DeviceModeToolbar.ts +5 -2
  145. package/front_end/panels/emulation/DeviceModeView.ts +6 -3
  146. package/front_end/panels/emulation/emulation-meta.ts +3 -8
  147. package/front_end/panels/layer_viewer/Layers3DView.ts +11 -7
  148. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +3 -10
  149. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +13 -3
  150. package/front_end/panels/network/NetworkConfigView.ts +30 -3
  151. package/front_end/panels/network/NetworkDataGridNode.ts +3 -0
  152. package/front_end/panels/network/NetworkLogView.ts +15 -18
  153. package/front_end/panels/network/NetworkPanel.ts +4 -3
  154. package/front_end/panels/network/NetworkWaterfallColumn.ts +7 -4
  155. package/front_end/panels/network/network-meta.ts +23 -34
  156. package/front_end/panels/profiler/HeapProfileView.ts +20 -24
  157. package/front_end/panels/profiler/ProfilesPanel.ts +8 -3
  158. package/front_end/panels/screencast/ScreencastView.ts +6 -4
  159. package/front_end/panels/security/SecurityPanel.ts +27 -20
  160. package/front_end/panels/sources/DebuggerPlugin.ts +2 -2
  161. package/front_end/panels/sources/SourcesPanel.ts +9 -1
  162. package/front_end/panels/sources/SourcesView.ts +1 -1
  163. package/front_end/panels/sources/TabbedEditorContainer.ts +36 -32
  164. package/front_end/panels/sources/UISourceCodeFrame.ts +69 -64
  165. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +4 -1
  166. package/front_end/panels/timeline/CountersGraph.ts +19 -10
  167. package/front_end/panels/timeline/ModificationsManager.ts +3 -1
  168. package/front_end/panels/timeline/ThreadAppender.ts +4 -1
  169. package/front_end/panels/timeline/TimelineController.ts +9 -2
  170. package/front_end/panels/timeline/TimelineDetailsView.ts +4 -1
  171. package/front_end/panels/timeline/TimelineEventOverview.ts +3 -5
  172. package/front_end/panels/timeline/TimelineFlameChartView.ts +1 -4
  173. package/front_end/panels/timeline/TimelineHistoryManager.ts +2 -4
  174. package/front_end/panels/timeline/TimelinePanel.ts +27 -16
  175. package/front_end/panels/timeline/TimelineTreeView.ts +0 -6
  176. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -3
  177. package/front_end/panels/timeline/components/LiveMetricsView.ts +7 -20
  178. package/front_end/panels/timeline/components/MetricCard.ts +262 -315
  179. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +3 -1
  180. package/front_end/panels/timeline/components/liveMetricsView.css +4 -0
  181. package/front_end/panels/timeline/components/metricCard.css +2 -24
  182. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +36 -18
  183. package/front_end/panels/timeline/overlays/components/TimeRangeOverlay.ts +298 -196
  184. package/front_end/panels/timeline/overlays/components/timeRangeOverlay.css +76 -74
  185. package/front_end/panels/timeline/timeline-meta.ts +22 -84
  186. package/front_end/panels/whats_new/WhatsNewImpl.ts +2 -1
  187. package/front_end/panels/whats_new/whats_new-meta.ts +2 -5
  188. package/front_end/third_party/chromium/README.chromium +1 -1
  189. package/front_end/third_party/web-vitals/README.chromium +2 -2
  190. package/front_end/third_party/web-vitals/package/README.md +5 -3
  191. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +1 -1
  192. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +8 -5
  193. package/front_end/third_party/web-vitals/package/package.json +1 -1
  194. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +1 -1
  195. package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +9 -5
  196. package/front_end/third_party/web-vitals/rebuild.sh +2 -2
  197. package/front_end/ui/components/text_editor/TextEditor.ts +18 -6
  198. package/front_end/ui/components/text_editor/config.ts +2 -1
  199. package/front_end/ui/legacy/TabbedPane.ts +83 -12
  200. package/front_end/ui/legacy/TextPrompt.ts +80 -19
  201. package/front_end/ui/legacy/Toolbar.ts +29 -9
  202. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +93 -31
  203. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +15 -7
  204. package/front_end/ui/legacy/components/source_frame/ImageView.ts +11 -4
  205. package/front_end/ui/legacy/components/utils/Linkifier.ts +33 -17
  206. package/front_end/ui/legacy/tabbedPane.css +12 -8
  207. package/front_end/ui/settings/ElementsSettings.ts +93 -0
  208. package/front_end/ui/settings/EmulationSettings.ts +17 -0
  209. package/front_end/ui/settings/LayerViewerSettings.ts +26 -0
  210. package/front_end/ui/settings/NetworkSettings.ts +26 -0
  211. package/front_end/ui/settings/TimelineSettings.ts +103 -0
  212. package/front_end/ui/settings/WhatsNewSettings.ts +11 -0
  213. package/front_end/ui/settings/settings.ts +12 -0
  214. package/front_end/ui/visual_logging/KnownContextValues.ts +8 -0
  215. package/inspector_overlay/highlight_anchor.ts +1 -1
  216. package/package.json +1 -1
  217. package/front_end/models/ai_assistance/contexts/AccessibilityContext.snapshot.txt +0 -26
package/AUTHORS CHANGED
@@ -53,12 +53,14 @@ Han Xu <suyanhanx@gmail.com>
53
53
  Helmut Januschka <helmut@januschka.com>
54
54
  Henry Lim <henry@limhenry.xyz>
55
55
  Hojeong Park <parkhj062@gmail.com>
56
+ Ivan Akulov <gxoptg@gmail.com>
56
57
  Jacky Hu <flameddd@gmail.com>
57
58
  Jake Mulhern <mulherje@gmail.com>
58
59
  Jan Keitel <jan.keitel@gmail.com>
59
60
  Jeffrey Chen <jeffreyca16@gmail.com>
60
61
  Jerome Vouillon <jerome.vouillon@gmail.com>
61
62
  Jesper van den Ende <jespertheend@gmail.com>
63
+ Jihyeon Lee <wlgus7464@gmail.com>
62
64
  Jithil p Ponnan <jithil.p@gmail.com>
63
65
  Joseph P <thepigrammer@gmail.com>
64
66
  Juba Borgohain <chromiumjuba@gmail.com>
@@ -99,6 +101,7 @@ Ryuhei Shima <shimaryuhei@gmail.com>
99
101
  Samuel Maddock <samuelmaddock@electronjs.org>
100
102
  Satvic Dhawan <satvicdhawan14@gmail.com>
101
103
  Sebastian Markbåge <sebastian@calyptus.eu>
104
+ Sebeen Kwon <a856412@gmail.com>
102
105
  Semih Dogan <semih702do@gmail.com>
103
106
  Serg Kryvonos <sergeikrivonos@gmail.com>
104
107
  Sergio Avalos <sergio.avalos@gmail.com>
@@ -2458,6 +2458,12 @@ export const PageHighlight: Record<string, Legacy> = {
2458
2458
  GapBackground: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, .3]),
2459
2459
  GapHatch: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, .8]),
2460
2460
  GridAreaBorder: Legacy.fromRGBA([26, 115, 232, 1]),
2461
+ AnchorIMCB: Legacy.fromRGBA([127, 32, 210, 1]),
2462
+ AnchorIMCBBackground: Legacy.fromRGBA([127, 32, 210, 0.15]),
2463
+ AnchorInsetsBackground: Legacy.fromRGBA([246, 178, 107, 0.25]),
2464
+ AnchorInsetsHatch: Legacy.fromRGBA([246, 178, 107, 0.8]),
2465
+ AnchorTarget: Legacy.fromRGBA([26, 115, 232, 1]),
2466
+ AnchorTargetBackground: Legacy.fromRGBA([26, 115, 232, 0.15]),
2461
2467
  };
2462
2468
 
2463
2469
  export const SourceOrderHighlight: Record<string, Legacy> = {
@@ -57,26 +57,34 @@ const WEB_SAFE_SCHEMES = new Set([
57
57
  'data:',
58
58
  ]);
59
59
 
60
- /**
61
- * Returns true if the URL uses an unprivileged web-safe scheme (or is a `blob:` URL wrapping one).
62
- */
63
- export function hasWebSafeScheme(url: Platform.DevToolsPath.UrlString|URL|string): boolean {
60
+ function parseUnwrappedURL(url: Platform.DevToolsPath.UrlString|URL|string): URL|null {
64
61
  try {
65
- const parsed = new URL(url);
66
- if (parsed.protocol === 'blob:') {
67
- return hasWebSafeScheme(parsed.pathname);
62
+ let parsed = new URL(url);
63
+ // Iteratively unwrap nested `blob:` and `filesystem:` URLs (e.g. `blob:filesystem:https://...`)
64
+ // to inspect the underlying origin's protocol.
65
+ while (parsed.protocol === 'blob:' || parsed.protocol === 'filesystem:') {
66
+ parsed = new URL(parsed.href.slice(parsed.protocol.length));
68
67
  }
69
- return WEB_SAFE_SCHEMES.has(parsed.protocol);
68
+ return parsed;
70
69
  } catch {
71
- return false;
70
+ return null;
72
71
  }
73
72
  }
74
73
 
74
+ /**
75
+ * Returns true if the URL uses an unprivileged web-safe scheme (or is a `blob:`/`filesystem:` URL wrapping one).
76
+ */
77
+ export function hasWebSafeScheme(url: Platform.DevToolsPath.UrlString|URL|string): boolean {
78
+ const parsed = parseUnwrappedURL(url);
79
+ return parsed !== null && WEB_SAFE_SCHEMES.has(parsed.protocol);
80
+ }
81
+
75
82
  /**
76
83
  * Privileged browser and local schemes that must not be opened via external/new-tab links by default.
77
84
  */
78
85
  const PRIVILEGED_SCHEMES = new Set([
79
86
  'chrome:',
87
+ 'chrome-error:',
80
88
  'chrome-extension:',
81
89
  'chrome-search:',
82
90
  'chrome-untrusted:',
@@ -86,18 +94,11 @@ const PRIVILEGED_SCHEMES = new Set([
86
94
  ]);
87
95
 
88
96
  /**
89
- * Returns true if the URL uses a privileged scheme (or is a `blob:` URL wrapping one).
97
+ * Returns true if the URL uses a privileged scheme (or is a `blob:`/`filesystem:` URL wrapping one).
90
98
  */
91
99
  export function isPrivilegedScheme(url: Platform.DevToolsPath.UrlString|URL|string): boolean {
92
- try {
93
- const parsed = new URL(url);
94
- if (parsed.protocol === 'blob:') {
95
- return isPrivilegedScheme(parsed.pathname);
96
- }
97
- return PRIVILEGED_SCHEMES.has(parsed.protocol);
98
- } catch {
99
- return false;
100
- }
100
+ const parsed = parseUnwrappedURL(url);
101
+ return parsed !== null && PRIVILEGED_SCHEMES.has(parsed.protocol);
101
102
  }
102
103
 
103
104
  /**
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Platform from '../platform/platform.js';
6
- import * as Root from '../root/root.js';
7
6
 
8
7
  /* eslint @devtools/enforce-version-controller-methods: "error" */
9
8
 
@@ -834,67 +833,15 @@ export class VersionController {
834
833
  }
835
834
 
836
835
  updateVersionFrom42To43(): void {
837
- const timelineShowAllEventsExperimentEnabled =
838
- Root.Runtime.experiments.getValueFromStorage('timeline-show-all-events' as Root.ExperimentNames.ExperimentName);
839
- if (timelineShowAllEventsExperimentEnabled !== undefined) {
840
- if (this.#settings.syncedStorage.has('timeline-show-all-events')) {
841
- return; // Already migrated
842
- }
843
- try {
844
- const timelineShowAllEventsSetting = this.#settings.moduleSetting('timeline-show-all-events');
845
- timelineShowAllEventsSetting.set(timelineShowAllEventsExperimentEnabled);
846
- } catch {
847
- // If the setting is not registered yet (e.g. in tests), skip.
848
- }
849
- }
850
836
  }
851
837
 
852
838
  updateVersionFrom43To44(): void {
853
- const apcaExperimentEnabled =
854
- Root.Runtime.experiments.getValueFromStorage('apca' as Root.ExperimentNames.ExperimentName);
855
- if (apcaExperimentEnabled !== undefined) {
856
- if (this.#settings.syncedStorage.has('apca')) {
857
- return; // Already migrated
858
- }
859
- try {
860
- const apcaSetting = this.#settings.moduleSetting('apca');
861
- apcaSetting.set(apcaExperimentEnabled);
862
- } catch {
863
- // If the setting is not registered yet (e.g. in tests), skip.
864
- }
865
- }
866
839
  }
867
840
 
868
841
  updateVersionFrom44To45(): void {
869
- const timelineDebugModeExperimentEnabled =
870
- Root.Runtime.experiments.getValueFromStorage('timeline-debug-mode' as Root.ExperimentNames.ExperimentName);
871
- if (timelineDebugModeExperimentEnabled !== undefined) {
872
- if (this.#settings.syncedStorage.has('timeline-debug-mode')) {
873
- return; // Already migrated
874
- }
875
- try {
876
- const timelineDebugModeSetting = this.#settings.moduleSetting('timeline-debug-mode');
877
- timelineDebugModeSetting.set(timelineDebugModeExperimentEnabled);
878
- } catch {
879
- // If the setting is not registered yet (e.g. in tests), skip.
880
- }
881
- }
882
842
  }
883
843
 
884
844
  updateVersionFrom45To46(): void {
885
- const timelineInvalidationTrackingExperimentEnabled = Root.Runtime.experiments.getValueFromStorage(
886
- 'timeline-invalidation-tracking' as Root.ExperimentNames.ExperimentName);
887
- if (timelineInvalidationTrackingExperimentEnabled !== undefined) {
888
- if (this.#settings.syncedStorage.has('timeline-invalidation-tracking')) {
889
- return; // Already migrated
890
- }
891
- try {
892
- const timelineInvalidationTrackingSetting = this.#settings.moduleSetting('timeline-invalidation-tracking');
893
- timelineInvalidationTrackingSetting.set(timelineInvalidationTrackingExperimentEnabled);
894
- } catch {
895
- // If the setting is not registered yet (e.g. in tests), skip.
896
- }
897
- }
898
845
  }
899
846
 
900
847
  updateVersionFrom46To47(): void {
@@ -175,7 +175,6 @@ export interface Option {
175
175
  export class ExperimentsSupport {
176
176
  #experiments = new Map<ExperimentName, Experiment>();
177
177
  readonly #enabledForTests = new Set<ExperimentName>();
178
- readonly #storage = new ExperimentStorage();
179
178
 
180
179
  allConfigurableExperiments(): Experiment[] {
181
180
  return [...this.#experiments.values()];
@@ -205,10 +204,6 @@ export class ExperimentsSupport {
205
204
  throw new Error(`Unknown experiment '${experimentName}'`);
206
205
  }
207
206
 
208
- getValueFromStorage(experimentName: ExperimentName): boolean|undefined {
209
- return this.#storage.get(experimentName);
210
- }
211
-
212
207
  setEnabled(experimentName: ExperimentName, enabled: boolean): void {
213
208
  if (this.#isExperiment(experimentName)) {
214
209
  this.#experiments.get(experimentName)?.setEnabled(enabled);
@@ -240,47 +235,11 @@ export class ExperimentsSupport {
240
235
  this.#enabledForTests.clear();
241
236
  }
242
237
 
243
- // TODO(crbug.com/464173054) remove after M156
244
- removeAllExperimentsFromLocalStorage(): void {
245
- this.#storage.removeAllExperimentsFromLocalStorage();
246
- }
247
-
248
238
  #isExperiment(experimentName: ExperimentName): boolean {
249
239
  return this.#experiments.has(experimentName);
250
240
  }
251
241
  }
252
242
 
253
- // TODO(crbug.com/464173054) remove after M156
254
- /** Manages the 'experiments' dictionary in globalThis.localStorage */
255
- class ExperimentStorage {
256
- readonly #experiments: Record<string, boolean|undefined> = {};
257
-
258
- constructor() {
259
- try {
260
- const storedExperiments = Platform.HostRuntime.HOST_RUNTIME.getLocalStorage()?.getItem('experiments');
261
- if (storedExperiments) {
262
- this.#experiments = JSON.parse(storedExperiments);
263
- }
264
- } catch (err) {
265
- console.error('Failed to parse localStorage[\'experiments\']: ' + err.message);
266
- }
267
- }
268
-
269
- /**
270
- * Experiments are stored with a tri-state:
271
- * - true: Explicitly enabled.
272
- * - false: Explicitly disabled.
273
- * - undefined: Disabled.
274
- */
275
- get(experimentName: ExperimentName): boolean|undefined {
276
- return this.#experiments[experimentName];
277
- }
278
-
279
- removeAllExperimentsFromLocalStorage(): void {
280
- Platform.HostRuntime.HOST_RUNTIME.getLocalStorage()?.removeItem('experiments');
281
- }
282
- }
283
-
284
243
  export class Experiment {
285
244
  name: ExperimentName;
286
245
  title: string;
@@ -44,6 +44,60 @@ export interface LayoutProperties {
44
44
  isContents?: boolean;
45
45
  containerType?: string;
46
46
  hasScroll: boolean;
47
+ isAnchorPositioned?: boolean;
48
+ }
49
+
50
+ function isAnchorPositioned(computedStyle: Map<string, string>, matchedStyles?: CSSMatchedStyles|null): boolean {
51
+ const position = computedStyle.get('position');
52
+ if (position !== 'absolute' && position !== 'fixed') {
53
+ return false;
54
+ }
55
+ const positionAnchor = computedStyle.get('position-anchor');
56
+ if (positionAnchor && positionAnchor !== 'none') {
57
+ return true;
58
+ }
59
+ const positionArea = computedStyle.get('position-area');
60
+ if (positionArea && positionArea !== 'none') {
61
+ return true;
62
+ }
63
+ const anchorProperties = [
64
+ 'top',
65
+ 'right',
66
+ 'bottom',
67
+ 'left',
68
+ 'inset',
69
+ 'inset-block',
70
+ 'inset-inline',
71
+ 'inset-block-start',
72
+ 'inset-block-end',
73
+ 'inset-inline-start',
74
+ 'inset-inline-end',
75
+ 'width',
76
+ 'height',
77
+ 'min-width',
78
+ 'min-height',
79
+ 'max-width',
80
+ 'max-height',
81
+ ];
82
+ if (anchorProperties.some(prop => {
83
+ const val = computedStyle.get(prop);
84
+ return Boolean(val && (val.includes('anchor(') || val.includes('anchor-size(')));
85
+ })) {
86
+ return true;
87
+ }
88
+ if (matchedStyles) {
89
+ for (const style of matchedStyles.nodeStyles()) {
90
+ for (const property of style.allProperties()) {
91
+ if (!property.activeInStyle() || !matchedStyles.propertyState(property)) {
92
+ continue;
93
+ }
94
+ if (property.value.includes('anchor(') || property.value.includes('anchor-size(')) {
95
+ return true;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ return false;
47
101
  }
48
102
 
49
103
  export class CSSModel extends SDKModel<EventTypes> {
@@ -408,6 +462,8 @@ export class CSSModel extends SDKModel<EventTypes> {
408
462
  const isContainer = Boolean(containerType) && containerType !== '' && containerType !== 'normal';
409
463
  const hasScroll = Boolean(styles.get('scroll-snap-type')) && styles.get('scroll-snap-type') !== 'none';
410
464
 
465
+ const isAnchored = isAnchorPositioned(styles);
466
+
411
467
  return {
412
468
  isFlex,
413
469
  isGrid,
@@ -416,6 +472,7 @@ export class CSSModel extends SDKModel<EventTypes> {
416
472
  isContents,
417
473
  containerType: isContainer ? containerType : undefined,
418
474
  hasScroll,
475
+ isAnchorPositioned: isAnchored,
419
476
  };
420
477
  }
421
478
 
@@ -87,9 +87,8 @@ export class SyntaxTree {
87
87
  readonly tree: CodeMirror.SyntaxNode;
88
88
  readonly trailingNodes: CodeMirror.SyntaxNode[];
89
89
  readonly propertyName: string|undefined;
90
- constructor(
91
- propertyValue: string, rule: string, tree: CodeMirror.SyntaxNode, propertyName?: string,
92
- trailingNodes: CodeMirror.SyntaxNode[] = []) {
90
+ constructor(propertyValue: string, rule: string, tree: CodeMirror.SyntaxNode, propertyName?: string,
91
+ trailingNodes: CodeMirror.SyntaxNode[] = []) {
93
92
  this.propertyName = propertyName;
94
93
  this.propertyValue = propertyValue;
95
94
  this.rule = rule;
@@ -135,8 +134,8 @@ export abstract class TreeWalker {
135
134
  }
136
135
  return instance;
137
136
  }
138
- static walk<T extends TreeWalker, ArgTs extends unknown[]>(
139
- this: {new(ast: SyntaxTree, ...args: ArgTs): T}, propertyValue: SyntaxTree, ...args: ArgTs): T {
137
+ static walk<T extends TreeWalker, ArgTs extends unknown[]>(this: {new(ast: SyntaxTree, ...args: ArgTs): T},
138
+ propertyValue: SyntaxTree, ...args: ArgTs): T {
140
139
  const instance = new this(propertyValue, ...args);
141
140
  if (propertyValue.tree.name === 'Declaration') {
142
141
  instance.iterateDeclaration(propertyValue.tree);
@@ -279,9 +278,8 @@ export class BottomUpTreeMatching extends TreeWalker {
279
278
  return this.getComputedTextRange(from ?? this.ast.tree, to ?? this.ast.tree, substitutionHook);
280
279
  }
281
280
 
282
- getComputedTextRange(
283
- from: CodeMirror.SyntaxNode|undefined, to: CodeMirror.SyntaxNode|undefined,
284
- substitutionHook?: (match: Match) => string | null): string {
281
+ getComputedTextRange(from: CodeMirror.SyntaxNode|undefined, to: CodeMirror.SyntaxNode|undefined,
282
+ substitutionHook?: (match: Match) => string | null): string {
285
283
  if (!from || !to) {
286
284
  return '';
287
285
  }
@@ -481,10 +479,9 @@ export class ComputedText {
481
479
 
482
480
  countTopLevelValues(begin: number, end: number): number {
483
481
  const pieces = Array.from(this.#getPieces(begin, end));
484
- const counts = pieces.map(
485
- chunk =>
486
- (chunk instanceof ComputedTextChunk ? chunk.topLevelValueCount :
487
- this.#countTopLevelValuesInStringPiece(chunk)));
482
+ const counts =
483
+ pieces.map(chunk => (chunk instanceof ComputedTextChunk ? chunk.topLevelValueCount :
484
+ this.#countTopLevelValuesInStringPiece(chunk)));
488
485
  const count = counts.reduce((sum, v) => sum + v, 0);
489
486
  return count;
490
487
  }
@@ -496,11 +493,7 @@ export class ComputedText {
496
493
  * sequences that make up the pieces of text may contain non-text nodes/trees. Any such element in between the texts is
497
494
  * ignored for the spacing requirement.
498
495
  **/
499
- export function requiresSpace(a: string, b: string): boolean;
500
- export function requiresSpace(a: Array<{textContent?: string | null}>,
501
- b: Array<{textContent?: string | null}>): boolean;
502
- export function requiresSpace(a: Array<{textContent?: string | null}>|string|undefined,
503
- b: Array<{textContent?: string | null}>|string|undefined): boolean {
496
+ export function requiresSpace(a: string, b: string): boolean {
504
497
  const tail = Array.isArray(a) ? a.findLast(node => node.textContent)?.textContent : a;
505
498
  const head = Array.isArray(b) ? b.find(node => node.textContent)?.textContent : b;
506
499
  const trailingChar = tail ? tail[tail.length - 1] : '';
@@ -1100,8 +1100,9 @@ export class DOMNode extends Common.ObjectWrapper.ObjectWrapper<DOMNodeEventType
1100
1100
  */
1101
1101
  async toggleHideElement(): Promise<void> {
1102
1102
  let pseudoElementName = this.pseudoType() ? this.nodeName() : null;
1103
- if (pseudoElementName && this.pseudoIdentifier()) {
1104
- pseudoElementName += `(${this.pseudoIdentifier()})`;
1103
+ const pseudoIdentifier = this.pseudoIdentifier();
1104
+ if (pseudoElementName && pseudoIdentifier) {
1105
+ pseudoElementName += `(${cssEscape(pseudoIdentifier)})`;
1105
1106
  }
1106
1107
 
1107
1108
  let effectiveNode: DOMNode|null = this;
@@ -1358,8 +1359,9 @@ export class DOMNode extends Common.ObjectWrapper.ObjectWrapper<DOMNodeEventType
1358
1359
  const classList = classes.trim().split(/\s+/g);
1359
1360
  return (lowerCaseName === 'div' ? '' : lowerCaseName) + '.' + classList.map(cls => cssEscape(cls)).join('.');
1360
1361
  }
1361
- if (this.pseudoIdentifier()) {
1362
- return `${lowerCaseName}(${this.pseudoIdentifier()})`;
1362
+ const pseudoIdentifier = this.pseudoIdentifier();
1363
+ if (pseudoIdentifier) {
1364
+ return `${lowerCaseName}(${cssEscape(pseudoIdentifier)})`;
1363
1365
  }
1364
1366
  return lowerCaseName;
1365
1367
  }
@@ -134,6 +134,31 @@ export const enum StepMode {
134
134
  STEP_OVER = 'StepOver',
135
135
  }
136
136
 
137
+ /** A CDP step command. `ranges` is passed as `skipList` to stepInto/stepOver, and ignored for stepOut. */
138
+ export interface AutoStep {
139
+ readonly command: StepMode;
140
+ readonly ranges: readonly LocationRange[];
141
+ }
142
+
143
+ /**
144
+ * The step the user requested. It lives until a pause is presented to the user, or the user resumes or pauses, and
145
+ * allows the before-paused callback to continue the step automatically.
146
+ */
147
+ export interface StepContext {
148
+ readonly mode: StepMode;
149
+ /** The call frames of the pause in which the user requested the step. */
150
+ readonly callFrames: readonly CallFrame[];
151
+ }
152
+
153
+ /** Computes the CDP step command for a user-requested step. */
154
+ export type ComputeAutoStepCallback = (mode: StepMode, callFrames: readonly CallFrame[]) => Promise<AutoStep>;
155
+
156
+ /**
157
+ * Invoked for every pause before it's presented. Returns null to present the pause, or the step to issue instead.
158
+ */
159
+ export type BeforePausedCallback = (details: DebuggerPausedDetails, context: StepContext|null) =>
160
+ Promise<AutoStep|null>;
161
+
137
162
  export const WASM_SYMBOLS_PRIORITY: Protocol.Debugger.DebugSymbolsType[] = [
138
163
  Protocol.Debugger.DebugSymbolsType.ExternalDWARF,
139
164
  Protocol.Debugger.DebugSymbolsType.EmbeddedDWARF,
@@ -166,20 +191,15 @@ export class DebuggerModel extends SDKModel<EventTypes> {
166
191
  readonly #jsSourceMapsEnabledSetting: Common.Settings.Setting<boolean>;
167
192
  readonly #skipAllPausesSetting: Common.Settings.Setting<boolean>;
168
193
  #skipAllPausesTimeout?: ReturnType<typeof setTimeout>;
169
- #beforePausedCallback: ((arg0: DebuggerPausedDetails, stepOver: Location|null) => Promise<boolean>)|null = null;
170
- #computeAutoStepRangesCallback: ((arg0: StepMode, arg1: CallFrame) => Promise<Array<{
171
- start: Location,
172
- end: Location,
173
- }>>)|null = null;
194
+ #beforePausedCallback: BeforePausedCallback|null = null;
195
+ #computeAutoStepCallback: ComputeAutoStepCallback|null = null;
174
196
  evaluateOnCallFrameCallback:
175
197
  ((arg0: CallFrame, arg1: EvaluationOptions) => Promise<EvaluationResult|null>)|null = null;
176
198
  #synchronizeBreakpointsCallback: ((script: Script) => Promise<void>)|null = null;
177
199
  // We need to be able to register listeners for individual breakpoints. As such, we dispatch
178
200
  // on breakpoint ids, which are not statically known. The event #payload will always be a `Location`.
179
201
  readonly #breakpointResolvedEventTarget = new Common.ObjectWrapper.ObjectWrapper<Record<string, Location>>();
180
- // When stepping over with autostepping enabled, the context denotes the function to which autostepping is restricted
181
- // to by way of its functionLocation (as per Debugger.CallFrame).
182
- #autoSteppingContext: Location|null = null;
202
+ #stepContext: StepContext|null = null;
183
203
  #isPausing = false;
184
204
 
185
205
  constructor(target: Target) {
@@ -429,58 +449,63 @@ export class DebuggerModel extends SDKModel<EventTypes> {
429
449
  void this.agent.invoke_setBreakpointsActive({active: this.#breakpointsActiveSetting.get()});
430
450
  }
431
451
 
432
- setComputeAutoStepRangesCallback(callback: ((arg0: StepMode, arg1: CallFrame) => Promise<LocationRange[]>)|null):
433
- void {
434
- this.#computeAutoStepRangesCallback = callback;
435
- }
436
-
437
- private async computeAutoStepSkipList(mode: StepMode): Promise<Protocol.Debugger.LocationRange[]> {
438
- let ranges: LocationRange[] = [];
439
- if (this.#computeAutoStepRangesCallback && this.#debuggerPausedDetails &&
440
- this.#debuggerPausedDetails.callFrames.length > 0) {
441
- const [callFrame] = this.#debuggerPausedDetails.callFrames;
442
- ranges = await this.#computeAutoStepRangesCallback.call(null, mode, callFrame);
443
- }
444
- const skipList = ranges.map(({start, end}) => ({
445
- scriptId: start.scriptId,
446
- start: {lineNumber: start.lineNumber, columnNumber: start.columnNumber},
447
- end: {lineNumber: end.lineNumber, columnNumber: end.columnNumber},
448
- }));
449
- return sortAndMergeRanges(skipList);
452
+ setComputeAutoStepCallback(callback: ComputeAutoStepCallback|null): void {
453
+ this.#computeAutoStepCallback = callback;
450
454
  }
451
455
 
452
456
  async stepInto(): Promise<void> {
453
- const skipList = await this.computeAutoStepSkipList(StepMode.STEP_INTO);
454
- void this.agent.invoke_stepInto({breakOnAsyncCall: false, skipList});
457
+ await this.#userStep(StepMode.STEP_INTO);
455
458
  }
456
459
 
457
460
  async stepOver(): Promise<void> {
458
- this.#autoSteppingContext = this.#debuggerPausedDetails?.callFrames[0]?.functionLocation() ?? null;
459
- const skipList = await this.computeAutoStepSkipList(StepMode.STEP_OVER);
460
- void this.agent.invoke_stepOver({skipList});
461
+ await this.#userStep(StepMode.STEP_OVER);
461
462
  }
462
463
 
463
464
  async stepOut(): Promise<void> {
464
- const skipList = await this.computeAutoStepSkipList(StepMode.STEP_OUT);
465
- if (skipList.length !== 0) {
466
- void this.agent.invoke_stepOver({skipList});
467
- } else {
468
- void this.agent.invoke_stepOut();
469
- }
465
+ await this.#userStep(StepMode.STEP_OUT);
470
466
  }
471
467
 
472
468
  scheduleStepIntoAsync(): void {
473
- void this.computeAutoStepSkipList(StepMode.STEP_INTO).then(skipList => {
474
- void this.agent.invoke_stepInto({breakOnAsyncCall: true, skipList});
475
- });
469
+ void this.#userStep(StepMode.STEP_INTO, /* breakOnAsyncCall */ true);
470
+ }
471
+
472
+ async #userStep(mode: StepMode, breakOnAsyncCall = false): Promise<void> {
473
+ const callFrames = this.#debuggerPausedDetails?.callFrames ?? [];
474
+ this.#stepContext = {mode, callFrames};
475
+ const step = this.#computeAutoStepCallback && callFrames.length > 0 ?
476
+ await this.#computeAutoStepCallback(mode, callFrames) :
477
+ {command: mode, ranges: []};
478
+ this.#issueStep(step, breakOnAsyncCall);
479
+ }
480
+
481
+ #issueStep({command, ranges}: AutoStep, breakOnAsyncCall = false): void {
482
+ const skipList =
483
+ sortAndMergeRanges(ranges.map(({start, end}) => ({
484
+ scriptId: start.scriptId,
485
+ start: {lineNumber: start.lineNumber, columnNumber: start.columnNumber},
486
+ end: {lineNumber: end.lineNumber, columnNumber: end.columnNumber},
487
+ })));
488
+ switch (command) {
489
+ case StepMode.STEP_INTO:
490
+ void this.agent.invoke_stepInto({breakOnAsyncCall, skipList});
491
+ break;
492
+ case StepMode.STEP_OVER:
493
+ void this.agent.invoke_stepOver({skipList});
494
+ break;
495
+ case StepMode.STEP_OUT:
496
+ void this.agent.invoke_stepOut();
497
+ break;
498
+ }
476
499
  }
477
500
 
478
501
  resume(): void {
502
+ this.#stepContext = null;
479
503
  void this.agent.invoke_resume({terminateOnResume: false});
480
504
  this.#isPausing = false;
481
505
  }
482
506
 
483
507
  pause(): void {
508
+ this.#stepContext = null;
484
509
  this.#isPausing = true;
485
510
  this.skipAllPauses(false);
486
511
  void this.agent.invoke_pause();
@@ -569,7 +594,7 @@ export class DebuggerModel extends SDKModel<EventTypes> {
569
594
  this.#scripts.clear();
570
595
  this.#scriptsBySourceURL.clear();
571
596
  this.#discardableScripts = [];
572
- this.#autoSteppingContext = null;
597
+ this.#stepContext = null;
573
598
  }
574
599
 
575
600
  scripts(): Script[] {
@@ -611,20 +636,22 @@ export class DebuggerModel extends SDKModel<EventTypes> {
611
636
  return this.#debuggerPausedDetails;
612
637
  }
613
638
 
614
- private async setDebuggerPausedDetails(debuggerPausedDetails: DebuggerPausedDetails): Promise<boolean> {
639
+ /**
640
+ * @returns null if the pause was presented, or the step to issue instead, as decided by the before-paused callback.
641
+ */
642
+ private async setDebuggerPausedDetails(debuggerPausedDetails: DebuggerPausedDetails): Promise<AutoStep|null> {
615
643
  this.#isPausing = false;
616
644
  this.#debuggerPausedDetails = debuggerPausedDetails;
617
645
  if (this.#beforePausedCallback) {
618
- if (!await this.#beforePausedCallback.call(null, debuggerPausedDetails, this.#autoSteppingContext)) {
619
- return false;
646
+ const autoStep = await this.#beforePausedCallback(debuggerPausedDetails, this.#stepContext);
647
+ if (autoStep) {
648
+ return autoStep;
620
649
  }
621
650
  }
622
- // If we resolved a location in auto-stepping callback, reset the
623
- // auto-step-over context.
624
- this.#autoSteppingContext = null;
651
+ this.#stepContext = null;
625
652
  this.dispatchEventToListeners(Events.DebuggerPaused, this);
626
653
  this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
627
- return true;
654
+ return null;
628
655
  }
629
656
 
630
657
  private resetDebuggerPausedDetails(): void {
@@ -633,8 +660,7 @@ export class DebuggerModel extends SDKModel<EventTypes> {
633
660
  this.setSelectedCallFrame(null);
634
661
  }
635
662
 
636
- setBeforePausedCallback(
637
- callback: ((arg0: DebuggerPausedDetails, autoSteppingContext: Location|null) => Promise<boolean>)|null): void {
663
+ setBeforePausedCallback(callback: BeforePausedCallback|null): void {
638
664
  this.#beforePausedCallback = callback;
639
665
  }
640
666
 
@@ -676,12 +702,9 @@ export class DebuggerModel extends SDKModel<EventTypes> {
676
702
  }
677
703
  }
678
704
 
679
- if (!await this.setDebuggerPausedDetails(pausedDetails)) {
680
- if (this.#autoSteppingContext) {
681
- void this.stepOver();
682
- } else {
683
- void this.stepInto();
684
- }
705
+ const autoStep = await this.setDebuggerPausedDetails(pausedDetails);
706
+ if (autoStep) {
707
+ this.#issueStep(autoStep);
685
708
  }
686
709
  }
687
710
 
@@ -1480,6 +1503,17 @@ export class Scope implements ScopeChainEntry {
1480
1503
  return undefined;
1481
1504
  }
1482
1505
 
1506
+ /**
1507
+ * Present iff V8 has no variable values to show for this scope, either because the scope
1508
+ * declares no variables or because all of them are unavailable (e.g. optimized out).
1509
+ *
1510
+ * Such scopes are retained in {@link CallFrame.scopeChain} so they can be addressed via
1511
+ * `scopeNumber` in `Debugger.evaluateOnCallFrame` and matched against source map scopes.
1512
+ */
1513
+ emptyReason(): Protocol.Debugger.ScopeEmptyReason|undefined {
1514
+ return this.#payload.emptyReason;
1515
+ }
1516
+
1483
1517
  extraProperties(): RemoteObjectProperty[] {
1484
1518
  if (this !== this.#callFrame.localScope() || this.#callFrame.script.isWasm()) {
1485
1519
  return [];