chrome-devtools-frontend 1.0.1545096 → 1.0.1547147

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 (124) hide show
  1. package/docs/styleguide/ux/styles.md +1 -1
  2. package/eslint.config.mjs +1 -1
  3. package/front_end/Images/src/arrow-down.svg +8 -1
  4. package/front_end/Images/src/arrow-up.svg +8 -1
  5. package/front_end/core/host/AidaClient.ts +1 -1
  6. package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -1
  7. package/front_end/core/host/UserMetrics.ts +0 -5
  8. package/front_end/core/platform/HostRuntime.ts +18 -0
  9. package/front_end/core/platform/KeyboardUtilities.ts +2 -2
  10. package/front_end/core/platform/StringUtilities.ts +1 -1
  11. package/front_end/core/platform/api/HostRuntime.ts +20 -0
  12. package/front_end/core/platform/api/api.ts +7 -0
  13. package/front_end/core/platform/browser/HostRuntime.ts +14 -0
  14. package/front_end/core/platform/browser/browser.ts +7 -0
  15. package/front_end/core/platform/node/HostRuntime.ts +13 -0
  16. package/front_end/core/platform/node/node.ts +7 -0
  17. package/front_end/core/platform/platform.ts +2 -2
  18. package/front_end/core/sdk/SourceMapScopesInfo.ts +141 -23
  19. package/front_end/core/sdk/Target.ts +5 -14
  20. package/front_end/core/sdk/TargetManager.ts +26 -4
  21. package/front_end/core/sdk/sdk-meta.ts +62 -0
  22. package/front_end/devtools_compatibility.js +0 -1
  23. package/front_end/entrypoints/main/MainImpl.ts +2 -2
  24. package/front_end/foundation/Universe.ts +2 -2
  25. package/front_end/generated/Deprecation.ts +7 -0
  26. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  27. package/front_end/generated/SupportedCSSProperties.js +4 -2
  28. package/front_end/generated/protocol.ts +3 -2
  29. package/front_end/models/ai_assistance/AiConversation.ts +188 -0
  30. package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -172
  31. package/front_end/models/ai_assistance/ConversationHandler.ts +5 -5
  32. package/front_end/models/ai_assistance/agents/AiAgent.ts +1 -3
  33. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +6 -2
  34. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -1
  35. package/front_end/models/ai_assistance/agents/StylingAgent.ts +3 -9
  36. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  37. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +313 -313
  38. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +8 -6
  39. package/front_end/models/ai_assistance/performance/AICallTree.snapshot.txt +33 -33
  40. package/front_end/models/ai_assistance/performance/AICallTree.ts +9 -3
  41. package/front_end/models/bindings/CSSWorkspaceBinding.ts +5 -3
  42. package/front_end/models/bindings/SASSSourceMapping.ts +6 -4
  43. package/front_end/models/cpu_profile/CPUProfileDataModel.ts +10 -7
  44. package/front_end/models/crux-manager/CrUXManager.ts +7 -4
  45. package/front_end/models/issues_manager/GenericIssue.ts +12 -9
  46. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
  47. package/front_end/models/trace/handlers/SamplesHandler.ts +3 -0
  48. package/front_end/models/trace/helpers/Trace.ts +13 -0
  49. package/front_end/models/trace/types/TraceEvents.ts +2 -1
  50. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +29 -0
  51. package/front_end/models/workspace/IgnoreListManager.ts +1 -2
  52. package/front_end/models/workspace/UISourceCode.ts +50 -0
  53. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +9 -9
  54. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +8 -0
  55. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -2
  56. package/front_end/panels/animation/AnimationTimeline.ts +0 -8
  57. package/front_end/panels/application/FrameDetailsView.ts +8 -8
  58. package/front_end/panels/application/components/StackTrace.ts +84 -85
  59. package/front_end/panels/common/AiCodeGenerationTeaser.ts +80 -0
  60. package/front_end/panels/common/common.ts +2 -1
  61. package/front_end/panels/console/ConsolePrompt.ts +3 -1
  62. package/front_end/panels/console/ConsoleViewport.ts +1 -2
  63. package/front_end/panels/elements/ElementIssueUtils.ts +2 -2
  64. package/front_end/panels/elements/StylePropertyTreeElement.ts +23 -19
  65. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  66. package/front_end/panels/elements/cssValueTraceView.css +1 -1
  67. package/front_end/panels/elements/elements-meta.ts +1 -0
  68. package/front_end/panels/explain/components/ConsoleInsight.ts +44 -57
  69. package/front_end/panels/explain/components/consoleInsight.css +46 -1
  70. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +1 -2
  71. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +19 -0
  72. package/front_end/panels/network/RequestConditionsDrawer.ts +54 -24
  73. package/front_end/panels/network/networkLogView.css +11 -0
  74. package/front_end/panels/network/networkTimingTable.css +8 -6
  75. package/front_end/panels/network/requestConditionsDrawer.css +10 -1
  76. package/front_end/panels/profiler/ProfilesPanel.ts +1 -2
  77. package/front_end/panels/settings/KeybindsSettingsTab.ts +20 -21
  78. package/front_end/panels/sources/CoveragePlugin.ts +5 -5
  79. package/front_end/panels/sources/Plugin.ts +1 -1
  80. package/front_end/panels/sources/ProfilePlugin.ts +22 -14
  81. package/front_end/panels/sources/UISourceCodeFrame.ts +2 -1
  82. package/front_end/panels/sources/sources-meta.ts +0 -62
  83. package/front_end/panels/timeline/README.md +1 -9
  84. package/front_end/panels/timeline/ThreadAppender.ts +0 -7
  85. package/front_end/panels/timeline/TimelinePanel.ts +1 -1
  86. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -0
  87. package/front_end/panels/timeline/components/ExportTraceOptions.ts +15 -1
  88. package/front_end/panels/timeline/components/LiveMetricsView.ts +37 -1
  89. package/front_end/panels/timeline/components/exportTraceOptions.css +11 -2
  90. package/front_end/third_party/chromium/README.chromium +1 -1
  91. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +1 -0
  92. package/front_end/ui/legacy/ARIAUtils.ts +2 -2
  93. package/front_end/ui/legacy/ActionRegistration.ts +11 -0
  94. package/front_end/ui/legacy/SoftDropDown.ts +2 -2
  95. package/front_end/ui/legacy/TextPrompt.ts +3 -2
  96. package/front_end/ui/legacy/Treeoutline.ts +2 -1
  97. package/front_end/ui/legacy/UIUtils.ts +11 -10
  98. package/front_end/ui/legacy/Widget.ts +3 -2
  99. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +2 -2
  100. package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +62 -39
  101. package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +1 -1
  102. package/front_end/ui/legacy/components/perf_ui/TimelineGrid.ts +2 -2
  103. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -7
  104. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +1 -2
  105. package/front_end/ui/legacy/inspectorCommon.css +2 -2
  106. package/front_end/ui/legacy/legacy.ts +2 -0
  107. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  108. package/package.json +1 -1
  109. package/front_end/panels/explain/components/consoleInsightSourcesList.css +0 -51
  110. package/front_end/ui/components/docs/README.md +0 -6
  111. package/front_end/ui/components/docs/building-ui-documentation/ComponentEvents.md +0 -54
  112. package/front_end/ui/components/docs/building-ui-documentation/ComponentPerformance.md +0 -136
  113. package/front_end/ui/components/docs/building-ui-documentation/CreatingComponents.md +0 -242
  114. package/front_end/ui/components/docs/building-ui-documentation/README.md +0 -23
  115. package/front_end/ui/components/docs/building-ui-documentation/StylingComponents.md +0 -66
  116. package/front_end/ui/components/docs/building-ui-documentation/TestingComponents.md +0 -111
  117. package/front_end/ui/components/docs/component_docs.ts +0 -24
  118. package/front_end/ui/components/docs/component_docs_styles.css +0 -53
  119. package/front_end/ui/components/docs/create_breadcrumbs.ts +0 -44
  120. package/front_end/ui/components/docs/slider/basic.html +0 -20
  121. package/front_end/ui/components/docs/switch/basic.html +0 -20
  122. /package/front_end/models/issues_manager/descriptions/{genericFormAriaLabelledByToNonExistingId.md → genericFormAriaLabelledByToNonExistingIdError.md} +0 -0
  123. /package/front_end/models/issues_manager/descriptions/{genericFormLabelHasNeitherForNorNestedInput.md → genericFormLabelHasNeitherForNorNestedInputError.md} +0 -0
  124. /package/front_end/{core/platform → ui/legacy}/DOMUtilities.ts +0 -0
@@ -29,7 +29,7 @@ tokens**](https://crsrc.org/c/third_party/devtools-frontend/src/front_end/design
29
29
  name e.g. `--sys-color-error-container`). They reference palette tokens and
30
30
  incorporate light / dark mode switches and should be used in the code directly.
31
31
  You can view all system tokens in their light and dark variant when running the
32
- component server with `npm run components-server` under *Theme Colors*.
32
+ component server on our [component documentation page](https://chromedevtools.github.io/devtools-frontend/#ThemeColors).
33
33
 
34
34
  [**Application
35
35
  tokens**](https://crsrc.org/c/third_party/devtools-frontend/src/front_end/application_tokens.css)
package/eslint.config.mjs CHANGED
@@ -60,7 +60,7 @@ export default defineConfig([
60
60
  'scripts/protocol_typescript/*.js',
61
61
  'scripts/deps/tests/fixtures',
62
62
  'test/**/fixtures/',
63
- 'test/e2e/**/*.js',
63
+ 'test/e2e_non_hosted/**/*.js',
64
64
  'test/shared/**/*.js',
65
65
  ]),
66
66
  {
@@ -1,3 +1,10 @@
1
1
  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M9.25 3V14.125L7.062 11.938L6 13L10 17L14 13L12.938 11.938L10.75 14.125V3H9.25Z" fill="black"/>
2
+ <g clip-path="url(#clip0_4041_3016)">
3
+ <path d="M9.25 4H10.75V13.125L14.9375 8.9375L16 10L10 16L4 10L5.0625 8.9375L9.25 13.125V4Z" fill="black"/>
4
+ </g>
5
+ <defs>
6
+ <clipPath id="clip0_4041_3016">
7
+ <rect width="20" height="20" fill="white"/>
8
+ </clipPath>
9
+ </defs>
3
10
  </svg>
@@ -1,3 +1,10 @@
1
1
  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <path d="M9.25 17V5.875L7.062 8.062L6 7L10 3L14 7L12.938 8.062L10.75 5.875V17H9.25Z" fill="black"/>
2
+ <g clip-path="url(#clip0_4041_3013)">
3
+ <path d="M9.25 16V6.875L5.0625 11.0625L4 10L10 4L16 10L14.9375 11.0625L10.75 6.875V16H9.25Z" fill="black"/>
4
+ </g>
5
+ <defs>
6
+ <clipPath id="clip0_4041_3013">
7
+ <rect width="20" height="20" fill="white"/>
8
+ </clipPath>
9
+ </defs>
3
10
  </svg>
@@ -733,7 +733,7 @@ export function convertToUserTierEnum(userTier: string|undefined): UserTier {
733
733
  return UserTier.PUBLIC;
734
734
  }
735
735
  }
736
- return UserTier.BETA;
736
+ return UserTier.PUBLIC;
737
737
  }
738
738
 
739
739
  let hostConfigTrackerInstance: HostConfigTracker|undefined;
@@ -549,7 +549,6 @@ export const enum EnumeratedHistogram {
549
549
  LighthouseModeRun = 'DevTools.LighthouseModeRun',
550
550
  LighthouseCategoryUsed = 'DevTools.LighthouseCategoryUsed',
551
551
  SwatchActivated = 'DevTools.SwatchActivated',
552
- AnimationPlaybackRateChanged = 'DevTools.AnimationPlaybackRateChanged',
553
552
  BuiltInAiAvailability = 'DevTools.BuiltInAiAvailability',
554
553
  // LINT.ThenChange(/front_end/devtools_compatibility.js:EnumeratedHistogram)
555
554
  }
@@ -269,11 +269,6 @@ export class UserMetrics {
269
269
  EnumeratedHistogram.SwatchActivated, swatch, SwatchType.MAX_VALUE);
270
270
  }
271
271
 
272
- animationPlaybackRateChanged(playbackRate: AnimationsPlaybackRate): void {
273
- InspectorFrontendHostInstance.recordEnumeratedHistogram(
274
- EnumeratedHistogram.AnimationPlaybackRateChanged, playbackRate, AnimationsPlaybackRate.MAX_VALUE);
275
- }
276
-
277
272
  workspacesPopulated(wallClockTimeInMilliseconds: number): void {
278
273
  InspectorFrontendHostInstance.recordPerformanceHistogram(
279
274
  'DevTools.Workspaces.PopulateWallClocktime', wallClockTimeInMilliseconds);
@@ -0,0 +1,18 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import type * as Api from './api/api.js';
6
+ import * as Browser from './browser/browser.js';
7
+ import * as Node from './node/node.js';
8
+
9
+ export const HOST_RUNTIME = ((): Api.HostRuntime.HostRuntime => {
10
+ if (Node.HostRuntime.IS_NODE) {
11
+ return Node.HostRuntime.HOST_RUNTIME;
12
+ }
13
+ if (Browser.HostRuntime.IS_BROWSER) {
14
+ return Browser.HostRuntime.HOST_RUNTIME;
15
+ }
16
+
17
+ throw new Error('Unknown runtime!');
18
+ })();
@@ -29,10 +29,10 @@ export function keyIsArrowKey(key: string): key is ArrowKey {
29
29
  return ARROW_KEYS.has(key as ArrowKey);
30
30
  }
31
31
 
32
- export function isEscKey(event: KeyboardEvent): boolean {
32
+ export function isEscKey(event: {readonly key: string}): boolean {
33
33
  return event.key === 'Escape';
34
34
  }
35
35
 
36
- export function isEnterOrSpaceKey(event: KeyboardEvent): boolean {
36
+ export function isEnterOrSpaceKey(event: {readonly key: string}): boolean {
37
37
  return event.key === 'Enter' || event.key === ' ';
38
38
  }
@@ -584,5 +584,5 @@ export const concatBase64 = function(lhs: string, rhs: string): string {
584
584
  }
585
585
  const lhsLeaveAsIs = lhs.substring(0, lhs.length - 4);
586
586
  const lhsToDecode = lhs.substring(lhs.length - 4);
587
- return lhsLeaveAsIs + window.btoa(window.atob(lhsToDecode) + window.atob(rhs));
587
+ return lhsLeaveAsIs + globalThis.btoa(globalThis.atob(lhsToDecode) + globalThis.atob(rhs));
588
588
  };
@@ -0,0 +1,20 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ /**
6
+ * Provides abstractions for host features that require different implementations depending
7
+ * on whether DevTools runs in the browser or Node.js
8
+ */
9
+ export interface HostRuntime {
10
+ createWorker(url: string): Worker;
11
+ }
12
+
13
+ /**
14
+ * Abstracts away the differences between browser web workers and Node.js worker threads.
15
+ */
16
+ export interface Worker {
17
+ // TODO(crbug.com/461952544): Actually add some methods here.
18
+ // Leave one marker method to make this non-empty.
19
+ dispose?(): void;
20
+ }
@@ -0,0 +1,7 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as HostRuntime from './HostRuntime.js';
6
+
7
+ export {HostRuntime};
@@ -0,0 +1,14 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import type * as Api from '../api/api.js';
6
+
7
+ export const IS_BROWSER =
8
+ typeof window !== 'undefined' || (typeof self !== 'undefined' && typeof self.postMessage === 'function');
9
+
10
+ export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
11
+ createWorker(): Api.HostRuntime.Worker {
12
+ throw new Error('unimplemented');
13
+ }
14
+ };
@@ -0,0 +1,7 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as HostRuntime from './HostRuntime.js';
6
+
7
+ export {HostRuntime};
@@ -0,0 +1,13 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import type * as Api from '../api/api.js';
6
+
7
+ export const IS_NODE = typeof (process as unknown) !== 'undefined' && process.versions?.node !== null;
8
+
9
+ export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
10
+ createWorker(): Api.HostRuntime.Worker {
11
+ throw new Error('unimplemented');
12
+ }
13
+ };
@@ -0,0 +1,7 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as HostRuntime from './HostRuntime.js';
6
+
7
+ export {HostRuntime};
@@ -7,7 +7,7 @@ import * as Brand from './Brand.js';
7
7
  import * as Constructor from './Constructor.js';
8
8
  import * as DateUtilities from './DateUtilities.js';
9
9
  import * as DevToolsPath from './DevToolsPath.js';
10
- import * as DOMUtilities from './DOMUtilities.js';
10
+ import * as HostRuntime from './HostRuntime.js';
11
11
  import * as KeyboardUtilities from './KeyboardUtilities.js';
12
12
  import * as MapUtilities from './MapUtilities.js';
13
13
  import * as MimeType from './MimeType.js';
@@ -31,7 +31,7 @@ export {
31
31
  Constructor,
32
32
  DateUtilities,
33
33
  DevToolsPath,
34
- DOMUtilities,
34
+ HostRuntime,
35
35
  KeyboardUtilities,
36
36
  MapUtilities,
37
37
  MimeType,
@@ -26,35 +26,114 @@ export class SourceMapScopesInfo {
26
26
  }
27
27
 
28
28
  /**
29
- * If the source map does not contain any scopes information, this factory function attempts to create bare bones scope information
29
+ * If the source map does not contain any scopes information, this factory function attempts to create scope information
30
30
  * via the script's AST combined with the mappings.
31
31
  *
32
32
  * We create the generated ranges from the scope tree and for each range we create an original scope that matches the bounds 1:1.
33
- * We don't map the bounds via mappings as mappings are often iffy and it's not strictly required to translate stack traces where we
34
- * map call-sites separately.
35
33
  */
36
34
  static createFromAst(
37
35
  sourceMap: SourceMap, scopeTree: Formatter.FormatterWorkerPool.ScopeTreeNode,
38
36
  text: TextUtils.Text.Text): SourceMapScopesInfo {
39
- const {scope, range} = convertScope(scopeTree, undefined, undefined);
40
- return new SourceMapScopesInfo(sourceMap, {scopes: [scope], ranges: [range]});
37
+ const numSourceUrls = sourceMap.sourceURLs().length;
38
+ const scopeBySourceUrl: ScopesCodec.OriginalScope[] = [];
39
+ for (let i = 0; i < numSourceUrls; i++) {
40
+ const scope: ScopesCodec.OriginalScope = {
41
+ start: {line: 0, column: 0},
42
+ end: {line: Number.POSITIVE_INFINITY, column: Number.POSITIVE_INFINITY},
43
+ isStackFrame: false,
44
+ variables: [],
45
+ children: [],
46
+ };
47
+ scopeBySourceUrl.push(scope);
48
+ }
49
+
50
+ // Convert the entire scopeTree. Returns a root range that encompasses everything,
51
+ // and inserts scopes by sourceIndex into the above scopeBySourceUrl.
52
+ const {range} = convertScope(scopeTree, undefined);
53
+ return new SourceMapScopesInfo(sourceMap, {scopes: scopeBySourceUrl, ranges: [range]});
54
+
55
+ /**
56
+ * Recursively finds the correct place in the tree to insert the new scope.
57
+ * Maintains the invariant that children are sorted and contained by their parent.
58
+ */
59
+ function insertInScope(parent: ScopesCodec.OriginalScope, newScope: ScopesCodec.OriginalScope): void {
60
+ // Check if the newScope fits strictly inside any of the existing children.
61
+ for (const child of parent.children) {
62
+ if (contains(child, newScope)) {
63
+ insertInScope(child, newScope);
64
+ return;
65
+ }
66
+ }
67
+
68
+ // When here, newScope belongs directly in parent.
69
+ // However, newScope might encompass some of parent's existing children (due
70
+ // to compiler transform quirks or arbitrary insertion order). We must move
71
+ // those children inside newScope.
72
+ const childrenToKeep: ScopesCodec.OriginalScope[] = [];
73
+ for (const child of parent.children) {
74
+ if (contains(newScope, child)) {
75
+ // child is actually inside newScope, so re-parent it.
76
+ newScope.children.push(child);
77
+ child.parent = newScope;
78
+ } else {
79
+ childrenToKeep.push(child);
80
+ }
81
+ }
82
+
83
+ // Find the correct index in the remaining children to insert newScope.
84
+ // We look for the first child that starts after the new scope.
85
+ const insertIndex = childrenToKeep.findIndex(child => compareScopes(newScope, child) < 0);
86
+ if (insertIndex === -1) {
87
+ // If no child starts after, it goes at the end.
88
+ childrenToKeep.push(newScope);
89
+ } else {
90
+ childrenToKeep.splice(insertIndex, 0, newScope);
91
+ }
92
+
93
+ // Update parent's children to only be the ones that don't belong to newScope.
94
+ parent.children = childrenToKeep;
95
+ newScope.parent = parent;
96
+ }
97
+
98
+ function contains(outer: ScopesCodec.OriginalScope, inner: ScopesCodec.OriginalScope): boolean {
99
+ return comparePositions(outer.start, inner.start) <= 0 && comparePositions(outer.end, inner.end) >= 0;
100
+ }
101
+
102
+ function compareScopes(a: ScopesCodec.OriginalScope, b: ScopesCodec.OriginalScope): number {
103
+ return comparePositions(a.start, b.start);
104
+ }
105
+
106
+ function comparePositions(a: ScopesCodec.Position, b: ScopesCodec.Position): number {
107
+ if (a.line !== b.line) {
108
+ return a.line - b.line;
109
+ }
110
+ return a.column - b.column;
111
+ }
41
112
 
42
113
  function convertScope(
43
- node: Formatter.FormatterWorkerPool.ScopeTreeNode, parentScope: ScopesCodec.OriginalScope|undefined,
44
- parentRange: ScopesCodec.GeneratedRange|
45
- undefined): {scope: ScopesCodec.OriginalScope, range: ScopesCodec.GeneratedRange} {
114
+ node: Formatter.FormatterWorkerPool.ScopeTreeNode,
115
+ parentRange: ScopesCodec.GeneratedRange|undefined): {range: ScopesCodec.GeneratedRange} {
46
116
  const start = positionFromOffset(node.start);
47
117
  const end = positionFromOffset(node.end);
118
+ const startEntry = sourceMap.findEntry(start.line, start.column);
119
+ const endEntry = sourceMap.findEntry(end.line, end.column);
120
+ const sourceIndex = startEntry?.sourceIndex;
121
+ const canMapOriginalPosition = startEntry && endEntry && sourceIndex !== undefined &&
122
+ startEntry.sourceIndex === endEntry.sourceIndex && startEntry.sourceIndex !== undefined && sourceIndex >= 0 &&
123
+ sourceIndex < numSourceUrls;
48
124
  const isStackFrame = node.kind === Formatter.FormatterWorkerPool.ScopeKind.FUNCTION;
49
125
 
50
- const scope: ScopesCodec.OriginalScope = {
51
- start,
52
- end,
53
- name: sourceMap.findEntry(start.line, start.column, 0)?.name,
54
- isStackFrame,
55
- variables: [],
56
- children: [],
57
- };
126
+ let scope: ScopesCodec.OriginalScope|undefined;
127
+ if (canMapOriginalPosition) {
128
+ scope = {
129
+ start: {line: startEntry.sourceLineNumber, column: startEntry.sourceColumnNumber},
130
+ end: {line: endEntry.sourceLineNumber, column: endEntry.sourceColumnNumber},
131
+ name: startEntry.name,
132
+ isStackFrame,
133
+ variables: [],
134
+ children: [],
135
+ };
136
+ }
58
137
 
59
138
  const range: ScopesCodec.GeneratedRange = {
60
139
  start,
@@ -67,11 +146,14 @@ export class SourceMapScopesInfo {
67
146
  };
68
147
 
69
148
  parentRange?.children.push(range);
70
- parentScope?.children.push(scope);
149
+ if (canMapOriginalPosition && scope) {
150
+ const rootScope = scopeBySourceUrl[sourceIndex];
151
+ insertInScope(rootScope, scope);
152
+ }
71
153
 
72
- node.children.forEach(child => convertScope(child, scope, range));
154
+ node.children.forEach(child => convertScope(child, range));
73
155
 
74
- return {scope, range};
156
+ return {range};
75
157
  }
76
158
 
77
159
  function positionFromOffset(offset: number): ScopesCodec.Position {
@@ -347,7 +429,16 @@ export class SourceMapScopesInfo {
347
429
  /**
348
430
  * Returns the authored function name of the function containing the provided generated position.
349
431
  */
350
- findOriginalFunctionName({line, column}: ScopesCodec.Position): string|null {
432
+ findOriginalFunctionName(position: ScopesCodec.Position): string|null {
433
+ const originalInnerMostScope = this.findOriginalFunctionScope(position)?.scope ?? undefined;
434
+ return this.#findFunctionNameInOriginalScopeChain(originalInnerMostScope);
435
+ }
436
+
437
+ /**
438
+ * Returns the authored function scope of the function containing the provided generated position.
439
+ */
440
+ findOriginalFunctionScope({line, column}: ScopesCodec.Position):
441
+ {scope: ScopesCodec.OriginalScope, url?: Platform.DevToolsPath.UrlString}|null {
351
442
  // There are 2 approaches:
352
443
  // 1) Find the inner-most generated range containing the provided generated position
353
444
  // and use it's OriginalScope (then walk it outwards until we hit a function).
@@ -376,7 +467,24 @@ export class SourceMapScopesInfo {
376
467
  .at(-1);
377
468
  }
378
469
 
379
- return this.#findFunctionNameInOriginalScopeChain(originalInnerMostScope) ?? null;
470
+ if (!originalInnerMostScope) {
471
+ return null;
472
+ }
473
+
474
+ const functionScope = this.#findFunctionScopeInOriginalScopeChain(originalInnerMostScope);
475
+ if (!functionScope) {
476
+ return null;
477
+ }
478
+
479
+ // Find the root scope for some given original source, to get the source url.
480
+ let rootScope: ScopesCodec.OriginalScope = functionScope;
481
+ while (rootScope.parent) {
482
+ rootScope = rootScope.parent;
483
+ }
484
+ const sourceIndex = this.#originalScopes.indexOf(rootScope);
485
+ const url = sourceIndex !== -1 ? this.#sourceMap.sourceURLForSourceIndex(sourceIndex) : undefined;
486
+
487
+ return functionScope ? {scope: functionScope, url} : null;
380
488
  }
381
489
 
382
490
  /**
@@ -403,15 +511,25 @@ export class SourceMapScopesInfo {
403
511
  return result;
404
512
  }
405
513
 
406
- #findFunctionNameInOriginalScopeChain(innerOriginalScope: ScopesCodec.OriginalScope|undefined): string|null {
514
+ #findFunctionScopeInOriginalScopeChain(innerOriginalScope: ScopesCodec.OriginalScope|undefined):
515
+ ScopesCodec.OriginalScope|null {
407
516
  for (let originalScope = innerOriginalScope; originalScope; originalScope = originalScope.parent) {
408
517
  if (originalScope.isStackFrame) {
409
- return originalScope.name ?? '';
518
+ return originalScope;
410
519
  }
411
520
  }
412
521
  return null;
413
522
  }
414
523
 
524
+ #findFunctionNameInOriginalScopeChain(innerOriginalScope: ScopesCodec.OriginalScope|undefined): string|null {
525
+ const functionScope = this.#findFunctionScopeInOriginalScopeChain(innerOriginalScope);
526
+ if (!functionScope) {
527
+ return null;
528
+ }
529
+
530
+ return functionScope.name ?? '';
531
+ }
532
+
415
533
  /**
416
534
  * Returns one or more original stack frames for this single "raw frame" or call-site.
417
535
  *
@@ -7,7 +7,7 @@ import * as Common from '../common/common.js';
7
7
  import * as Platform from '../platform/platform.js';
8
8
  import * as ProtocolClient from '../protocol_client/protocol_client.js';
9
9
 
10
- import {SDKModel} from './SDKModel.js';
10
+ import {SDKModel, type SDKModelConstructor} from './SDKModel.js';
11
11
  import type {TargetManager} from './TargetManager.js';
12
12
 
13
13
  export class Target extends ProtocolClient.InspectorBackend.TargetBase {
@@ -111,20 +111,11 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
111
111
  this.#targetInfo = targetInfo;
112
112
  }
113
113
 
114
- createModels(required: Set<new(arg1: Target) => SDKModel>): void {
114
+ /** Creates the models in the order in which they are provided */
115
+ createModels(models: SDKModelConstructor[]): void {
115
116
  this.#creatingModels = true;
116
- const registeredModels = Array.from(SDKModel.registeredModels.entries());
117
- // Create early models.
118
- for (const [modelClass, info] of registeredModels) {
119
- if (info.early) {
120
- this.model(modelClass);
121
- }
122
- }
123
- // Create autostart and required models.
124
- for (const [modelClass, info] of registeredModels) {
125
- if (info.autostart || required.has(modelClass)) {
126
- this.model(modelClass);
127
- }
117
+ for (const model of models) {
118
+ this.model(model);
128
119
  }
129
120
  this.#creatingModels = false;
130
121
  }
@@ -10,7 +10,7 @@ import {assertNotNullOrUndefined} from '../platform/platform.js';
10
10
  import type * as ProtocolClient from '../protocol_client/protocol_client.js';
11
11
  import * as Root from '../root/root.js';
12
12
 
13
- import {SDKModel, type SDKModelConstructor} from './SDKModel.js';
13
+ import {type RegistrationInfo, SDKModel, type SDKModelConstructor} from './SDKModel.js';
14
14
  import {Target, Type as TargetType} from './Target.js';
15
15
 
16
16
  export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
@@ -31,8 +31,12 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
31
31
  #scopeTarget: Target|null;
32
32
  #defaultScopeSet: boolean;
33
33
  readonly #scopeChangeListeners: Set<() => void>;
34
+ readonly #overrideAutoStartModels?: Set<SDKModelConstructor>;
34
35
 
35
- constructor() {
36
+ /**
37
+ * @param overrideAutoStartModels If provided, then the `autostart` flag on {@link RegistrationInfo} will be ignored.
38
+ */
39
+ constructor(overrideAutoStartModels?: Set<SDKModelConstructor>) {
36
40
  super();
37
41
  this.#targets = new Set();
38
42
  this.#observers = new Set();
@@ -44,6 +48,7 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
44
48
  this.#scopedObservers = new WeakSet();
45
49
  this.#defaultScopeSet = false;
46
50
  this.#scopeChangeListeners = new Set();
51
+ this.#overrideAutoStartModels = overrideAutoStartModels;
47
52
  }
48
53
 
49
54
  static instance({forceNew}: {
@@ -205,6 +210,23 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
205
210
  this.#scopedObservers.delete(targetObserver);
206
211
  }
207
212
 
213
+ /** @returns The set of models we create unconditionally for new targets in the order in which they should be created */
214
+ #autoStartModels(): SDKModelConstructor[] {
215
+ const earlyModels = new Set<SDKModelConstructor>();
216
+ const models = new Set<SDKModelConstructor>();
217
+ const shouldAutostart = (model: SDKModelConstructor, info: RegistrationInfo): boolean =>
218
+ this.#overrideAutoStartModels ? this.#overrideAutoStartModels.has(model) : info.autostart;
219
+
220
+ for (const [model, info] of SDKModel.registeredModels) {
221
+ if (info.early) {
222
+ earlyModels.add(model);
223
+ } else if (shouldAutostart(model, info) || this.#modelObservers.has(model)) {
224
+ models.add(model);
225
+ }
226
+ }
227
+ return [...earlyModels, ...models];
228
+ }
229
+
208
230
  createTarget(
209
231
  id: Protocol.Target.TargetID|'main', name: string, type: TargetType, parentTarget: Target|null,
210
232
  sessionId?: string, waitForDebuggerInPage?: boolean, connection?: ProtocolClient.CDPConnection.CDPConnection,
@@ -214,7 +236,7 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
214
236
  if (waitForDebuggerInPage) {
215
237
  void target.pageAgent().invoke_waitForDebugger();
216
238
  }
217
- target.createModels(new Set(this.#modelObservers.keysArray()));
239
+ target.createModels(this.#autoStartModels());
218
240
  this.#targets.add(target);
219
241
 
220
242
  const inScope = this.isInScope(target);
@@ -316,7 +338,7 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
316
338
  this.#browserTarget = new Target(
317
339
  this, /* #id*/ 'main', /* #name*/ 'browser', TargetType.BROWSER, /* #parentTarget*/ null,
318
340
  /* #sessionId */ '', /* suspended*/ false, /* #connection*/ null, /* targetInfo*/ undefined);
319
- this.#browserTarget.createModels(new Set(this.#modelObservers.keysArray()));
341
+ this.#browserTarget.createModels(this.#autoStartModels());
320
342
  }
321
343
  const targetId =
322
344
  await Host.InspectorFrontendHost.InspectorFrontendHostInstance.initialTargetId() as Protocol.Target.TargetID;
@@ -363,6 +363,30 @@ const UIStrings = {
363
363
  */
364
364
  networkCacheExplanation:
365
365
  'Disabling the network cache will simulate a network experience similar to a first time visitor.',
366
+ /**
367
+ * @description Setting under the Sources category to toggle usage of JavaScript source maps.
368
+ */
369
+ javaScriptSourceMaps: 'JavaScript source maps',
370
+ /**
371
+ * @description Title of a setting under the Sources category that can be invoked through the Command Menu
372
+ */
373
+ enableJavaScriptSourceMaps: 'Enable JavaScript source maps',
374
+ /**
375
+ * @description Title of a setting under the Sources category that can be invoked through the Command Menu
376
+ */
377
+ disableJavaScriptSourceMaps: 'Disable JavaScript source maps',
378
+ /**
379
+ * @description Title of a setting under the Sources category
380
+ */
381
+ cssSourceMaps: 'CSS source maps',
382
+ /**
383
+ * @description Title of a setting under the Sources category that can be invoked through the Command Menu
384
+ */
385
+ enableCssSourceMaps: 'Enable CSS source maps',
386
+ /**
387
+ * @description Title of a setting under the Sources category that can be invoked through the Command Menu
388
+ */
389
+ disableCssSourceMaps: 'Disable CSS source maps',
366
390
  } as const;
367
391
  const str_ = i18n.i18n.registerUIStrings('core/sdk/sdk-meta.ts', UIStrings);
368
392
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
@@ -1132,3 +1156,41 @@ Common.Settings.registerSettingExtension({
1132
1156
  tooltip: i18nLazyString(UIStrings.remoteFileLoadingInfo),
1133
1157
  }
1134
1158
  });
1159
+
1160
+ Common.Settings.registerSettingExtension({
1161
+ category: Common.Settings.SettingCategory.SOURCES,
1162
+ storageType: Common.Settings.SettingStorageType.SYNCED,
1163
+ title: i18nLazyString(UIStrings.javaScriptSourceMaps),
1164
+ settingName: 'js-source-maps-enabled',
1165
+ settingType: Common.Settings.SettingType.BOOLEAN,
1166
+ defaultValue: true,
1167
+ options: [
1168
+ {
1169
+ value: true,
1170
+ title: i18nLazyString(UIStrings.enableJavaScriptSourceMaps),
1171
+ },
1172
+ {
1173
+ value: false,
1174
+ title: i18nLazyString(UIStrings.disableJavaScriptSourceMaps),
1175
+ },
1176
+ ],
1177
+ });
1178
+
1179
+ Common.Settings.registerSettingExtension({
1180
+ category: Common.Settings.SettingCategory.SOURCES,
1181
+ storageType: Common.Settings.SettingStorageType.SYNCED,
1182
+ title: i18nLazyString(UIStrings.cssSourceMaps),
1183
+ settingName: 'css-source-maps-enabled',
1184
+ settingType: Common.Settings.SettingType.BOOLEAN,
1185
+ defaultValue: true,
1186
+ options: [
1187
+ {
1188
+ value: true,
1189
+ title: i18nLazyString(UIStrings.enableCssSourceMaps),
1190
+ },
1191
+ {
1192
+ value: false,
1193
+ title: i18nLazyString(UIStrings.disableCssSourceMaps),
1194
+ },
1195
+ ],
1196
+ });
@@ -450,7 +450,6 @@
450
450
  TimelineNavigationSettingState: 'DevTools.TimelineNavigationSettingState',
451
451
  SyncSetting: 'DevTools.SyncSetting',
452
452
  SwatchActivated: 'DevTools.SwatchActivated',
453
- AnimationPlaybackRateChanged: 'DevTools.AnimationPlaybackRateChanged',
454
453
  BuiltInAiAvailability: 'DevTools.BuiltInAiAvailability'
455
454
  // LINT.ThenChange(/front_end/core/host/InspectorFrontendHostAPI.ts:EnumeratedHistogram)
456
455
  };
@@ -717,7 +717,7 @@ export class MainImpl {
717
717
  // @ts-expect-error Used in ElementsTreeOutline
718
718
  eventCopy['original'] = event;
719
719
  const document = event.target && (event.target as HTMLElement).ownerDocument;
720
- const target = document ? Platform.DOMUtilities.deepActiveElement(document) : null;
720
+ const target = document ? UI.DOMUtilities.deepActiveElement(document) : null;
721
721
  if (target) {
722
722
  target.dispatchEvent(eventCopy);
723
723
  }
@@ -778,7 +778,7 @@ export class ZoomActionDelegate implements UI.ActionRegistration.ActionDelegate
778
778
  export class SearchActionDelegate implements UI.ActionRegistration.ActionDelegate {
779
779
  handleAction(_context: UI.Context.Context, actionId: string): boolean {
780
780
  let searchableView = UI.SearchableView.SearchableView.fromElement(
781
- Platform.DOMUtilities.deepActiveElement(document),
781
+ UI.DOMUtilities.deepActiveElement(document),
782
782
  );
783
783
  if (!searchableView) {
784
784
  const currentPanel = (UI.InspectorView.InspectorView.instance().currentPanelDeprecated() as UI.Panel.Panel);