chrome-devtools-frontend 1.0.1654411 → 1.0.1656897

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 (204) hide show
  1. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +116 -0
  2. package/.agents/skills/ui-eng-vision-logic-consolidator/SKILL.md +82 -0
  3. package/.agents/skills/ui-eng-vision-orchestrator/SKILL.md +123 -0
  4. package/.agents/skills/ui-eng-vision-test-scaffolder/SKILL.md +125 -0
  5. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +75 -0
  6. package/AUTHORS +1 -0
  7. package/config/owner/COMMON_OWNERS +0 -4
  8. package/docs/playbook.md +1 -1
  9. package/front_end/Tests.js +1 -0
  10. package/front_end/core/common/Settings.ts +47 -30
  11. package/front_end/core/sdk/CPUThrottlingManager.ts +10 -159
  12. package/front_end/core/sdk/ConsoleModel.ts +13 -11
  13. package/front_end/core/sdk/DOMDebuggerModel.ts +11 -5
  14. package/front_end/core/sdk/DOMModel.ts +7 -5
  15. package/front_end/core/sdk/EventBreakpointsModel.ts +9 -5
  16. package/front_end/core/sdk/IsolateManager.ts +6 -6
  17. package/front_end/core/sdk/ResourceTreeModel.ts +5 -3
  18. package/front_end/core/sdk/SourceMapCache.ts +2 -4
  19. package/front_end/core/sdk/SourceMapManager.ts +8 -7
  20. package/front_end/core/sdk/TargetManager.ts +17 -0
  21. package/front_end/entrypoints/devtools_app/devtools_app.ts +0 -1
  22. package/front_end/entrypoints/main/MainImpl.ts +12 -36
  23. package/front_end/entrypoints/main/SimpleApp.ts +0 -13
  24. package/front_end/entrypoints/main/main-meta.ts +1 -1
  25. package/front_end/foundation/Universe.ts +110 -3
  26. package/front_end/generated/InspectorBackendCommands.ts +5 -1
  27. package/front_end/generated/SupportedCSSProperties.js +2 -6
  28. package/front_end/generated/protocol-mapping.d.ts +8 -0
  29. package/front_end/generated/protocol-proxy-api.d.ts +15 -0
  30. package/front_end/generated/protocol.ts +36 -1
  31. package/front_end/models/ai_assistance/AiConversation.ts +0 -6
  32. package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +1 -1
  33. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +2 -156
  34. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -24
  35. package/front_end/models/ai_assistance/agents/StylingAgent.ts +2 -358
  36. package/front_end/models/ai_assistance/ai_assistance.ts +0 -6
  37. package/front_end/models/ai_assistance/contexts/RequestContext.snapshot.txt +0 -1
  38. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +0 -2
  39. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -14
  40. package/front_end/models/autofill_manager/AutofillManager.ts +1 -2
  41. package/front_end/models/crux-manager/CrUXManager.ts +16 -11
  42. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  43. package/front_end/models/persistence/AutomaticFileSystemManager.ts +14 -13
  44. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +12 -9
  45. package/front_end/models/persistence/IsolatedFileSystemManager.ts +18 -9
  46. package/front_end/models/project_settings/ProjectSettingsModel.ts +12 -11
  47. package/front_end/models/trace/handlers/ScreenshotsHandler.ts +14 -59
  48. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +3 -29
  49. package/front_end/panels/application/DeviceBoundSessionsView.ts +15 -3
  50. package/front_end/panels/application/FrameDetailsView.ts +2 -1
  51. package/front_end/panels/application/ServiceWorkersView.ts +193 -161
  52. package/front_end/panels/application/serviceWorkersView.css +8 -0
  53. package/front_end/panels/common/CPUThrottlingOption.ts +142 -0
  54. package/front_end/panels/common/ThrottlingUtils.ts +9 -4
  55. package/front_end/panels/common/common.ts +1 -1
  56. package/front_end/panels/console/ConsoleViewMessage.ts +45 -0
  57. package/front_end/panels/elements/ElementsPanel.ts +35 -102
  58. package/front_end/panels/elements/ElementsTreeOutline.ts +0 -4
  59. package/front_end/panels/elements/elements-meta.ts +3 -2
  60. package/front_end/panels/emulation/DeviceModeToolbar.ts +46 -45
  61. package/front_end/panels/mobile_throttling/CalibrationController.ts +6 -5
  62. package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +1 -1
  63. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +40 -13
  64. package/front_end/panels/mobile_throttling/ThrottlingPresets.ts +13 -17
  65. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +15 -13
  66. package/front_end/panels/network/NetworkLogView.ts +0 -9
  67. package/front_end/panels/network/NetworkPanel.ts +1 -63
  68. package/front_end/panels/network/RequestInitiatorView.ts +29 -4
  69. package/front_end/panels/network/components/HeaderSectionRow.css +9 -7
  70. package/front_end/panels/network/components/HeaderSectionRow.ts +20 -1
  71. package/front_end/panels/network/components/RequestHeaderSection.css +5 -3
  72. package/front_end/panels/network/components/RequestHeaderSection.ts +1 -2
  73. package/front_end/panels/network/components/RequestHeadersView.css +1 -1
  74. package/front_end/panels/security/SecurityPanel.ts +36 -23
  75. package/front_end/panels/settings/SettingsScreen.ts +18 -103
  76. package/front_end/panels/settings/settings-meta.ts +0 -24
  77. package/front_end/panels/timeline/TimelineController.ts +3 -2
  78. package/front_end/panels/timeline/TimelinePanel.ts +20 -3
  79. package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +15 -14
  80. package/front_end/panels/timeline/timelineFlamechartPopover.css +2 -0
  81. package/front_end/panels/utils/utils.ts +25 -24
  82. package/front_end/third_party/chromium/README.chromium +1 -1
  83. package/front_end/third_party/puppeteer/README.chromium +2 -2
  84. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +34 -55
  85. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +96 -83
  86. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +10 -1
  87. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/CDPSession.d.ts.map +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/CDPSession.js.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts +3 -2
  95. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.js.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Target.d.ts +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Target.js +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js +2 -1
  105. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Realm.js.map +1 -1
  108. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +2 -2
  109. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  110. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +5 -2
  111. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/FrameManager.d.ts.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/FrameManager.js +23 -13
  116. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/FrameManager.js.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPResponse.d.ts.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPResponse.js +4 -1
  119. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPResponse.js.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Input.js +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/LifecycleWatcher.d.ts.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/LifecycleWatcher.js.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts.map +1 -1
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.d.ts +3 -41
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.d.ts.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebMCP.js.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +4 -2
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/LaunchOptions.d.ts +5 -0
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/LaunchOptions.d.ts.map +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.d.ts +1 -1
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.d.ts.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.js +5 -5
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/httpUtils.js.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/types.d.ts +34 -55
  143. package/front_end/third_party/puppeteer/package/package.json +4 -4
  144. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +13 -1
  145. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +2 -3
  146. package/front_end/third_party/puppeteer/package/src/api/CDPSession.ts +3 -1
  147. package/front_end/third_party/puppeteer/package/src/api/HTTPResponse.ts +3 -2
  148. package/front_end/third_party/puppeteer/package/src/api/Realm.ts +1 -2
  149. package/front_end/third_party/puppeteer/package/src/api/Target.ts +1 -1
  150. package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +1 -2
  151. package/front_end/third_party/puppeteer/package/src/bidi/HTTPResponse.ts +3 -1
  152. package/front_end/third_party/puppeteer/package/src/bidi/core/Realm.ts +1 -3
  153. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +13 -3
  154. package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +1 -1
  155. package/front_end/third_party/puppeteer/package/src/cdp/FrameManager.ts +24 -13
  156. package/front_end/third_party/puppeteer/package/src/cdp/HTTPResponse.ts +4 -1
  157. package/front_end/third_party/puppeteer/package/src/cdp/Input.ts +1 -1
  158. package/front_end/third_party/puppeteer/package/src/cdp/LifecycleWatcher.ts +1 -4
  159. package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +2 -4
  160. package/front_end/third_party/puppeteer/package/src/cdp/WebMCP.ts +7 -76
  161. package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +1 -4
  162. package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +4 -1
  163. package/front_end/third_party/puppeteer/package/src/node/LaunchOptions.ts +5 -0
  164. package/front_end/third_party/puppeteer/package/src/revisions.ts +1 -1
  165. package/front_end/third_party/puppeteer/package/src/util/httpUtils.ts +5 -5
  166. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  167. package/front_end/third_party/puppeteer/third_party/parsel/README.chromium +1 -1
  168. package/front_end/ui/components/dialogs/Dialog.ts +3 -0
  169. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +0 -7
  170. package/front_end/ui/helpers/OpenInNewTab.ts +15 -7
  171. package/front_end/ui/legacy/TabbedPane.ts +1 -108
  172. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +9 -0
  173. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +172 -123
  174. package/front_end/ui/legacy/components/data_grid/DataGridExporter.ts +89 -0
  175. package/front_end/ui/legacy/components/data_grid/dataGrid.css +10 -0
  176. package/front_end/ui/legacy/components/data_grid/data_grid.ts +3 -1
  177. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +89 -40
  178. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  179. package/package.json +1 -1
  180. package/front_end/Images/navigationControls.png +0 -0
  181. package/front_end/Images/navigationControls_2x.png +0 -0
  182. package/front_end/Images/popoverArrows.png +0 -0
  183. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -746
  184. package/front_end/entrypoints/greendev_floaty/floaty.css +0 -301
  185. package/front_end/entrypoints/greendev_floaty/floaty.html +0 -38
  186. package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -415
  187. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +0 -834
  188. package/front_end/models/ai_assistance/agents/GreenDevAgentAntigravityCliSocketClient.ts +0 -53
  189. package/front_end/models/ai_assistance/agents/GreenDevAgentGeminiCliSocketClient.ts +0 -117
  190. package/front_end/models/annotations/AnnotationRepository.ts +0 -238
  191. package/front_end/models/annotations/AnnotationType.ts +0 -10
  192. package/front_end/models/annotations/README.md +0 -7
  193. package/front_end/models/annotations/annotations.ts +0 -6
  194. package/front_end/models/greendev/Prototypes.ts +0 -68
  195. package/front_end/models/greendev/README.md +0 -5
  196. package/front_end/models/greendev/greendev.ts +0 -5
  197. package/front_end/panels/common/Annotation.ts +0 -184
  198. package/front_end/panels/common/AnnotationManager.ts +0 -208
  199. package/front_end/panels/common/annotation.css +0 -40
  200. package/front_end/panels/greendev/GreenDevPanel.css +0 -282
  201. package/front_end/panels/greendev/GreenDevPanel.ts +0 -364
  202. package/front_end/panels/greendev/GreenDevShared.ts +0 -13
  203. package/front_end/panels/greendev/greendev-meta.ts +0 -52
  204. package/front_end/panels/greendev/greendev.ts +0 -9
@@ -0,0 +1,142 @@
1
+ // Copyright 2026 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 Common from '../../core/common/common.js';
6
+ import * as i18n from '../../core/i18n/i18n.js';
7
+
8
+ const UIStrings = {
9
+ /**
10
+ * @description Text label for a menu item indicating that no throttling is applied.
11
+ */
12
+ noThrottling: 'No throttling',
13
+ /**
14
+ * @description Text label for a menu item indicating that a specific slowdown multiplier is applied.
15
+ * @example {2} PH1
16
+ */
17
+ dSlowdown: '{PH1}× slowdown',
18
+ /**
19
+ * @description Text label for a menu item indicating an average mobile device.
20
+ */
21
+ calibratedMidTierMobile: 'Mid-tier mobile',
22
+ /**
23
+ * @description Text label for a menu item indicating a below-average mobile device.
24
+ */
25
+ calibratedLowTierMobile: 'Low-tier mobile',
26
+ /**
27
+ * @description Text label indicating why an option is not available, because the user's device is not fast enough to emulate a device.
28
+ */
29
+ calibrationErrorDeviceTooWeak: 'Device is not powerful enough',
30
+ } as const;
31
+ const str_ = i18n.i18n.registerUIStrings('panels/common/CPUThrottlingOption.ts', UIStrings);
32
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
33
+ const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
34
+
35
+ export enum CPUThrottlingRates {
36
+ NO_THROTTLING = 1,
37
+ MID_TIER_MOBILE = 4,
38
+ LOW_TIER_MOBILE = 6,
39
+ EXTRA_SLOW = 20,
40
+
41
+ // eslint-disable-next-line @typescript-eslint/naming-convention -- Used by web_tests.
42
+ MidTierMobile = MID_TIER_MOBILE,
43
+ // eslint-disable-next-line @typescript-eslint/naming-convention -- Used by web_tests.
44
+ LowEndMobile = LOW_TIER_MOBILE,
45
+ }
46
+
47
+ export type CalibratedDeviceType = 'low-tier-mobile'|'mid-tier-mobile';
48
+
49
+ export interface CPUThrottlingOption {
50
+ title: () => string;
51
+ rate: () => number;
52
+ calibratedDeviceType?: CalibratedDeviceType;
53
+ jslogContext: string;
54
+ }
55
+
56
+ function makeFixedPresetThrottlingOption(rate: CPUThrottlingRates): CPUThrottlingOption {
57
+ return {
58
+ title: rate === 1 ? i18nLazyString(UIStrings.noThrottling) : i18nLazyString(UIStrings.dSlowdown, {PH1: rate}),
59
+ rate: () => rate,
60
+ jslogContext: rate === 1 ? 'cpu-no-throttling' : `cpu-throttled-${rate}`,
61
+ };
62
+ }
63
+
64
+ export const NoThrottlingOption = makeFixedPresetThrottlingOption(CPUThrottlingRates.NO_THROTTLING);
65
+ export const MidTierThrottlingOption = makeFixedPresetThrottlingOption(CPUThrottlingRates.MID_TIER_MOBILE);
66
+ export const LowTierThrottlingOption = makeFixedPresetThrottlingOption(CPUThrottlingRates.LOW_TIER_MOBILE);
67
+ export const ExtraSlowThrottlingOption = makeFixedPresetThrottlingOption(CPUThrottlingRates.EXTRA_SLOW);
68
+
69
+ function makeCalibratedThrottlingOption(calibratedDeviceType: CalibratedDeviceType): CPUThrottlingOption {
70
+ const getSettingValue = (): number|CalibrationError|null => {
71
+ const setting = Common.Settings.Settings.instance().createSetting<CalibratedCPUThrottling>(
72
+ 'calibrated-cpu-throttling', {}, Common.Settings.SettingStorageType.GLOBAL);
73
+ const value = setting.get();
74
+ if (calibratedDeviceType === 'low-tier-mobile') {
75
+ return value.low ?? null;
76
+ }
77
+ if (calibratedDeviceType === 'mid-tier-mobile') {
78
+ return value.mid ?? null;
79
+ }
80
+ return null;
81
+ };
82
+
83
+ return {
84
+ title(): string {
85
+ const typeString = calibratedDeviceType === 'low-tier-mobile' ? i18nString(UIStrings.calibratedLowTierMobile) :
86
+ i18nString(UIStrings.calibratedMidTierMobile);
87
+
88
+ const value = getSettingValue();
89
+ if (typeof value === 'number') {
90
+ return `${typeString} – ${value.toFixed(1)}×`;
91
+ }
92
+
93
+ return typeString;
94
+ },
95
+ rate(): number {
96
+ const value = getSettingValue();
97
+ if (typeof value === 'number') {
98
+ return value;
99
+ }
100
+ return 0;
101
+ },
102
+ calibratedDeviceType,
103
+ jslogContext: `cpu-throttled-calibrated-${calibratedDeviceType}`,
104
+ };
105
+ }
106
+
107
+ export const CalibratedLowTierMobileThrottlingOption = makeCalibratedThrottlingOption('low-tier-mobile');
108
+ export const CalibratedMidTierMobileThrottlingOption = makeCalibratedThrottlingOption('mid-tier-mobile');
109
+
110
+ export interface CalibratedCPUThrottling {
111
+ /** Either the CPU multiplier, or an error code for why it could not be determined. */
112
+ low?: number|CalibrationError;
113
+ mid?: number|CalibrationError;
114
+ }
115
+
116
+ export enum CalibrationError {
117
+ DEVICE_TOO_WEAK = 'DEVICE_TOO_WEAK',
118
+ }
119
+
120
+ export function calibrationErrorToString(error: CalibrationError): string {
121
+ if (error === CalibrationError.DEVICE_TOO_WEAK) {
122
+ return i18nString(UIStrings.calibrationErrorDeviceTooWeak);
123
+ }
124
+
125
+ return error;
126
+ }
127
+
128
+ export const cpuThrottlingPresets: CPUThrottlingOption[] = [
129
+ NoThrottlingOption,
130
+ MidTierThrottlingOption,
131
+ LowTierThrottlingOption,
132
+ ExtraSlowThrottlingOption,
133
+ CalibratedLowTierMobileThrottlingOption,
134
+ CalibratedMidTierMobileThrottlingOption,
135
+ ];
136
+
137
+ export function determineOptionFromRate(rate: number, currentOption?: CPUThrottlingOption): CPUThrottlingOption {
138
+ if (currentOption && currentOption.rate() === rate) {
139
+ return currentOption;
140
+ }
141
+ return cpuThrottlingPresets.find(o => o.rate() === rate) || NoThrottlingOption;
142
+ }
@@ -5,8 +5,14 @@
5
5
  import * as SDK from '../../core/sdk/sdk.js';
6
6
  import * as CrUXManager from '../../models/crux-manager/crux-manager.js';
7
7
 
8
+ import {
9
+ CalibratedMidTierMobileThrottlingOption,
10
+ type CPUThrottlingOption,
11
+ MidTierThrottlingOption,
12
+ } from './CPUThrottlingOption.js';
13
+
8
14
  export interface ThrottlingRecommendations {
9
- cpuOption: SDK.CPUThrottlingManager.CPUThrottlingOption|null;
15
+ cpuOption: CPUThrottlingOption|null;
10
16
  networkConditions: SDK.NetworkManager.Conditions|null;
11
17
  }
12
18
 
@@ -18,10 +24,9 @@ export function getThrottlingRecommendations(): ThrottlingRecommendations {
18
24
  const cruxManager = CrUXManager.CrUXManager.instance();
19
25
  const roundTripTimeMetricData = cruxManager.getSelectedFieldMetricData('round_trip_time');
20
26
 
21
- let cpuOption: SDK.CPUThrottlingManager.CPUThrottlingOption =
22
- SDK.CPUThrottlingManager.CalibratedMidTierMobileThrottlingOption;
27
+ let cpuOption: CPUThrottlingOption = CalibratedMidTierMobileThrottlingOption;
23
28
  if (cpuOption.rate() === 0) {
24
- cpuOption = SDK.CPUThrottlingManager.MidTierThrottlingOption;
29
+ cpuOption = MidTierThrottlingOption;
25
30
  }
26
31
 
27
32
  const networkConditions = getRecommendedNetworkConditions(roundTripTimeMetricData);
@@ -97,13 +97,13 @@ export class TypeToAllowDialog {
97
97
  export {AiCodeCompletionTeaser} from './AiCodeCompletionTeaser.js';
98
98
  export * as AiCodeGenerationTeaser from './AiCodeGenerationTeaser.js';
99
99
  export {AiCodeGenerationUpgradeDialog} from './AiCodeGenerationUpgradeDialog.js';
100
- export {AnnotationManager} from './AnnotationManager.js';
101
100
  export {FreDialog} from './FreDialog.js';
102
101
  export {GdpSignUpDialog} from './GdpSignUpDialog.js';
103
102
  export {GeminiRebrandPromoDialog} from './GeminiRebrandPromoDialog.js';
104
103
  export {AiCodeCompletionDisclaimer} from './AiCodeCompletionDisclaimer.js';
105
104
  export * as AiCodeCompletionSummaryToolbar from './AiCodeCompletionSummaryToolbar.js';
106
105
  export * from './BadgeNotification.js';
106
+ export * as CPUThrottlingOption from './CPUThrottlingOption.js';
107
107
  export * as ExtensionPanel from './ExtensionPanel.js';
108
108
  export * as ExtensionServer from './ExtensionServer.js';
109
109
  export * as ExtensionView from './ExtensionView.js';
@@ -225,6 +225,18 @@ const UIStrings = {
225
225
  * @description Element title in Object Properties Section
226
226
  */
227
227
  invokePropertyGetter: 'Invoke property getter',
228
+ /**
229
+ * @description Context menu item to copy table data
230
+ */
231
+ copyTableAs: 'Copy table as',
232
+ /**
233
+ * @description Submenu item to copy table as Markdown
234
+ */
235
+ copyAsMarkdown: 'Copy as Markdown',
236
+ /**
237
+ * @description Submenu item to copy table as CSV
238
+ */
239
+ copyAsCsv: 'Copy as CSV',
228
240
  } as const;
229
241
  const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleViewMessage.ts', UIStrings);
230
242
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -2180,6 +2192,7 @@ export class ConsoleTableMessageView extends ConsoleViewMessage {
2180
2192
  if (this.dataGrid) {
2181
2193
  this.dataGrid.setStriped(true);
2182
2194
  this.dataGrid.setFocusable(false);
2195
+ this.dataGrid.setTableContextMenuCallback(this.populateTableContextMenu.bind(this));
2183
2196
 
2184
2197
  const formattedResult = document.createElement('span');
2185
2198
  formattedResult.classList.add('console-message-text');
@@ -2205,6 +2218,38 @@ export class ConsoleTableMessageView extends ConsoleViewMessage {
2205
2218
  }
2206
2219
  return defaultConsoleRowHeight;
2207
2220
  }
2221
+
2222
+ private populateTableContextMenu(contextMenu: UI.ContextMenu.ContextMenu): void {
2223
+ const copySubMenu = contextMenu.clipboardSection().appendSubMenuItem(i18nString(UIStrings.copyTableAs));
2224
+ copySubMenu.defaultSection().appendItem(i18nString(UIStrings.copyAsMarkdown), this.copyTableAsMarkdown.bind(this),
2225
+ {jslogContext: 'copy-as-markdown'});
2226
+ copySubMenu.defaultSection().appendItem(i18nString(UIStrings.copyAsCsv), this.copyTableAsCSV.bind(this),
2227
+ {jslogContext: 'copy-as-csv'});
2228
+ }
2229
+
2230
+ private copyTableAsMarkdown(): void {
2231
+ if (!this.dataGrid) {
2232
+ return;
2233
+ }
2234
+ const markdown = DataGrid.DataGridExporter.exportToMarkdown(this.dataGrid);
2235
+ UI.UIUtils.copyTextToClipboard(markdown);
2236
+ }
2237
+
2238
+ private copyTableAsCSV(): void {
2239
+ if (!this.dataGrid) {
2240
+ return;
2241
+ }
2242
+ const csv = DataGrid.DataGridExporter.exportToCSV(this.dataGrid);
2243
+ UI.UIUtils.copyTextToClipboard(csv);
2244
+ }
2245
+
2246
+ getDataGridForTest(): DataGrid.SortableDataGrid.SortableDataGrid<unknown>|null {
2247
+ return this.dataGrid;
2248
+ }
2249
+
2250
+ populateTableContextMenuForTest(contextMenu: UI.ContextMenu.ContextMenu): void {
2251
+ this.populateTableContextMenu(contextMenu);
2252
+ }
2208
2253
  }
2209
2254
 
2210
2255
  /**
@@ -40,7 +40,6 @@ import * as Platform from '../../core/platform/platform.js';
40
40
  import * as Root from '../../core/root/root.js';
41
41
  import * as SDK from '../../core/sdk/sdk.js';
42
42
  import type * as Protocol from '../../generated/protocol.js';
43
- import * as Annotations from '../../models/annotations/annotations.js';
44
43
  import * as ComputedStyle from '../../models/computed_style/computed_style.js';
45
44
  import * as PanelCommon from '../../panels/common/common.js';
46
45
  import type * as Adorners from '../../ui/components/adorners/adorners.js';
@@ -215,13 +214,25 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
215
214
  private cssStyleTrackerByCSSModel: Map<SDK.CSSModel.CSSModel, SDK.CSSModel.CSSPropertyTracker>;
216
215
  #domTreeWidget: DOMTreeWidget;
217
216
  #computedStyleModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel;
217
+ readonly #targetManager: SDK.TargetManager.TargetManager;
218
+ readonly #settings: Common.Settings.Settings;
219
+
220
+ get settings(): Common.Settings.Settings {
221
+ return this.#settings;
222
+ }
223
+
224
+ get targetManager(): SDK.TargetManager.TargetManager {
225
+ return this.#targetManager;
226
+ }
218
227
 
219
228
  getTreeOutlineForTesting(): ElementsTreeOutline|undefined {
220
229
  return this.#domTreeWidget.getTreeOutlineForTesting();
221
230
  }
222
231
 
223
- constructor() {
232
+ constructor(targetManager?: SDK.TargetManager.TargetManager, settings?: Common.Settings.Settings) {
224
233
  super('elements');
234
+ this.#targetManager = targetManager ?? SDK.TargetManager.TargetManager.instance();
235
+ this.#settings = settings ?? Common.Settings.Settings.instance();
225
236
  this.registerRequiredCSS(elementsPanelStyles);
226
237
 
227
238
  this.splitWidget = new UI.SplitWidget.SplitWidget(true, true, 'elements-panel-split-view-state', 325, 325);
@@ -252,12 +263,10 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
252
263
  this.domTreeContainer.id = 'elements-content';
253
264
  this.domTreeContainer.tabIndex = -1;
254
265
  // FIXME: crbug.com/425984
255
- if (Common.Settings.Settings.instance().moduleSetting('dom-word-wrap').get()) {
266
+ if (this.#settings.moduleSetting('dom-word-wrap').get()) {
256
267
  this.domTreeContainer.classList.add('elements-wrap');
257
268
  }
258
- Common.Settings.Settings.instance()
259
- .moduleSetting('dom-word-wrap')
260
- .addChangeListener(this.domWordWrapSettingChanged.bind(this));
269
+ this.#settings.moduleSetting('dom-word-wrap').addChangeListener(this.domWordWrapSettingChanged.bind(this));
261
270
 
262
271
  crumbsContainer.id = 'elements-crumbs';
263
272
  this.accessibilityTreeView = new AccessibilityTreeView(new TreeOutline.TreeOutline.TreeOutline<AXTreeNodeData>());
@@ -287,9 +296,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
287
296
 
288
297
  this.metricsWidget = new MetricsSidebarPane(this.#computedStyleModel);
289
298
 
290
- Common.Settings.Settings.instance()
291
- .moduleSetting('sidebar-position')
292
- .addChangeListener(this.updateSidebarPosition.bind(this));
299
+ this.#settings.moduleSetting('sidebar-position').addChangeListener(this.updateSidebarPosition.bind(this));
293
300
  this.updateSidebarPosition();
294
301
 
295
302
  this.cssStyleTrackerByCSSModel = new Map();
@@ -297,8 +304,8 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
297
304
 
298
305
  this.pendingNodeReveal = false;
299
306
 
300
- this.adornerManager = new ElementsComponents.AdornerManager.AdornerManager(
301
- Common.Settings.Settings.instance().moduleSetting('adorner-settings'));
307
+ this.adornerManager =
308
+ new ElementsComponents.AdornerManager.AdornerManager(this.#settings.moduleSetting('adorner-settings'));
302
309
  this.adornersByName = new Map();
303
310
 
304
311
  this.#domTreeWidget = new DOMTreeWidget();
@@ -307,23 +314,14 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
307
314
  this.#domTreeWidget.onSelectedNodeChanged = this.selectedNodeChanged.bind(this);
308
315
  this.#domTreeWidget.onElementsTreeUpdated = this.updateBreadcrumbIfNeeded.bind(this);
309
316
  this.#domTreeWidget.onDocumentUpdated = this.documentUpdated.bind(this);
310
- this.#domTreeWidget.onElementExpanded = this.handleElementExpanded.bind(this);
311
- this.#domTreeWidget.onElementCollapsed = this.handleElementCollapsed.bind(this);
312
- this.#domTreeWidget.setWordWrap(Common.Settings.Settings.instance().moduleSetting('dom-word-wrap').get());
313
-
314
- SDK.TargetManager.TargetManager.instance().observeModels(SDK.DOMModel.DOMModel, this, {scoped: true});
315
- SDK.TargetManager.TargetManager.instance().addEventListener(
316
- SDK.TargetManager.Events.NAME_CHANGED, event => this.targetNameChanged(event.data));
317
- Common.Settings.Settings.instance()
318
- .moduleSetting('show-ua-shadow-dom')
319
- .addChangeListener(this.showUAShadowDOMChanged.bind(this));
317
+ this.#domTreeWidget.setWordWrap(this.#settings.moduleSetting('dom-word-wrap').get());
318
+
319
+ this.#targetManager.observeModels(SDK.DOMModel.DOMModel, this, {scoped: true});
320
+ this.#targetManager.addEventListener(SDK.TargetManager.Events.NAME_CHANGED,
321
+ event => this.targetNameChanged(event.data));
322
+ this.#settings.moduleSetting('show-ua-shadow-dom').addChangeListener(this.showUAShadowDOMChanged.bind(this));
320
323
  PanelCommon.ExtensionServer.ExtensionServer.instance().addEventListener(
321
324
  PanelCommon.ExtensionServer.Events.SidebarPaneAdded, this.extensionSidebarPaneAdded, this);
322
-
323
- if (Annotations.AnnotationRepository.annotationsEnabled()) {
324
- PanelCommon.AnnotationManager.instance().initializePlacementForAnnotationType(
325
- Annotations.AnnotationType.ELEMENT_NODE, this.resolveInitialState.bind(this), this.#domTreeWidget.element);
326
- }
327
325
  }
328
326
 
329
327
  // This is a debounced method because the user might be navigated from Styles tab to Computed Style tab and vice versa.
@@ -353,18 +351,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
353
351
  }
354
352
  }
355
353
 
356
- private handleElementExpanded(): void {
357
- if (Annotations.AnnotationRepository.annotationsEnabled()) {
358
- void PanelCommon.AnnotationManager.instance().resolveAnnotationsOfType(Annotations.AnnotationType.ELEMENT_NODE);
359
- }
360
- }
361
-
362
- private handleElementCollapsed(): void {
363
- if (Annotations.AnnotationRepository.annotationsEnabled()) {
364
- void PanelCommon.AnnotationManager.instance().resolveAnnotationsOfType(Annotations.AnnotationType.ELEMENT_NODE);
365
- }
366
- }
367
-
368
354
  private showAccessibilityTree(): void {
369
355
  if (this.accessibilityTreeView) {
370
356
  this.splitWidget.setMainWidget(this.accessibilityTreeView);
@@ -398,10 +384,12 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
398
384
 
399
385
  static instance(opts: {
400
386
  forceNew: boolean|null,
387
+ targetManager?: SDK.TargetManager.TargetManager,
388
+ settings?: Common.Settings.Settings,
401
389
  }|undefined = {forceNew: null}): ElementsPanel {
402
- const {forceNew} = opts;
390
+ const {forceNew, targetManager, settings} = opts || {};
403
391
  if (!elementsPanelInstance || forceNew) {
404
- elementsPanelInstance = new ElementsPanel();
392
+ elementsPanelInstance = new ElementsPanel(targetManager, settings);
405
393
  }
406
394
 
407
395
  return elementsPanelInstance;
@@ -511,10 +499,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
511
499
  UI.Context.Context.instance().setFlavor(ElementsPanel, this);
512
500
  this.#domTreeWidget.show(this.domTreeContainer);
513
501
  this.evaluateTrackingComputedStyleUpdatesForNode();
514
-
515
- if (Annotations.AnnotationRepository.annotationsEnabled()) {
516
- void PanelCommon.AnnotationManager.instance().resolveAnnotationsOfType(Annotations.AnnotationType.ELEMENT_NODE);
517
- }
518
502
  }
519
503
 
520
504
  override willHide(): void {
@@ -758,7 +742,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
758
742
  this.currentSearchResultIndex = -1;
759
743
  delete this.searchResults;
760
744
 
761
- SDK.DOMModel.DOMModel.cancelSearch();
745
+ SDK.DOMModel.DOMModel.cancelSearch(this.#targetManager);
762
746
  }
763
747
 
764
748
  performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards?: boolean): void {
@@ -777,8 +761,8 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
777
761
 
778
762
  this.searchConfig = searchConfig;
779
763
 
780
- const showUAShadowDOM = Common.Settings.Settings.instance().moduleSetting('show-ua-shadow-dom').get();
781
- const domModels = SDK.TargetManager.TargetManager.instance().models(SDK.DOMModel.DOMModel, {scoped: true});
764
+ const showUAShadowDOM = this.#settings.moduleSetting('show-ua-shadow-dom').get();
765
+ const domModels = this.#targetManager.models(SDK.DOMModel.DOMModel, {scoped: true});
782
766
  const promises = domModels.map(domModel => domModel.performSearch(whitespaceTrimmedQuery, showUAShadowDOM));
783
767
  void Promise.all(promises).then(resultCounts => {
784
768
  this.searchResults = [];
@@ -976,9 +960,8 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
976
960
  const {showPanel = true, focusNode = false, highlightInOverlay = true} = opts ?? {};
977
961
  this.omitDefaultSelection = true;
978
962
 
979
- const node = Common.Settings.Settings.instance().moduleSetting('show-ua-shadow-dom').get() ?
980
- nodeToReveal :
981
- this.leaveUserAgentShadowDOM(nodeToReveal);
963
+ const node = this.#settings.moduleSetting('show-ua-shadow-dom').get() ? nodeToReveal :
964
+ this.leaveUserAgentShadowDOM(nodeToReveal);
982
965
  if (highlightInOverlay) {
983
966
  node.highlightForTwoSeconds();
984
967
  }
@@ -1191,7 +1174,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
1191
1174
  return;
1192
1175
  } // We can't reparent extension iframes.
1193
1176
 
1194
- const position = Common.Settings.Settings.instance().moduleSetting('sidebar-position').get();
1177
+ const position = this.#settings.moduleSetting('sidebar-position').get();
1195
1178
  let splitMode = SplitMode.HORIZONTAL;
1196
1179
  if (position === 'right' || (position === 'auto' && this.splitWidget.element.offsetWidth > 680)) {
1197
1180
  splitMode = SplitMode.VERTICAL;
@@ -1321,56 +1304,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
1321
1304
  this.#domTreeWidget.copyStyles(node);
1322
1305
  }
1323
1306
 
1324
- async resolveInitialState(
1325
- parentElement: Element, reveal: boolean, lookupId: string,
1326
- anchor?: SDK.DOMModel.DOMNode|SDK.NetworkRequest.NetworkRequest): Promise<{x: number, y: number}|null> {
1327
- if (!this.isShowing()) {
1328
- return null;
1329
- }
1330
-
1331
- if (!anchor) {
1332
- const backendNodeId = Number(lookupId) as Protocol.DOM.BackendNodeId;
1333
- if (isNaN(backendNodeId)) {
1334
- return null;
1335
- }
1336
- const rootDOMNode = this.#domTreeWidget.rootDOMNode;
1337
- if (!rootDOMNode) {
1338
- return null;
1339
- }
1340
- const domModel = rootDOMNode.domModel();
1341
- const nodes = await domModel.pushNodesByBackendIdsToFrontend(new Set([backendNodeId]));
1342
- if (!nodes) {
1343
- return null;
1344
- }
1345
- const foundNode = nodes.get(backendNodeId);
1346
- if (!foundNode) {
1347
- return null;
1348
- }
1349
- anchor = foundNode;
1350
- }
1351
-
1352
- const element = this.#domTreeWidget.treeElementForNode(anchor as SDK.DOMModel.DOMNode);
1353
- if (!element) {
1354
- return null;
1355
- }
1356
-
1357
- if (reveal) {
1358
- // The node must have been revealed in order to calculate its position.
1359
- await Common.Revealer.reveal(anchor);
1360
- }
1361
-
1362
- // The tree element element starts at the top-left of the expand/collapse arrow). We
1363
- // want to aim for the tagname instead.
1364
- const offsetToTagName = 22;
1365
- const yPadding = 5;
1366
-
1367
- const targetRect = element.listItemElement.getBoundingClientRect();
1368
- const parentRect = parentElement.getBoundingClientRect();
1369
- const relativeX = targetRect.x - parentRect.x + offsetToTagName;
1370
- const relativeY = targetRect.y - parentRect.y + yPadding;
1371
- return {x: relativeX, y: relativeY};
1372
- }
1373
-
1374
1307
  protected static firstInspectElementCompletedForTest = function(): void {};
1375
1308
  protected static firstInspectElementNodeNameForTest = '';
1376
1309
  }
@@ -1582,7 +1515,7 @@ export class ElementsActionDelegate implements UI.ActionRegistration.ActionDeleg
1582
1515
  ElementsPanel.instance().toggleAccessibilityTree();
1583
1516
  return true;
1584
1517
  case 'elements.toggle-word-wrap': {
1585
- const setting = Common.Settings.Settings.instance().moduleSetting<boolean>('dom-word-wrap');
1518
+ const setting = ElementsPanel.instance().settings.moduleSetting<boolean>('dom-word-wrap');
1586
1519
  setting.set(!setting.get());
1587
1520
  return true;
1588
1521
  }
@@ -235,8 +235,6 @@ export class DOMTreeWidget extends UI.Widget.Widget {
235
235
  Common.EventTarget.EventTargetEvent<{node: SDK.DOMModel.DOMNode | null, focus: boolean}>) => void = () => {};
236
236
  onElementsTreeUpdated: (event: Common.EventTarget.EventTargetEvent<SDK.DOMModel.DOMNode[]>) => void = () => {};
237
237
  onDocumentUpdated: (domModel: SDK.DOMModel.DOMModel) => void = () => {};
238
- onElementExpanded: () => void = () => {};
239
- onElementCollapsed: () => void = () => {};
240
238
 
241
239
  #maxTreeDepth?: number;
242
240
  #enableContextMenu = true;
@@ -455,11 +453,9 @@ export class DOMTreeWidget extends UI.Widget.Widget {
455
453
  },
456
454
  onElementCollapsed: () => {
457
455
  this.#clearHighlightedNode();
458
- this.onElementCollapsed();
459
456
  },
460
457
  onElementExpanded: () => {
461
458
  this.#clearHighlightedNode();
462
- this.onElementExpanded();
463
459
  },
464
460
  },
465
461
  this.#viewOutput, this.contentElement);
@@ -186,9 +186,10 @@ UI.ViewManager.registerViewExtension({
186
186
  order: 10,
187
187
  persistence: UI.ViewManager.ViewPersistence.PERMANENT,
188
188
  hasToolbar: false,
189
- async loadView() {
189
+ async loadView(universe) {
190
190
  const Elements = await loadElementsModule();
191
- return Elements.ElementsPanel.ElementsPanel.instance();
191
+ const {targetManager, settings} = universe;
192
+ return Elements.ElementsPanel.ElementsPanel.instance({forceNew: null, targetManager, settings});
192
193
  },
193
194
  });
194
195