chrome-devtools-frontend 1.0.1656291 → 1.0.1657110

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 (63) hide show
  1. package/AUTHORS +2 -0
  2. package/docs/get_the_code.md +6 -6
  3. package/front_end/Tests.js +1 -1
  4. package/front_end/core/common/Settings.ts +0 -8
  5. package/front_end/core/host/Platform.ts +4 -0
  6. package/front_end/core/sdk/CSSMetadata.ts +11 -0
  7. package/front_end/core/sdk/CSSModel.ts +3 -0
  8. package/front_end/core/sdk/DOMModel.ts +44 -13
  9. package/front_end/core/sdk/DebuggerModel.ts +5 -4
  10. package/front_end/core/sdk/EmulationModel.ts +6 -4
  11. package/front_end/core/sdk/NetworkManager.ts +21 -14
  12. package/front_end/core/sdk/RuntimeModel.ts +1 -1
  13. package/front_end/core/sdk/SourceMapCache.ts +2 -4
  14. package/front_end/core/sdk/SourceMapManager.ts +8 -7
  15. package/front_end/core/sdk/TargetManager.ts +10 -0
  16. package/front_end/design_system_tokens.css +6 -0
  17. package/front_end/entrypoints/inspector_main/InspectorMain.ts +1 -11
  18. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +1 -1
  19. package/front_end/entrypoints/main/GlobalAiButton.ts +29 -35
  20. package/front_end/entrypoints/main/MainImpl.ts +1 -1
  21. package/front_end/entrypoints/main/SimpleApp.ts +0 -13
  22. package/front_end/entrypoints/main/main-meta.ts +2 -2
  23. package/front_end/entrypoints/node_app/app/NodeConnectionsPanel.ts +2 -3
  24. package/front_end/foundation/Universe.ts +44 -0
  25. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  26. package/front_end/generated/protocol.ts +5 -5
  27. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +2 -1
  28. package/front_end/models/crux-manager/CrUXManager.ts +16 -11
  29. package/front_end/models/emulation/DeviceModeModel.ts +43 -24
  30. package/front_end/models/live-metrics/LiveMetrics.ts +47 -23
  31. package/front_end/models/project_settings/ProjectSettingsModel.ts +2 -37
  32. package/front_end/models/workspace/FileManager.ts +9 -6
  33. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -1
  34. package/front_end/panels/application/ServiceWorkersView.ts +177 -163
  35. package/front_end/panels/application/components/StorageMetadataView.ts +7 -2
  36. package/front_end/panels/application/serviceWorkersView.css +8 -0
  37. package/front_end/panels/common/BadgeNotification.ts +1 -1
  38. package/front_end/panels/console/ConsoleInsightTeaser.ts +2 -1
  39. package/front_end/panels/elements/ElementsPanel.ts +35 -28
  40. package/front_end/panels/elements/ElementsTreeElement.ts +208 -143
  41. package/front_end/panels/elements/ElementsTreeOutline.ts +3 -2
  42. package/front_end/panels/elements/components/AdornerManager.ts +1 -0
  43. package/front_end/panels/elements/elements-meta.ts +3 -2
  44. package/front_end/panels/emulation/DeviceModeToolbar.ts +19 -19
  45. package/front_end/panels/explain/components/ConsoleInsight.ts +2 -1
  46. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +13 -12
  47. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +8 -7
  48. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +6 -7
  49. package/front_end/panels/mobile_throttling/mobile_throttling-meta.ts +3 -2
  50. package/front_end/panels/settings/components/SyncSection.ts +2 -1
  51. package/front_end/panels/timeline/AppenderUtils.ts +12 -4
  52. package/front_end/panels/timeline/ThreadAppender.ts +3 -3
  53. package/front_end/panels/timeline/TimelinePanel.ts +5 -5
  54. package/front_end/panels/timeline/timelineFlameChartView.css +2 -1
  55. package/front_end/third_party/chromium/README.chromium +1 -1
  56. package/front_end/third_party/chromium/ahem/ahem.js +792 -0
  57. package/front_end/tsconfig.json +7 -1
  58. package/front_end/ui/legacy/ActionRegistration.ts +1 -1
  59. package/front_end/ui/legacy/InspectorView.ts +1 -1
  60. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +109 -23
  61. package/front_end/ui/legacy/theme_support/ThemeSupport.ts +2 -2
  62. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  63. package/package.json +1 -1
@@ -29,6 +29,12 @@
29
29
  ],
30
30
  "types": ["mocha"]
31
31
  },
32
- "exclude": ["devtools_compatibility.js"],
32
+ "exclude": [
33
+ "devtools_compatibility.js",
34
+ "Images/generate-css-vars.js",
35
+ "core/i18n/collect-ui-strings.js",
36
+ "core/i18n/generate-locales-js.js",
37
+ "panels/timeline/enable-easter-egg.js"
38
+ ],
33
39
  "references": [{ "path": "./tsconfig.compatibility.json" }]
34
40
  }
@@ -262,7 +262,7 @@ export function getRegisteredActionExtensions(): Action[] {
262
262
  .filter(action => {
263
263
  const settingName = action.setting();
264
264
  try {
265
- if (settingName && !Common.Settings.moduleSetting(settingName).get()) {
265
+ if (settingName && !Common.Settings.Settings.instance().moduleSetting(settingName).get()) {
266
266
  return false;
267
267
  }
268
268
  } catch (err) {
@@ -679,7 +679,7 @@ export class InspectorView extends VBox implements ViewLocationResolver {
679
679
  }
680
680
 
681
681
  // Ctrl/Cmd + 1-9 should show corresponding panel.
682
- const panelShortcutEnabled = Common.Settings.moduleSetting('shortcut-panel-switch').get();
682
+ const panelShortcutEnabled = Common.Settings.Settings.instance().moduleSetting('shortcut-panel-switch').get();
683
683
  if (panelShortcutEnabled) {
684
684
  let panelIndex = -1;
685
685
  if (event.keyCode > 0x30 && event.keyCode < 0x3A) {
@@ -5,6 +5,7 @@
5
5
  /* eslint-disable @devtools/no-imperative-dom-api */
6
6
 
7
7
  import * as Common from '../../../../core/common/common.js';
8
+ import * as Host from '../../../../core/host/host.js';
8
9
  import * as i18n from '../../../../core/i18n/i18n.js';
9
10
  import * as Platform from '../../../../core/platform/platform.js';
10
11
  import type * as NetworkTimeCalculator from '../../../../models/network_time_calculator/network_time_calculator.js';
@@ -80,6 +81,14 @@ const UIStrings = {
80
81
  * @description Shown in the context menu when right clicking on a track header to allow the user to exit track configuration mode.
81
82
  */
82
83
  exitTrackConfigurationMode: 'Finish configuring tracks',
84
+ /**
85
+ * @description Context menu option to copy the name of the track.
86
+ */
87
+ copyTrackName: 'Copy track name',
88
+ /**
89
+ * @description Context menu option to copy the URL of the track.
90
+ */
91
+ copyTrackUrl: 'Copy track URL',
83
92
  } as const;
84
93
  const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/perf_ui/FlameChart.ts', UIStrings);
85
94
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -314,6 +323,18 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
314
323
 
315
324
  #indexToDrawOverride = new Map<number, DrawOverride>();
316
325
  #persistedGroupConfig: PersistedGroupConfig[]|null = null;
326
+ /**
327
+ * Caches the middle-truncated display names of track header labels to avoid recalculating
328
+ * truncation during draw operations. The cache is invalidated when the panel is resized,
329
+ * when track configuration edit mode is toggled, or when the trace data is reset.
330
+ *
331
+ * The `names` map uses the static `groupIndex` (which is invariant to track reordering)
332
+ * as the key, and maps it to the truncated string drawn on the canvas.
333
+ */
334
+ #urlTruncations = {
335
+ names: new Map<number, string>(),
336
+ lastWidth: 0,
337
+ };
317
338
  readonly #boundOnThemeChanged = this.#onThemeChanged.bind(this);
318
339
 
319
340
  constructor(
@@ -925,8 +946,16 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
925
946
  return;
926
947
  }
927
948
  const group = data.groups.at(groupIndex);
928
- if (group?.description) {
929
- this.popoverElement.innerText = (group?.description);
949
+ if (!group) {
950
+ return;
951
+ }
952
+ // Only show a popover tooltip if the group has a pre-defined `fullTrackName`
953
+ // (e.g. main thread tracks that are named after their URL, which are middle-truncated on the canvas).
954
+ // All other tracks have short, static titles that fit without truncation and do not need a tooltip.
955
+ const fullTrackName = group.fullTrackName;
956
+
957
+ if (fullTrackName) {
958
+ this.popoverElement.innerText = fullTrackName;
930
959
  this.updatePopoverOffset();
931
960
  }
932
961
  this.lastPopoverState = {
@@ -1411,32 +1440,56 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
1411
1440
  this.update();
1412
1441
  }
1413
1442
 
1414
- #buildEnterEditModeContextMenu(event: MouseEvent): void {
1415
- if (this.#inTrackConfigEditMode) {
1443
+ #buildExitEditModeContextMenu(event: MouseEvent): void {
1444
+ if (this.#inTrackConfigEditMode === false) {
1416
1445
  return;
1417
1446
  }
1418
-
1419
1447
  this.contextMenu = new UI.ContextMenu.ContextMenu(event);
1420
- const label = i18nString(UIStrings.enterTrackConfigurationMode);
1448
+ const label = i18nString(UIStrings.exitTrackConfigurationMode);
1421
1449
  this.contextMenu.defaultSection().appendItem(label, () => {
1422
- this.enterTrackConfigurationMode();
1450
+ this.#exitEditMode();
1423
1451
  }, {
1424
- jslogContext: 'track-configuration-enter',
1452
+ jslogContext: 'track-configuration-exit',
1425
1453
  });
1426
1454
  void this.contextMenu.show();
1427
1455
  }
1428
1456
 
1429
- #buildExitEditModeContextMenu(event: MouseEvent): void {
1430
- if (this.#inTrackConfigEditMode === false) {
1457
+ #buildTrackHeaderContextMenu(event: MouseEvent, groupIndex: number): void {
1458
+ const data = this.timelineData();
1459
+ if (!data) {
1431
1460
  return;
1432
1461
  }
1462
+ const group = data.groups.at(groupIndex);
1463
+ if (!group) {
1464
+ return;
1465
+ }
1466
+
1433
1467
  this.contextMenu = new UI.ContextMenu.ContextMenu(event);
1434
- const label = i18nString(UIStrings.exitTrackConfigurationMode);
1435
- this.contextMenu.defaultSection().appendItem(label, () => {
1436
- this.#exitEditMode();
1468
+
1469
+ this.contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyTrackName), () => {
1470
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(group.name);
1437
1471
  }, {
1438
- jslogContext: 'track-configuration-exit',
1472
+ jslogContext: 'timeline.copy-track-name',
1439
1473
  });
1474
+
1475
+ if (group.url) {
1476
+ this.contextMenu.defaultSection().appendItem(i18nString(UIStrings.copyTrackUrl), () => {
1477
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(group.url);
1478
+ }, {
1479
+ jslogContext: 'timeline.copy-track-url',
1480
+ });
1481
+ }
1482
+
1483
+ if (this.#hasTrackConfigurationMode()) {
1484
+ this.contextMenu.defaultSection().appendSeparator();
1485
+ const label = i18nString(UIStrings.enterTrackConfigurationMode);
1486
+ this.contextMenu.defaultSection().appendItem(label, () => {
1487
+ this.enterTrackConfigurationMode();
1488
+ }, {
1489
+ jslogContext: 'track-configuration-enter',
1490
+ });
1491
+ }
1492
+
1440
1493
  void this.contextMenu.show();
1441
1494
  }
1442
1495
 
@@ -1461,8 +1514,9 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
1461
1514
  // extra check. For example, in the DevTools Performance Panel the network
1462
1515
  // data provider & flame chart does not support this mode, but the main one
1463
1516
  // does.
1464
- if (hoverType === HoverType.INSIDE_TRACK_HEADER && this.#hasTrackConfigurationMode()) {
1465
- this.#buildEnterEditModeContextMenu(event);
1517
+ if (hoverType === HoverType.INSIDE_TRACK_HEADER) {
1518
+ this.#buildTrackHeaderContextMenu(event, groupIndex);
1519
+ return;
1466
1520
  }
1467
1521
 
1468
1522
  // The user can create context menus in two ways:
@@ -2162,6 +2216,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
2162
2216
  if (!this.#hasTrackConfigurationMode()) {
2163
2217
  return;
2164
2218
  }
2219
+ this.#urlTruncations.names.clear();
2165
2220
  const div = document.createElement('div');
2166
2221
  div.classList.add('flame-chart-edit-confirm');
2167
2222
  const button = new Buttons.Button.Button();
@@ -2195,6 +2250,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
2195
2250
  }
2196
2251
 
2197
2252
  #exitEditMode(): void {
2253
+ this.#urlTruncations.names.clear();
2198
2254
  this.#removeEditModeButton();
2199
2255
  this.#inTrackConfigEditMode = false;
2200
2256
  this.dispatchEventToListeners(Events.TRACKS_REORDER_STATE_CHANGED, false);
@@ -2694,6 +2750,11 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
2694
2750
  return;
2695
2751
  }
2696
2752
 
2753
+ if (width !== this.#urlTruncations.lastWidth) {
2754
+ this.#urlTruncations.names.clear();
2755
+ this.#urlTruncations.lastWidth = width;
2756
+ }
2757
+
2697
2758
  const groups = this.rawTimelineData.groups || [];
2698
2759
  if (!groups.length) {
2699
2760
  return;
@@ -2787,20 +2848,35 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
2787
2848
  // |ICON_WIDTH|expansionArrowIndent * (nesting level + 1)|
2788
2849
  // |headerLeftPadding|EDIT ICON| |Arrow|LabelXPadding|Title|LabelXPadding|
2789
2850
  // ^ titleStart
2790
- const titleStart = iconsWidth + EXPANSION_ARROW_INDENT * (group.style.nestingLevel + 1) + ARROW_SIDE / 2 +
2791
- HEADER_LABEL_X_PADDING;
2851
+ const nestingLevel = group.style.nestingLevel || 0;
2852
+ const titleStart =
2853
+ iconsWidth + EXPANSION_ARROW_INDENT * (nestingLevel + 1) + ARROW_SIDE / 2 + HEADER_LABEL_X_PADDING;
2792
2854
  const y = offset + group.style.height - this.textBaseline;
2793
- context.fillText(group.name, titleStart, y);
2855
+ let displayName = this.#urlTruncations.names.get(groupIndex);
2856
+ if (displayName === undefined) {
2857
+ displayName = group.name;
2858
+ // Calculate the maximum width available for the text. We subtract the X coordinate where the text starts
2859
+ // (titleStart) and the padding at the end of the line (HEADER_LABEL_X_PADDING) from the total width of the canvas.
2860
+ // We then apply a 0.85 (85%) factor as a safety margin to prevent the text from running too close to the edge of
2861
+ // the canvas or overlapping other potential visual elements on the right.
2862
+ const maxTextWidth = (width - titleStart - HEADER_LABEL_X_PADDING) * 0.85;
2863
+ if (context.measureText(displayName).width > maxTextWidth) {
2864
+ displayName = UI.UIUtils.trimTextMiddle(context, displayName, maxTextWidth);
2865
+ }
2866
+ this.#urlTruncations.names.set(groupIndex, displayName);
2867
+ }
2868
+
2869
+ context.fillText(displayName, titleStart, y);
2794
2870
  if (group.subtitle) {
2795
- const titleMetrics = context.measureText(group.name);
2871
+ const titleMetrics = context.measureText(displayName);
2796
2872
  context.font = this.#subtitleFont;
2797
2873
  context.fillText(group.subtitle, titleStart + titleMetrics.width + PADDING_BETWEEN_TITLE_AND_SUBTITLE, y - 1);
2798
2874
  context.font = this.#font;
2799
2875
  }
2800
2876
  if (this.#inTrackConfigEditMode && group.hidden) {
2801
2877
  // Draw a strikethrough line for the hidden tracks.
2802
- context.fillRect(
2803
- titleStart, offset + group.style.height / 2, UI.UIUtils.measureTextWidth(context, group.name), 1);
2878
+ context.fillRect(titleStart, offset + group.style.height / 2, UI.UIUtils.measureTextWidth(context, displayName),
2879
+ 1);
2804
2880
  }
2805
2881
 
2806
2882
  // The icon and track title will look like this
@@ -3406,6 +3482,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
3406
3482
  }
3407
3483
 
3408
3484
  private processTimelineData(timelineData: FlameChartTimelineData|null): void {
3485
+ this.#urlTruncations.names.clear();
3409
3486
  if (!timelineData) {
3410
3487
  this.timelineLevels = null;
3411
3488
  this.visibleLevelOffsets = null;
@@ -3999,6 +4076,10 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
3999
4076
  this.#inTrackConfigEditMode = editMode;
4000
4077
  }
4001
4078
 
4079
+ getPopoverElementForTest(): HTMLElement {
4080
+ return this.popoverElement;
4081
+ }
4082
+
4002
4083
  /**
4003
4084
  * Returns the visibility of a level in the.
4004
4085
  * flame chart.
@@ -4079,6 +4160,8 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
4079
4160
  this.#removeEditModeButton();
4080
4161
  this.#inTrackConfigEditMode = false;
4081
4162
  }
4163
+ this.#urlTruncations.names.clear();
4164
+ this.#urlTruncations.lastWidth = 0;
4082
4165
 
4083
4166
  this.chartViewport.reset();
4084
4167
  this.rawTimelineData = null;
@@ -4448,7 +4531,10 @@ export interface Group {
4448
4531
  /** Should be turned on if the track supports user editable stacks. */
4449
4532
  showStackContextMenu?: boolean;
4450
4533
  jslogContext?: string;
4451
- description?: string;
4534
+ /** A full, non-truncated description of the track (e.g. full title with URL) to be shown in the tooltip on hover. */
4535
+ fullTrackName?: string;
4536
+ /** The raw URL of the track, if applicable, used for right-click copy actions. */
4537
+ url?: string;
4452
4538
  }
4453
4539
 
4454
4540
  export interface GroupStyle {
@@ -159,7 +159,7 @@ export class ThemeSupport extends EventTarget {
159
159
  this.#themeName = useSystemPreferred ? systemPreferredTheme : this.setting.get();
160
160
  document.documentElement.classList.toggle('theme-with-dark-background', this.#themeName === 'dark');
161
161
 
162
- const useChromeTheme = Common.Settings.moduleSetting('chrome-theme-colors').get();
162
+ const useChromeTheme = Common.Settings.Settings.instance().moduleSetting('chrome-theme-colors').get();
163
163
  const isIncognito = Root.Runtime.hostConfig.isOffTheRecord === true;
164
164
  // Baseline is the name of Chrome's default color theme and there are two of these: default and grayscale.
165
165
  // The collective name for the rest of the color themes is dynamic.
@@ -191,7 +191,7 @@ export class ThemeSupport extends EventTarget {
191
191
  }
192
192
 
193
193
  #fetchColorsAndApplyHostTheme(document: Document): void {
194
- const useChromeTheme = Common.Settings.moduleSetting('chrome-theme-colors').get();
194
+ const useChromeTheme = Common.Settings.Settings.instance().moduleSetting('chrome-theme-colors').get();
195
195
  if (Host.InspectorFrontendHost.InspectorFrontendHostInstance.isHostedMode() || !useChromeTheme) {
196
196
  this.#applyThemeToDocument(document);
197
197
  return;
@@ -1257,6 +1257,7 @@ export const knownContextValues = new Set([
1257
1257
  'custom',
1258
1258
  'custom-accepted-encodings',
1259
1259
  'custom-color-palette',
1260
+ 'custom-element',
1260
1261
  'custom-emulated-device-list',
1261
1262
  'custom-formatters',
1262
1263
  'custom-header-for-test',
@@ -4136,6 +4137,8 @@ export const knownContextValues = new Set([
4136
4137
  'timeline.breadcrumb-select',
4137
4138
  'timeline.clear',
4138
4139
  'timeline.configure',
4140
+ 'timeline.copy-track-name',
4141
+ 'timeline.copy-track-url',
4139
4142
  'timeline.create-breadcrumb',
4140
4143
  'timeline.disable',
4141
4144
  'timeline.download-after-error',
package/package.json CHANGED
@@ -92,5 +92,5 @@
92
92
  "webidl2": "24.5.0",
93
93
  "yargs": "17.7.2"
94
94
  },
95
- "version": "1.0.1656291"
95
+ "version": "1.0.1657110"
96
96
  }