chrome-devtools-frontend 1.0.1595925 → 1.0.1596535

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 (129) hide show
  1. package/.stylelintrc.json +3 -1
  2. package/docs/ui_engineering.md +0 -36
  3. package/front_end/core/common/Console.ts +6 -6
  4. package/front_end/core/common/Settings.ts +12 -8
  5. package/front_end/core/host/UserMetrics.ts +0 -1
  6. package/front_end/core/root/DevToolsContext.ts +13 -7
  7. package/front_end/core/root/ExperimentNames.ts +0 -1
  8. package/front_end/core/sdk/CPUThrottlingManager.ts +12 -9
  9. package/front_end/core/sdk/DOMModel.ts +206 -0
  10. package/front_end/core/sdk/FrameManager.ts +7 -8
  11. package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
  12. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +1 -1
  13. package/front_end/entrypoints/greendev_floaty/floaty.css +2 -2
  14. package/front_end/entrypoints/main/MainImpl.ts +1 -7
  15. package/front_end/foundation/Universe.ts +22 -11
  16. package/front_end/generated/InspectorBackendCommands.ts +7 -0
  17. package/front_end/generated/protocol-mapping.d.ts +16 -0
  18. package/front_end/generated/protocol-proxy-api.d.ts +25 -0
  19. package/front_end/generated/protocol.ts +71 -0
  20. package/front_end/models/ai_assistance/AiConversation.ts +6 -95
  21. package/front_end/models/ai_assistance/ConversationHandler.ts +1 -1
  22. package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -1
  23. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +14 -0
  24. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
  25. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +3 -0
  26. package/front_end/panels/ai_assistance/components/ChatMessage.ts +73 -35
  27. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -6
  28. package/front_end/panels/ai_assistance/components/chatMessage.css +4 -2
  29. package/front_end/panels/application/IndexedDBModel.ts +2 -4
  30. package/front_end/panels/application/ServiceWorkersView.ts +3 -11
  31. package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
  32. package/front_end/panels/elements/ComputedStyleWidget.ts +25 -16
  33. package/front_end/panels/elements/ElementsPanel.ts +0 -1
  34. package/front_end/panels/elements/StandaloneStylesContainer.ts +48 -12
  35. package/front_end/panels/elements/StylePropertiesSection.ts +97 -1
  36. package/front_end/panels/elements/StylePropertyTreeElement.ts +27 -5
  37. package/front_end/panels/elements/StylesContainer.ts +1 -0
  38. package/front_end/panels/elements/StylesSidebarPane.ts +48 -32
  39. package/front_end/panels/elements/nodeStackTraceWidget.css +1 -1
  40. package/front_end/panels/elements/stylePropertiesTreeOutline.css +1 -1
  41. package/front_end/panels/emulation/DeviceModeToolbar.ts +171 -89
  42. package/front_end/panels/greendev/GreenDevPanel.css +2 -2
  43. package/front_end/panels/issues/AffectedPermissionElementsView.ts +9 -6
  44. package/front_end/panels/lighthouse/LighthouseController.ts +13 -5
  45. package/front_end/panels/lighthouse/LighthousePanel.ts +22 -5
  46. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +11 -3
  47. package/front_end/panels/recorder/components/StepView.ts +0 -2
  48. package/front_end/panels/recorder/components/stepView.css +13 -13
  49. package/front_end/panels/recorder/components/timelineSection.css +6 -7
  50. package/front_end/panels/settings/components/SyncSection.ts +4 -13
  51. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +2 -15
  52. package/front_end/panels/timeline/RecordingMetadata.ts +1 -1
  53. package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
  54. package/front_end/panels/timeline/TimelinePanel.ts +18 -0
  55. package/front_end/panels/timeline/TimelineUIUtils.ts +7 -4
  56. package/front_end/panels/timeline/components/CWVMetrics.ts +339 -0
  57. package/front_end/panels/timeline/components/Sidebar.ts +17 -0
  58. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +10 -0
  59. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +25 -267
  60. package/front_end/panels/timeline/components/Utils.ts +2 -2
  61. package/front_end/panels/timeline/components/components.ts +2 -0
  62. package/front_end/panels/timeline/components/cwvMetrics.css +107 -0
  63. package/front_end/panels/timeline/components/sidebarSingleInsightSet.css +0 -102
  64. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  65. package/front_end/panels/timeline/utils/Helpers.ts +5 -1
  66. package/front_end/panels/webauthn/webauthnPane.css +1 -1
  67. package/front_end/third_party/chromium/README.chromium +1 -1
  68. package/front_end/third_party/puppeteer/README.chromium +2 -2
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +7 -0
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +1 -0
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -0
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +1 -0
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -0
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -0
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +5 -0
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +7 -0
  91. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +14 -3
  92. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +7 -0
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +1 -0
  96. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -0
  98. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +1 -0
  100. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -0
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -0
  104. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +5 -0
  106. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  108. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  109. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  110. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/types.d.ts +7 -0
  112. package/front_end/third_party/puppeteer/package/package.json +1 -1
  113. package/front_end/third_party/puppeteer/package/src/api/Page.ts +8 -0
  114. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +4 -0
  115. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +7 -0
  116. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +6 -0
  117. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  118. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  119. package/front_end/ui/components/text_editor/AutocompleteHistory.ts +89 -5
  120. package/front_end/ui/components/tree_outline/TreeOutline.ts +1 -1
  121. package/front_end/ui/legacy/ProgressIndicator.ts +1 -1
  122. package/front_end/ui/legacy/Toolbar.ts +1 -1
  123. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
  124. package/front_end/ui/legacy/legacy.ts +0 -2
  125. package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
  126. package/inspector_overlay/loadCSS.rollup.js +2 -2
  127. package/inspector_overlay/tool_source_order.css +1 -0
  128. package/package.json +1 -1
  129. package/front_end/ui/legacy/Fragment.ts +0 -234
package/.stylelintrc.json CHANGED
@@ -2,11 +2,13 @@
2
2
  "extends": "stylelint-config-standard",
3
3
  "plugins": [
4
4
  "./scripts/stylelint_rules/lib/use_theme_colors.mjs",
5
- "./scripts/stylelint_rules/lib/check_highlight_scope.mjs"
5
+ "./scripts/stylelint_rules/lib/check_highlight_scope.mjs",
6
+ "./scripts/stylelint_rules/lib/use_monospace_font.mjs"
6
7
  ],
7
8
  "rules": {
8
9
  "plugin/use_theme_colors": true,
9
10
  "plugin/check_highlight_scope": true,
11
+ "plugin/use_monospace_font": true,
10
12
  "alpha-value-notation": "percentage",
11
13
  "color-function-notation": "modern",
12
14
  "hue-degree-notation": "angle",
@@ -1183,42 +1183,6 @@ export const DEFAULT_VIEW = (input, _output, target) => {
1183
1183
  };
1184
1184
  ```
1185
1185
 
1186
- ## Migrating `UI.Fragment`
1187
-
1188
- Replace `UI.Fragment.Fragment.build` with a standard lit-html template. To get a reference to an element, use the `ref` directive.
1189
-
1190
- **Before:**
1191
- ```typescript
1192
-
1193
- class SomeWidget extends UI.Widget.Widget {
1194
- constructor() {
1195
- super();
1196
- const contrastFragment = UI.Fragment.Fragment.build`
1197
- <div class="contrast-container-in-grid" $="contrast-container-element">
1198
- <span class="contrast-preview">Aa</span>
1199
- <span>${contrastRatioString}</span>
1200
- </div>`;
1201
- this.contentElement.appendChild(contrastFragment.element());
1202
- }
1203
- }
1204
- ```
1205
-
1206
- **After:**
1207
- ```typescript
1208
-
1209
-
1210
- export const DEFAULT_VIEW = (input, output, target) => {
1211
- render(html`
1212
- <div>
1213
- <div class="contrast-container-in-grid" ${ref(e => { output.contrastContainerElement = e; })}>
1214
- <span class="contrast-preview">Aa</span>
1215
- <span>${contrastRatioString}</span>
1216
- </div>
1217
- </div>`,
1218
- target, {host: input});
1219
- };
1220
- ```
1221
-
1222
1186
  ## Migrating `UI.ARIAUtils` helpers
1223
1187
 
1224
1188
  Replace calls to `UI.ARIAUtils` helper functions with the corresponding ARIA attributes directly in the lit-html template.
@@ -2,24 +2,24 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
+ import * as Root from '../root/root.js';
6
+
5
7
  import {ObjectWrapper} from './Object.js';
6
8
  import {reveal} from './Revealer.js';
7
9
 
8
- let consoleInstance: Console|undefined;
9
-
10
10
  export class Console extends ObjectWrapper<EventTypes> {
11
11
  readonly #messages: Message[] = [];
12
12
 
13
13
  static instance(opts?: {forceNew: boolean}): Console {
14
- if (!consoleInstance || opts?.forceNew) {
15
- consoleInstance = new Console();
14
+ if (!Root.DevToolsContext.globalInstance().has(Console) || opts?.forceNew) {
15
+ Root.DevToolsContext.globalInstance().set(Console, new Console());
16
16
  }
17
17
 
18
- return consoleInstance;
18
+ return Root.DevToolsContext.globalInstance().get(Console);
19
19
  }
20
20
 
21
21
  static removeInstance(): void {
22
- consoleInstance = undefined;
22
+ Root.DevToolsContext.globalInstance().delete(Console);
23
23
  }
24
24
 
25
25
  /**
@@ -22,8 +22,6 @@ import {
22
22
  SettingType,
23
23
  } from './SettingRegistration.js';
24
24
 
25
- let settingsInstance: Settings|undefined;
26
-
27
25
  export interface SettingsCreationOptions {
28
26
  syncedStorage: SettingsStorage;
29
27
  globalStorage: SettingsStorage;
@@ -85,7 +83,7 @@ export class Settings {
85
83
  }
86
84
 
87
85
  static hasInstance(): boolean {
88
- return typeof settingsInstance !== 'undefined';
86
+ return Root.DevToolsContext.globalInstance().has(Settings);
89
87
  }
90
88
 
91
89
  static instance(opts: {
@@ -107,20 +105,26 @@ export class Settings {
107
105
  logSettingAccess,
108
106
  runSettingsMigration
109
107
  } = opts;
110
- if (!settingsInstance || forceNew) {
108
+ if (!Root.DevToolsContext.globalInstance().has(Settings) || forceNew) {
111
109
  if (!syncedStorage || !globalStorage || !localStorage || !settingRegistrations) {
112
110
  throw new Error(`Unable to create settings: global and local storage must be provided: ${new Error().stack}`);
113
111
  }
114
112
 
115
- settingsInstance = new Settings(
116
- {syncedStorage, globalStorage, localStorage, settingRegistrations, logSettingAccess, runSettingsMigration});
113
+ Root.DevToolsContext.globalInstance().set(Settings, new Settings({
114
+ syncedStorage,
115
+ globalStorage,
116
+ localStorage,
117
+ settingRegistrations,
118
+ logSettingAccess,
119
+ runSettingsMigration
120
+ }));
117
121
  }
118
122
 
119
- return settingsInstance;
123
+ return Root.DevToolsContext.globalInstance().get(Settings);
120
124
  }
121
125
 
122
126
  static removeInstance(): void {
123
- settingsInstance = undefined;
127
+ Root.DevToolsContext.globalInstance().delete(Settings);
124
128
  }
125
129
 
126
130
  private registerModuleSetting(setting: Setting<unknown>): void {
@@ -822,7 +822,6 @@ export enum DevtoolsExperiments {
822
822
  'authored-deployed-grouping' = 63,
823
823
  'just-my-code' = 65,
824
824
  'use-source-map-scopes' = 76,
825
- 'timeline-show-postmessage-events' = 86,
826
825
  'timeline-debug-mode' = 93,
827
826
  'durable-messages' = 110,
828
827
  'jpeg-xl' = 111,
@@ -11,7 +11,14 @@ export type ConstructorT<T> = new (...args: any[]) => T;
11
11
  * via constructor, and not just pass a {@link DevToolsContext} around. That would hide
12
12
  * dependencies and we want to be explicit.
13
13
  */
14
- export class DevToolsContext {
14
+ export interface DevToolsContext {
15
+ get<T>(ctor: ConstructorT<T>): T;
16
+ }
17
+
18
+ /**
19
+ * The actual implementation. Should only be accessed by test-setup code or the bootstrapper.
20
+ */
21
+ export class WritableDevToolsContext implements DevToolsContext {
15
22
  readonly #instances = new Map<ConstructorT<unknown>, unknown>();
16
23
 
17
24
  get<T>(ctor: ConstructorT<T>): T {
@@ -28,8 +35,7 @@ export class DevToolsContext {
28
35
  }
29
36
 
30
37
  /**
31
- * @deprecated Should only be used by existing `instance` accessors and the bootstrapper.
32
- * Exists on the public interface only for migration purposes for now.
38
+ * Should only be used by existing `instance` accessors and the bootstrapper.
33
39
  */
34
40
  set<T>(ctor: ConstructorT<T>, instance: T): void {
35
41
  // TODO(crbug.com/458180550): We need to throw here if an instance was already set!
@@ -42,16 +48,16 @@ export class DevToolsContext {
42
48
  }
43
49
  }
44
50
 
45
- let gInstance: DevToolsContext|null = null;
51
+ let gInstance: WritableDevToolsContext|null = null;
46
52
 
47
53
  /**
48
54
  * @deprecated Exists to migrate instance() methods.
49
55
  */
50
- export function globalInstance(): DevToolsContext {
56
+ export function globalInstance(): WritableDevToolsContext {
51
57
  if (!gInstance) {
52
58
  // TODO(crbug.com/458180550): This should really throw to prevent side-effects and globals
53
59
  // from leaking all over the place.
54
- gInstance = new DevToolsContext();
60
+ gInstance = new WritableDevToolsContext();
55
61
  }
56
62
  return gInstance;
57
63
  }
@@ -59,6 +65,6 @@ export function globalInstance(): DevToolsContext {
59
65
  /**
60
66
  * @deprecated Should only be called by test setup and MainImpl
61
67
  */
62
- export function setGlobalInstance(context: DevToolsContext|null): void {
68
+ export function setGlobalInstance(context: WritableDevToolsContext|null): void {
63
69
  gInstance = context;
64
70
  }
@@ -20,7 +20,6 @@ export enum ExperimentName {
20
20
  AUTHORED_DEPLOYED_GROUPING = 'authored-deployed-grouping',
21
21
  JUST_MY_CODE = 'just-my-code',
22
22
  USE_SOURCE_MAP_SCOPES = 'use-source-map-scopes',
23
- TIMELINE_SHOW_POST_MESSAGE_EVENTS = 'timeline-show-postmessage-events',
24
23
  TIMELINE_DEBUG_MODE = 'timeline-debug-mode',
25
24
  DURABLE_MESSAGES = 'durable-messages',
26
25
  JPEG_XL = 'jpeg-xl',
@@ -39,24 +39,27 @@ let throttlingManagerInstance: CPUThrottlingManager;
39
39
 
40
40
  export class CPUThrottlingManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes> implements
41
41
  SDKModelObserver<EmulationModel> {
42
+ readonly #targetManager: TargetManager;
42
43
  #cpuThrottlingOption: CPUThrottlingOption;
43
44
  #calibratedThrottlingSetting: Common.Settings.Setting<CalibratedCPUThrottling>;
44
45
  #hardwareConcurrency?: number;
45
46
  #pendingMainTargetPromise?: (r: number) => void;
46
47
 
47
- private constructor() {
48
+ private constructor(settings: Common.Settings.Settings, targetManager: TargetManager) {
48
49
  super();
50
+ this.#targetManager = targetManager;
49
51
  this.#cpuThrottlingOption = NoThrottlingOption;
50
- this.#calibratedThrottlingSetting = Common.Settings.Settings.instance().createSetting<CalibratedCPUThrottling>(
52
+ this.#calibratedThrottlingSetting = settings.createSetting<CalibratedCPUThrottling>(
51
53
  'calibrated-cpu-throttling', {}, Common.Settings.SettingStorageType.GLOBAL);
52
54
  this.#calibratedThrottlingSetting.addChangeListener(this.#onCalibratedSettingChanged, this);
53
- TargetManager.instance().observeModels(EmulationModel, this);
55
+ targetManager.observeModels(EmulationModel, this);
54
56
  }
55
57
 
56
58
  static instance(opts: {forceNew: boolean|null} = {forceNew: null}): CPUThrottlingManager {
57
59
  const {forceNew} = opts;
58
60
  if (!throttlingManagerInstance || forceNew) {
59
- throttlingManagerInstance = new CPUThrottlingManager();
61
+ throttlingManagerInstance =
62
+ new CPUThrottlingManager(Common.Settings.Settings.instance(), TargetManager.instance());
60
63
  }
61
64
 
62
65
  return throttlingManagerInstance;
@@ -84,7 +87,7 @@ export class CPUThrottlingManager extends Common.ObjectWrapper.ObjectWrapper<Eve
84
87
  return;
85
88
  }
86
89
 
87
- for (const emulationModel of TargetManager.instance().models(EmulationModel)) {
90
+ for (const emulationModel of this.#targetManager.models(EmulationModel)) {
88
91
  void emulationModel.setCPUThrottlingRate(rate);
89
92
  }
90
93
  this.dispatchEventToListeners(Events.RATE_CHANGED, rate);
@@ -96,7 +99,7 @@ export class CPUThrottlingManager extends Common.ObjectWrapper.ObjectWrapper<Eve
96
99
  }
97
100
 
98
101
  this.#cpuThrottlingOption = option;
99
- for (const emulationModel of TargetManager.instance().models(EmulationModel)) {
102
+ for (const emulationModel of this.#targetManager.models(EmulationModel)) {
100
103
  void emulationModel.setCPUThrottlingRate(this.#cpuThrottlingOption.rate());
101
104
  }
102
105
  this.dispatchEventToListeners(Events.RATE_CHANGED, this.#cpuThrottlingOption.rate());
@@ -104,7 +107,7 @@ export class CPUThrottlingManager extends Common.ObjectWrapper.ObjectWrapper<Eve
104
107
 
105
108
  setHardwareConcurrency(concurrency: number): void {
106
109
  this.#hardwareConcurrency = concurrency;
107
- for (const emulationModel of TargetManager.instance().models(EmulationModel)) {
110
+ for (const emulationModel of this.#targetManager.models(EmulationModel)) {
108
111
  void emulationModel.setHardwareConcurrency(concurrency);
109
112
  }
110
113
  this.dispatchEventToListeners(Events.HARDWARE_CONCURRENCY_CHANGED, this.#hardwareConcurrency);
@@ -115,14 +118,14 @@ export class CPUThrottlingManager extends Common.ObjectWrapper.ObjectWrapper<Eve
115
118
  // target may error. So if we get any errors here at all, assume that we do
116
119
  // not have a target.
117
120
  try {
118
- return TargetManager.instance().primaryPageTarget() !== null;
121
+ return this.#targetManager.primaryPageTarget() !== null;
119
122
  } catch {
120
123
  return false;
121
124
  }
122
125
  }
123
126
 
124
127
  async getHardwareConcurrency(): Promise<number> {
125
- const target = TargetManager.instance().primaryPageTarget();
128
+ const target = this.#targetManager.primaryPageTarget();
126
129
  const existingCallback = this.#pendingMainTargetPromise;
127
130
 
128
131
  // If the main target hasn't attached yet, block callers until it appears.
@@ -1223,6 +1223,122 @@ export class DOMNode extends Common.ObjectWrapper.ObjectWrapper<DOMNodeEventType
1223
1223
  return this.domModel().nodeForId(response.nodeId);
1224
1224
  }
1225
1225
 
1226
+ async takeSnapshot(ownerDocumentSnapshot?: DOMDocument): Promise<DOMNode> {
1227
+ const snapshot = (this instanceof DOMDocument) ? new DOMDocumentSnapshot(this.domModel(), {
1228
+ nodeId: this.id,
1229
+ backendNodeId: this.backendNodeId(),
1230
+ nodeType: this.nodeType(),
1231
+ nodeName: this.nodeName(),
1232
+ localName: this.localName(),
1233
+ nodeValue: this.nodeValueInternal,
1234
+ } as Protocol.DOM.Node) :
1235
+ new DOMNodeSnapshot(this.domModel());
1236
+ snapshot.id = this.id;
1237
+ snapshot.#backendNodeId = this.#backendNodeId;
1238
+ snapshot.#frameOwnerFrameId = this.#frameOwnerFrameId;
1239
+ snapshot.#nodeType = this.#nodeType;
1240
+ snapshot.#nodeName = this.#nodeName;
1241
+ snapshot.#localName = this.#localName;
1242
+ snapshot.nodeValueInternal = this.nodeValueInternal;
1243
+ snapshot.#pseudoType = this.#pseudoType;
1244
+ snapshot.#pseudoIdentifier = this.#pseudoIdentifier;
1245
+ snapshot.#shadowRootType = this.#shadowRootType;
1246
+ snapshot.#xmlVersion = this.#xmlVersion;
1247
+ snapshot.#isSVGNode = this.#isSVGNode;
1248
+ snapshot.#isScrollable = this.#isScrollable;
1249
+ snapshot.#affectedByStartingStyles = this.#affectedByStartingStyles;
1250
+ snapshot.ownerDocument =
1251
+ ownerDocumentSnapshot || ((snapshot instanceof DOMDocument) ? snapshot : this.ownerDocument);
1252
+ snapshot.#isInShadowTree = this.#isInShadowTree;
1253
+ snapshot.childNodeCountInternal = this.childNodeCountInternal;
1254
+
1255
+ if (snapshot instanceof DOMDocument && this instanceof DOMDocument) {
1256
+ snapshot.documentURL = this.documentURL;
1257
+ snapshot.baseURL = this.baseURL;
1258
+ }
1259
+
1260
+ if (!this.childrenInternal && this.childNodeCountInternal > 0) {
1261
+ await this.getSubtree(1, false);
1262
+ }
1263
+
1264
+ for (const [name, attr] of this.#attributes) {
1265
+ snapshot.#attributes.set(name, {name: attr.name, value: attr.value, _node: snapshot});
1266
+ }
1267
+
1268
+ if (this.childrenInternal) {
1269
+ snapshot.childrenInternal = [];
1270
+ for (const child of this.childrenInternal) {
1271
+ const childSnapshot = await child.takeSnapshot(snapshot.ownerDocument || undefined);
1272
+ childSnapshot.parentNode = snapshot;
1273
+ childSnapshot.ownerDocument = (snapshot instanceof DOMDocument) ? snapshot : snapshot.ownerDocument;
1274
+ snapshot.childrenInternal.push(childSnapshot);
1275
+ if (childSnapshot.ownerDocument instanceof DOMDocument) {
1276
+ if (childSnapshot.nodeName() === 'HTML' && !childSnapshot.ownerDocument.documentElement) {
1277
+ childSnapshot.ownerDocument.documentElement = childSnapshot;
1278
+ }
1279
+ if (childSnapshot.nodeName() === 'BODY' && !childSnapshot.ownerDocument.body) {
1280
+ childSnapshot.ownerDocument.body = childSnapshot;
1281
+ }
1282
+ }
1283
+ }
1284
+ }
1285
+
1286
+ for (const root of this.shadowRootsInternal) {
1287
+ const rootSnapshot = await root.takeSnapshot(snapshot.ownerDocument || undefined);
1288
+ rootSnapshot.parentNode = snapshot;
1289
+ rootSnapshot.ownerDocument = snapshot.ownerDocument;
1290
+ snapshot.shadowRootsInternal.push(rootSnapshot);
1291
+ }
1292
+
1293
+ if (this.templateContentInternal) {
1294
+ const templateSnapshot = await this.templateContentInternal.takeSnapshot(snapshot.ownerDocument || undefined);
1295
+ templateSnapshot.parentNode = snapshot;
1296
+ templateSnapshot.ownerDocument = snapshot.ownerDocument;
1297
+ snapshot.templateContentInternal = templateSnapshot;
1298
+ }
1299
+
1300
+ if (this.contentDocumentInternal) {
1301
+ const contentDocSnapshot = await this.contentDocumentInternal.takeSnapshot();
1302
+ contentDocSnapshot.parentNode = snapshot;
1303
+ snapshot.contentDocumentInternal = contentDocSnapshot as DOMDocumentSnapshot;
1304
+ }
1305
+
1306
+ if (this.#importedDocument) {
1307
+ const importedDocSnapshot = await this.#importedDocument.takeSnapshot(snapshot.ownerDocument || undefined);
1308
+ importedDocSnapshot.parentNode = snapshot;
1309
+ importedDocSnapshot.ownerDocument = snapshot.ownerDocument;
1310
+ snapshot.#importedDocument = importedDocSnapshot;
1311
+ }
1312
+
1313
+ for (const [pseudoType, nodes] of this.#pseudoElements) {
1314
+ const snapshots = [];
1315
+ for (const node of nodes) {
1316
+ const pseudoSnapshot = await node.takeSnapshot(snapshot.ownerDocument || undefined);
1317
+ pseudoSnapshot.parentNode = snapshot;
1318
+ pseudoSnapshot.ownerDocument = snapshot.ownerDocument;
1319
+ snapshots.push(pseudoSnapshot);
1320
+ }
1321
+ snapshot.#pseudoElements.set(pseudoType, snapshots);
1322
+ }
1323
+
1324
+ // We intentionally preserve references to live nodes for assignedSlot and distributedNodes.
1325
+ // This allows slot adorners in the Elements panel to remain functional within the snapshot,
1326
+ // enabling users to resolve and jump to the actual nodes in the live DOM tree.
1327
+ if (this.#distributedNodes) {
1328
+ snapshot.#distributedNodes = [...this.#distributedNodes];
1329
+ }
1330
+
1331
+ snapshot.assignedSlot = this.assignedSlot;
1332
+
1333
+ snapshot.#retainedNodes = this.#retainedNodes;
1334
+
1335
+ if (this.#adoptedStyleSheets.length) {
1336
+ snapshot.setAdoptedStyleSheets(this.#adoptedStyleSheets.map(sheet => sheet.id));
1337
+ }
1338
+
1339
+ return snapshot;
1340
+ }
1341
+
1226
1342
  classNames(): string[] {
1227
1343
  const classes = this.getAttribute('class');
1228
1344
  return classes ? classes.split(/\s+/) : [];
@@ -2176,6 +2292,96 @@ export class DOMModelUndoStack {
2176
2292
  }
2177
2293
 
2178
2294
  SDKModel.register(DOMModel, {capabilities: Capability.DOM, autostart: true});
2295
+ export class DOMNodeSnapshot extends DOMNode {
2296
+ override init(
2297
+ _doc: DOMDocument|null, _isInShadowTree: boolean, _payload: Protocol.DOM.Node,
2298
+ _retainedNodes?: Set<Protocol.DOM.BackendNodeId>|undefined): void {
2299
+ }
2300
+
2301
+ override setNodeName(_name: string, _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
2302
+ }
2303
+
2304
+ override setNodeValue(_value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2305
+ }
2306
+
2307
+ override setAttribute(_name: string, _text: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2308
+ }
2309
+
2310
+ override setAttributeValue(_name: string, _value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2311
+ }
2312
+
2313
+ override removeAttribute(_name: string): Promise<void> {
2314
+ return Promise.resolve();
2315
+ }
2316
+
2317
+ override setOuterHTML(_html: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2318
+ }
2319
+
2320
+ override removeNode(_callback?: ((arg0: string|null, arg1?: Protocol.DOM.NodeId|undefined) => void)|undefined):
2321
+ Promise<void> {
2322
+ return Promise.resolve();
2323
+ }
2324
+
2325
+ override copyTo(
2326
+ _targetNode: DOMNode, _anchorNode: DOMNode|null,
2327
+ _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
2328
+ }
2329
+
2330
+ override moveTo(
2331
+ _targetNode: DOMNode, _anchorNode: DOMNode|null,
2332
+ _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
2333
+ }
2334
+
2335
+ override setAsInspectedNode(): Promise<void> {
2336
+ return Promise.resolve();
2337
+ }
2338
+ }
2339
+
2340
+ export class DOMDocumentSnapshot extends DOMDocument {
2341
+ override init(
2342
+ _doc: DOMDocument|null, _isInShadowTree: boolean, _payload: Protocol.DOM.Node,
2343
+ _retainedNodes?: Set<Protocol.DOM.BackendNodeId>|undefined): void {
2344
+ }
2345
+
2346
+ override setNodeName(_name: string, _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
2347
+ }
2348
+
2349
+ override setNodeValue(_value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2350
+ }
2351
+
2352
+ override setAttribute(_name: string, _text: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2353
+ }
2354
+
2355
+ override setAttributeValue(_name: string, _value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2356
+ }
2357
+
2358
+ override removeAttribute(_name: string): Promise<void> {
2359
+ return Promise.resolve();
2360
+ }
2361
+
2362
+ override setOuterHTML(_html: string, _callback?: ((arg0: string|null) => void)|undefined): void {
2363
+ }
2364
+
2365
+ override removeNode(_callback?: ((arg0: string|null, arg1?: Protocol.DOM.NodeId|undefined) => void)|undefined):
2366
+ Promise<void> {
2367
+ return Promise.resolve();
2368
+ }
2369
+
2370
+ override copyTo(
2371
+ _targetNode: DOMNode, _anchorNode: DOMNode|null,
2372
+ _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
2373
+ }
2374
+
2375
+ override moveTo(
2376
+ _targetNode: DOMNode, _anchorNode: DOMNode|null,
2377
+ _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
2378
+ }
2379
+
2380
+ override setAsInspectedNode(): Promise<void> {
2381
+ return Promise.resolve();
2382
+ }
2383
+ }
2384
+
2179
2385
  export interface Attribute {
2180
2386
  name: string;
2181
2387
  value: string;
@@ -4,14 +4,13 @@
4
4
 
5
5
  import type * as Protocol from '../../generated/protocol.js';
6
6
  import * as Common from '../common/common.js';
7
+ import * as Root from '../root/root.js';
7
8
 
8
9
  import type {Resource} from './Resource.js';
9
10
  import {Events as ResourceTreeModelEvents, type ResourceTreeFrame, ResourceTreeModel} from './ResourceTreeModel.js';
10
11
  import type {Target} from './Target.js';
11
12
  import {type SDKModelObserver, TargetManager} from './TargetManager.js';
12
13
 
13
- let frameManagerInstance: FrameManager|null = null;
14
-
15
14
  /**
16
15
  * The FrameManager is a central storage for all #frames. It collects #frames from all
17
16
  * ResourceTreeModel-instances (one per target), so that #frames can be found by id
@@ -37,22 +36,22 @@ export class FrameManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
37
36
  }>();
38
37
  #awaitedFrames = new Map<string, Array<{resolve: (frame: ResourceTreeFrame) => void, notInTarget?: Target}>>();
39
38
 
40
- constructor() {
39
+ constructor(targetManager: TargetManager) {
41
40
  super();
42
- TargetManager.instance().observeModels(ResourceTreeModel, this);
41
+ targetManager.observeModels(ResourceTreeModel, this);
43
42
  }
44
43
 
45
44
  static instance({forceNew}: {
46
45
  forceNew: boolean,
47
46
  } = {forceNew: false}): FrameManager {
48
- if (!frameManagerInstance || forceNew) {
49
- frameManagerInstance = new FrameManager();
47
+ if (!Root.DevToolsContext.globalInstance().has(FrameManager) || forceNew) {
48
+ Root.DevToolsContext.globalInstance().set(FrameManager, new FrameManager(TargetManager.instance()));
50
49
  }
51
- return frameManagerInstance;
50
+ return Root.DevToolsContext.globalInstance().get(FrameManager);
52
51
  }
53
52
 
54
53
  static removeInstance(): void {
55
- frameManagerInstance = null;
54
+ Root.DevToolsContext.globalInstance().delete(FrameManager);
56
55
  }
57
56
 
58
57
  modelAdded(resourceTreeModel: ResourceTreeModel): void {
@@ -418,7 +418,7 @@ export class SourceMapScopesInfo {
418
418
  * Returns the authored function name of the function containing the provided generated position.
419
419
  */
420
420
  findOriginalFunctionName(position: ScopesCodec.Position): string|null {
421
- const originalInnerMostScope = this.findOriginalFunctionScope(position)?.scope ?? undefined;
421
+ const originalInnerMostScope = this.findOriginalFunctionScope(position)?.scope;
422
422
  return this.#findFunctionNameInOriginalScopeChain(originalInnerMostScope);
423
423
  }
424
424
 
@@ -431,7 +431,7 @@ async function init(): Promise<void> {
431
431
  settingRegistrations: Common.SettingRegistration.getRegisteredSettings(),
432
432
  }
433
433
  });
434
- Root.DevToolsContext.setGlobalInstance(universe.context);
434
+ Root.DevToolsContext.setGlobalInstance(universe.context as Root.DevToolsContext.WritableDevToolsContext);
435
435
 
436
436
  await i18n.i18n.fetchAndRegisterLocaleData('en-US');
437
437
  Host.InspectorFrontendHost.InspectorFrontendHostInstance.connectionReady();
@@ -134,7 +134,7 @@ html, body {
134
134
  margin-top: 8px;
135
135
  padding-top: 8px;
136
136
  border-top: 1px solid #eee;
137
- font-family: monospace;
137
+ font-family: var(--monospace-font-family);
138
138
  }
139
139
 
140
140
  .thought, .action {
@@ -186,7 +186,7 @@ html, body {
186
186
 
187
187
  .green-dev-floaty-dialog-node-description {
188
188
  font-size: 11px;
189
- font-family: monospace;
189
+ font-family: var(--monospace-font-family);
190
190
  color: #0b57d0;
191
191
  background-color: #d3e3fd;
192
192
  padding: 2px 8px;
@@ -201,7 +201,7 @@ export class MainImpl {
201
201
  },
202
202
  };
203
203
  this.#universe = new Foundation.Universe.Universe(creationOptions);
204
- Root.DevToolsContext.setGlobalInstance(this.#universe.context);
204
+ Root.DevToolsContext.setGlobalInstance(this.#universe.context as Root.DevToolsContext.WritableDevToolsContext);
205
205
 
206
206
  await this.requestAndRegisterLocaleData();
207
207
 
@@ -413,11 +413,6 @@ export class MainImpl {
413
413
  Root.Runtime.experiments.register(
414
414
  Root.ExperimentNames.ExperimentName.JUST_MY_CODE, 'Hide ignore-listed code in Sources tree view');
415
415
 
416
- Root.Runtime.experiments.register(
417
- Root.ExperimentNames.ExperimentName.TIMELINE_SHOW_POST_MESSAGE_EVENTS,
418
- 'Performance panel: show postMessage dispatch and handling flows',
419
- );
420
-
421
416
  Root.Runtime.experiments.registerHostExperiment({
422
417
  name: Root.ExperimentNames.ExperimentName.DURABLE_MESSAGES,
423
418
  title: 'Durable Messages',
@@ -493,7 +488,6 @@ export class MainImpl {
493
488
 
494
489
  // These instances need to be created early so they don't miss any events about requests/issues/etc.
495
490
  Logs.NetworkLog.NetworkLog.instance();
496
- SDK.FrameManager.FrameManager.instance();
497
491
  Logs.LogManager.LogManager.instance();
498
492
  IssuesManager.IssuesManager.IssuesManager.instance({
499
493
  forceNew: true,