chrome-devtools-frontend 1.0.1602348 → 1.0.1603822

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 (105) hide show
  1. package/.agents/skills/version-control/SKILL.md +17 -2
  2. package/AUTHORS +1 -0
  3. package/front_end/core/common/Settings.ts +1 -871
  4. package/front_end/core/common/VersionController.ts +880 -0
  5. package/front_end/core/common/common.ts +2 -0
  6. package/front_end/core/platform/HostRuntime.ts +9 -3
  7. package/front_end/core/protocol_client/InspectorBackend.ts +8 -0
  8. package/front_end/core/root/Runtime.ts +5 -0
  9. package/front_end/core/sdk/OverlayModel.ts +13 -13
  10. package/front_end/core/sdk/OverlayPersistentHighlighter.ts +13 -10
  11. package/front_end/core/sdk/RuntimeModel.ts +5 -5
  12. package/front_end/core/sdk/ServiceWorkerManager.ts +4 -2
  13. package/front_end/core/sdk/Target.ts +5 -0
  14. package/front_end/core/sdk/TargetManager.ts +5 -0
  15. package/front_end/core/sdk/WebMCPModel.ts +104 -0
  16. package/front_end/core/sdk/sdk.ts +2 -0
  17. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +13 -19
  18. package/front_end/generated/InspectorBackendCommands.ts +3 -0
  19. package/front_end/generated/protocol-mapping.d.ts +8 -0
  20. package/front_end/generated/protocol-proxy-api.d.ts +10 -0
  21. package/front_end/generated/protocol.ts +57 -0
  22. package/front_end/models/ai_assistance/AiConversation.ts +3 -3
  23. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +50 -0
  24. package/front_end/models/ai_assistance/agents/AiAgent.ts +14 -1
  25. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +19 -4
  26. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +7 -1
  27. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +30 -7
  28. package/front_end/models/ai_assistance/agents/StylingAgent.ts +0 -23
  29. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +60 -9
  30. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +71 -15
  31. package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +7 -7
  32. package/front_end/models/javascript_metadata/NativeFunctions.js +6 -2
  33. package/front_end/models/lighthouse/LighthouseReporterTypes.ts +10 -8
  34. package/front_end/models/lighthouse/RunTypes.ts +3 -1
  35. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +13 -5
  36. package/front_end/panels/ai_assistance/components/ChatMessage.ts +143 -18
  37. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -10
  38. package/front_end/panels/ai_assistance/components/chatMessage.css +58 -3
  39. package/front_end/panels/ai_assistance/components/walkthroughView.css +35 -5
  40. package/front_end/panels/application/AppManifestView.ts +2 -2
  41. package/front_end/panels/application/BackgroundServiceView.ts +9 -9
  42. package/front_end/panels/application/FrameDetailsView.ts +4 -13
  43. package/front_end/panels/application/IndexedDBViews.ts +1 -1
  44. package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -3
  45. package/front_end/panels/application/components/PermissionsPolicySection.ts +1 -1
  46. package/front_end/panels/application/components/permissionsPolicySection.css +54 -52
  47. package/front_end/panels/application/frameDetailsReportView.css +13 -1
  48. package/front_end/panels/common/ThrottlingUtils.ts +46 -0
  49. package/front_end/panels/common/common.ts +1 -0
  50. package/front_end/panels/elements/CSSValueTraceView.ts +9 -1
  51. package/front_end/panels/elements/ComputedStyleWidget.ts +11 -1
  52. package/front_end/panels/elements/PropertiesWidget.ts +14 -13
  53. package/front_end/panels/elements/PropertyRenderer.ts +10 -9
  54. package/front_end/panels/elements/StandaloneStylesContainer.ts +15 -5
  55. package/front_end/panels/elements/StylePropertiesSection.ts +0 -49
  56. package/front_end/panels/elements/StylePropertyTreeElement.ts +20 -0
  57. package/front_end/panels/elements/StylesContainer.ts +0 -1
  58. package/front_end/panels/elements/StylesSidebarPane.ts +65 -31
  59. package/front_end/panels/elements/stylePropertiesTreeOutline.css +5 -0
  60. package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +2 -2
  61. package/front_end/panels/lighthouse/LighthouseController.ts +4 -1
  62. package/front_end/panels/media/EventDisplayTable.ts +3 -2
  63. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -0
  64. package/front_end/panels/network/EventSourceMessagesView.ts +2 -2
  65. package/front_end/panels/network/ResourceChunkView.ts +1 -1
  66. package/front_end/panels/profiler/HeapDetachedElementsView.ts +9 -4
  67. package/front_end/panels/profiler/HeapProfileView.ts +8 -4
  68. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +40 -33
  69. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +1 -1
  70. package/front_end/panels/profiler/HeapSnapshotProxy.ts +1 -1
  71. package/front_end/panels/profiler/HeapSnapshotView.ts +12 -18
  72. package/front_end/panels/profiler/LiveHeapProfileView.ts +3 -4
  73. package/front_end/panels/profiler/ProfileHeader.ts +5 -11
  74. package/front_end/panels/profiler/ProfileView.ts +1 -10
  75. package/front_end/panels/sensors/SensorsView.ts +24 -43
  76. package/front_end/panels/settings/keybindsSettingsTab.css +25 -31
  77. package/front_end/panels/timeline/EventsTimelineTreeView.ts +2 -2
  78. package/front_end/panels/timeline/ThirdPartyTreeView.ts +8 -0
  79. package/front_end/panels/timeline/TimelinePanel.ts +14 -2
  80. package/front_end/panels/timeline/TimelineTreeView.ts +19 -17
  81. package/front_end/panels/timeline/components/FieldSettingsDialog.ts +5 -9
  82. package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -2
  83. package/front_end/panels/timeline/components/OriginMap.ts +176 -159
  84. package/front_end/panels/timeline/components/originMap.css +4 -51
  85. package/front_end/panels/timeline/components/timelineRangeSummaryView.css +3 -1
  86. package/front_end/panels/timeline/thirdPartyTreeView.css +6 -0
  87. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  88. package/front_end/panels/timeline/utils/Helpers.ts +5 -25
  89. package/front_end/panels/webauthn/WebauthnPane.ts +52 -0
  90. package/front_end/third_party/acorn/README.chromium +1 -0
  91. package/front_end/third_party/chromium/README.chromium +1 -1
  92. package/front_end/ui/components/{list → lists}/List.ts +1 -1
  93. package/front_end/ui/components/{list → lists}/list.css +0 -1
  94. package/front_end/ui/legacy/Treeoutline.ts +7 -3
  95. package/front_end/ui/legacy/UIUtils.ts +13 -11
  96. package/front_end/ui/legacy/Widget.ts +5 -0
  97. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -1
  98. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
  99. package/front_end/ui/legacy/components/data_grid/SortableDataGrid.ts +2 -2
  100. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +39 -23
  101. package/front_end/ui/legacy/components/perf_ui/GCActionDelegate.ts +20 -4
  102. package/front_end/ui/legacy/treeoutline.css +4 -0
  103. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  104. package/package.json +1 -1
  105. /package/front_end/ui/components/{list → lists}/lists.ts +0 -0
@@ -964,8 +964,6 @@ export class HeapSnapshotView extends UI.View.SimpleView implements DataDisplayD
964
964
  }
965
965
  let objectPopoverHelper: ObjectUI.ObjectPopoverHelper.ObjectPopoverHelper|null;
966
966
  return {
967
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
968
- // @ts-expect-error
969
967
  box: span.boxInWindow(),
970
968
  show: async (popover: UI.GlassPane.GlassPane) => {
971
969
  if (!heapProfilerModel) {
@@ -1364,7 +1362,7 @@ export class HeapSnapshotProfileType extends
1364
1362
  return;
1365
1363
  }
1366
1364
 
1367
- let profile: HeapProfileHeader = new HeapProfileHeader(heapProfilerModel, this);
1365
+ let profile = new HeapProfileHeader(heapProfilerModel, this);
1368
1366
  this.setProfileBeingRecorded(profile);
1369
1367
  this.addProfile(profile);
1370
1368
  profile.updateStatus(i18nString(UIStrings.snapshotting));
@@ -1649,33 +1647,29 @@ export interface TrackingHeapSnapshotProfileTypeEventTypes {
1649
1647
 
1650
1648
  export class HeapProfileHeader extends ProfileHeader {
1651
1649
  readonly heapProfilerModelInternal: SDK.HeapProfilerModel.HeapProfilerModel|null;
1652
- maxJSObjectId: number;
1653
- workerProxy: HeapSnapshotWorkerProxy|null;
1654
- receiver: Common.StringOutputStream.OutputStream|null;
1655
- snapshotProxy: HeapSnapshotProxy|null;
1650
+ maxJSObjectId = -1;
1651
+ workerProxy: HeapSnapshotWorkerProxy|null = null;
1652
+ receiver: Common.StringOutputStream.OutputStream|null = null;
1653
+ snapshotProxy: HeapSnapshotProxy|null = null;
1656
1654
  readonly loadPromise: Promise<HeapSnapshotProxy>;
1657
1655
  fulfillLoad: (value: HeapSnapshotProxy|PromiseLike<HeapSnapshotProxy>) => void;
1658
- totalNumberOfChunks: number;
1659
- bufferedWriter: Bindings.TempFile.TempFile|null;
1660
- onTempFileReady: (() => void)|null;
1656
+ totalNumberOfChunks = 0;
1657
+ bufferedWriter: Bindings.TempFile.TempFile|null = null;
1658
+ onTempFileReady: (() => void)|null = null;
1661
1659
  failedToCreateTempFile?: boolean;
1662
1660
  wasDisposed?: boolean;
1663
1661
  fileName?: Platform.DevToolsPath.RawPathString;
1664
1662
 
1665
1663
  constructor(
1666
- heapProfilerModel: SDK.HeapProfilerModel.HeapProfilerModel|null, type: HeapSnapshotProfileType, title?: string) {
1664
+ heapProfilerModel: SDK.HeapProfilerModel.HeapProfilerModel|null,
1665
+ type: HeapSnapshotProfileType,
1666
+ title?: string,
1667
+ ) {
1667
1668
  super(type, title || i18nString(UIStrings.snapshotD, {PH1: type.nextProfileUid()}));
1668
1669
  this.heapProfilerModelInternal = heapProfilerModel;
1669
- this.maxJSObjectId = -1;
1670
- this.workerProxy = null;
1671
- this.receiver = null;
1672
- this.snapshotProxy = null;
1673
1670
  const {promise, resolve} = Promise.withResolvers<HeapSnapshotProxy>();
1674
1671
  this.loadPromise = promise;
1675
1672
  this.fulfillLoad = resolve;
1676
- this.totalNumberOfChunks = 0;
1677
- this.bufferedWriter = null;
1678
- this.onTempFileReady = null;
1679
1673
  }
1680
1674
 
1681
1675
  heapProfilerModel(): SDK.HeapProfilerModel.HeapProfilerModel|null {
@@ -103,15 +103,14 @@ export class LiveHeapProfileView extends UI.Widget.VBox {
103
103
  }
104
104
 
105
105
  createDataGrid(): DataGrid.SortableDataGrid.SortableDataGrid<GridNode> {
106
- const defaultColumnConfig: DataGrid.DataGrid.ColumnDescriptor = {
107
- id: '',
106
+ const defaultColumnConfig = {
108
107
  title: Common.UIString.LocalizedEmptyString,
109
108
  fixedWidth: true,
110
109
  sortable: true,
111
110
  align: DataGrid.DataGrid.Align.RIGHT,
112
111
  sort: DataGrid.DataGrid.Order.Descending,
113
112
  };
114
- const columns = [
113
+ const columns: Array<{tooltip: Common.UIString.LocalizedString}&DataGrid.DataGrid.ColumnDescriptor> = [
115
114
  {
116
115
  ...defaultColumnConfig,
117
116
  id: 'size',
@@ -140,7 +139,7 @@ export class LiveHeapProfileView extends UI.Widget.VBox {
140
139
  sortable: true,
141
140
  tooltip: i18nString(UIStrings.urlOfTheScriptSource),
142
141
  },
143
- ] as Array<{tooltip: Common.UIString.LocalizedString}&DataGrid.DataGrid.ColumnDescriptor>;
142
+ ];
144
143
  const dataGrid = new DataGrid.SortableDataGrid.SortableDataGrid({
145
144
  displayName: i18nString(UIStrings.heapProfile),
146
145
  columns,
@@ -11,17 +11,14 @@ export class ProfileHeader extends Common.ObjectWrapper.ObjectWrapper<EventTypes
11
11
  readonly #profileType: ProfileType;
12
12
  title: string;
13
13
  uid: number;
14
- #fromFile: boolean;
15
- tempFile: Bindings.TempFile.TempFile|null;
14
+ #fromFile = false;
15
+ tempFile: Bindings.TempFile.TempFile|null = null;
16
16
 
17
17
  constructor(profileType: ProfileType, title: string) {
18
18
  super();
19
19
  this.#profileType = profileType;
20
20
  this.title = title;
21
21
  this.uid = profileType.incrementProfileUid();
22
- this.#fromFile = false;
23
-
24
- this.tempFile = null;
25
22
  }
26
23
 
27
24
  setTitle(title: string): void {
@@ -103,17 +100,14 @@ export interface EventTypes {
103
100
  export class ProfileType extends Common.ObjectWrapper.ObjectWrapper<ProfileEventTypes> {
104
101
  readonly #id: string;
105
102
  readonly #name: string;
106
- profiles: ProfileHeader[];
107
- #profileBeingRecorded: ProfileHeader|null;
108
- #nextProfileUid: number;
103
+ profiles: ProfileHeader[] = [];
104
+ #profileBeingRecorded: ProfileHeader|null = null;
105
+ #nextProfileUid = 1;
109
106
 
110
107
  constructor(id: string, name: string) {
111
108
  super();
112
109
  this.#id = id;
113
110
  this.#name = name;
114
- this.profiles = [];
115
- this.#profileBeingRecorded = null;
116
- this.#nextProfileUid = 1;
117
111
 
118
112
  if (!window.opener) {
119
113
  window.addEventListener('pagehide', this.clearTempStorage.bind(this), false);
@@ -138,7 +138,7 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
138
138
  this.searchableViewInternal.setPlaceholder(i18nString(UIStrings.findByCostMsNameOrFile));
139
139
  this.searchableViewInternal.show(this.element);
140
140
 
141
- const columns = ([] as DataGrid.DataGrid.ColumnDescriptor[]);
141
+ const columns: DataGrid.DataGrid.ColumnDescriptor[] = [];
142
142
  columns.push({
143
143
  id: 'self',
144
144
  title: this.columnHeader('self'),
@@ -298,9 +298,6 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
298
298
  if (!this.profileDataGridTree) {
299
299
  return;
300
300
  }
301
- const selectedProfileNode =
302
- this.dataGrid.selectedNode ? (this.dataGrid.selectedNode as ProfileDataGridNode).profileNode : null;
303
-
304
301
  this.dataGrid.rootNode().removeChildren();
305
302
 
306
303
  const children = this.profileDataGridTree.children;
@@ -309,12 +306,6 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
309
306
  for (let index = 0; index < count; ++index) {
310
307
  this.dataGrid.rootNode().appendChild(children[index]);
311
308
  }
312
-
313
- if (selectedProfileNode) {
314
- // TODO(crbug.com/1011811): Cleanup the added `selected` property to this SDK class.
315
- // @ts-expect-error
316
- selectedProfileNode.selected = true;
317
- }
318
309
  }
319
310
 
320
311
  refreshVisibleData(): void {
@@ -660,10 +660,12 @@ export class SensorsView extends UI.Widget.VBox {
660
660
  <input
661
661
  id="alpha-input"
662
662
  type="number"
663
+ min="0"
664
+ max="359.9999"
663
665
  step="any"
666
+ required
664
667
  ${Directives.ref((el: Element | undefined) => { if (el) { this.alphaElement = el as HTMLInputElement; } })}
665
668
  @change=${this.#onOrientationChange.bind(this)}
666
- @input=${this.#onOrientationInput.bind(this)}
667
669
  @keydown=${this.#onOrientationKeyDown.bind(this)}
668
670
  @focus=${this.#onOrientationFocus.bind(this)}
669
671
  >
@@ -674,10 +676,12 @@ export class SensorsView extends UI.Widget.VBox {
674
676
  <input
675
677
  id="beta-input"
676
678
  type="number"
679
+ min="-180"
680
+ max="179.9999"
677
681
  step="any"
682
+ required
678
683
  ${Directives.ref((el: Element | undefined) => { if (el) { this.betaElement = el as HTMLInputElement; } })}
679
684
  @change=${this.#onOrientationChange.bind(this)}
680
- @input=${this.#onOrientationInput.bind(this)}
681
685
  @keydown=${this.#onOrientationKeyDown.bind(this)}
682
686
  @focus=${this.#onOrientationFocus.bind(this)}
683
687
  >
@@ -688,10 +692,12 @@ export class SensorsView extends UI.Widget.VBox {
688
692
  <input
689
693
  id="gamma-input"
690
694
  type="number"
695
+ min="-90"
696
+ max="89.9999"
691
697
  step="any"
698
+ required
692
699
  ${Directives.ref((el: Element | undefined) => { if (el) { this.gammaElement = el as HTMLInputElement; } })}
693
700
  @change=${this.#onOrientationChange.bind(this)}
694
- @input=${this.#onOrientationInput.bind(this)}
695
701
  @keydown=${this.#onOrientationKeyDown.bind(this)}
696
702
  @focus=${this.#onOrientationFocus.bind(this)}
697
703
  >
@@ -745,9 +751,9 @@ export class SensorsView extends UI.Widget.VBox {
745
751
  this.enableOrientationFields(true);
746
752
  this.setBoxOrientation(this.deviceOrientation, false);
747
753
 
748
- this.#setOrientationInputValue(this.alphaElement, String(this.deviceOrientation.alpha));
749
- this.#setOrientationInputValue(this.betaElement, String(this.deviceOrientation.beta));
750
- this.#setOrientationInputValue(this.gammaElement, String(this.deviceOrientation.gamma));
754
+ this.alphaElement.value = String(this.deviceOrientation.alpha);
755
+ this.betaElement.value = String(this.deviceOrientation.beta);
756
+ this.gammaElement.value = String(this.deviceOrientation.gamma);
751
757
  }
752
758
 
753
759
  private createPressureSection(): void {
@@ -837,9 +843,9 @@ export class SensorsView extends UI.Widget.VBox {
837
843
  // Even though the angles in |deviceOrientation| will not be rounded
838
844
  // here, their precision will be rounded by CSS when we change
839
845
  // |this.orientationLayer.style| in setBoxOrientation().
840
- this.#setOrientationInputValue(this.alphaElement, String(roundAngle(deviceOrientation.alpha)));
841
- this.#setOrientationInputValue(this.betaElement, String(roundAngle(deviceOrientation.beta)));
842
- this.#setOrientationInputValue(this.gammaElement, String(roundAngle(deviceOrientation.gamma)));
846
+ this.alphaElement.value = String(roundAngle(deviceOrientation.alpha));
847
+ this.betaElement.value = String(roundAngle(deviceOrientation.beta));
848
+ this.gammaElement.value = String(roundAngle(deviceOrientation.gamma));
843
849
  }
844
850
 
845
851
  const animate = modificationSource !== DeviceOrientationModificationSource.USER_DRAG;
@@ -853,17 +859,9 @@ export class SensorsView extends UI.Widget.VBox {
853
859
  {PH1: deviceOrientation.alpha, PH2: deviceOrientation.beta, PH3: deviceOrientation.gamma}));
854
860
  }
855
861
 
856
- #onOrientationInput(event: Event): void {
857
- const input = event.currentTarget as HTMLInputElement;
858
- const valid = this.#validateOrientationInput(input, input.value);
859
- input.classList.toggle('error-input', !valid);
860
- }
861
-
862
862
  #onOrientationChange(event: Event): void {
863
863
  const input = event.currentTarget as HTMLInputElement;
864
- const valid = this.#validateOrientationInput(input, input.value);
865
- input.classList.toggle('error-input', !valid);
866
- if (valid) {
864
+ if (input.checkValidity()) {
867
865
  this.applyDeviceOrientationUserInput();
868
866
  }
869
867
  }
@@ -871,8 +869,7 @@ export class SensorsView extends UI.Widget.VBox {
871
869
  #onOrientationKeyDown(event: KeyboardEvent): void {
872
870
  const input = event.currentTarget as HTMLInputElement;
873
871
  if (event.key === 'Enter') {
874
- const valid = this.#validateOrientationInput(input, input.value);
875
- if (valid) {
872
+ if (input.checkValidity()) {
876
873
  this.applyDeviceOrientationUserInput();
877
874
  }
878
875
  event.preventDefault();
@@ -883,10 +880,13 @@ export class SensorsView extends UI.Widget.VBox {
883
880
  if (value === null) {
884
881
  return;
885
882
  }
886
- const stringValue = String(value);
887
- const valid = this.#validateOrientationInput(input, stringValue);
888
- if (valid) {
889
- this.#setOrientationInputValue(input, stringValue);
883
+ const prevValue = input.value;
884
+ input.value = String(value);
885
+ if (input.checkValidity()) {
886
+ this.applyDeviceOrientationUserInput();
887
+ } else {
888
+ // If ArrowUp/ArrowDown adjusts the value out of bounds, we reset it.
889
+ input.value = prevValue;
890
890
  }
891
891
  event.preventDefault();
892
892
  }
@@ -896,25 +896,6 @@ export class SensorsView extends UI.Widget.VBox {
896
896
  input.select();
897
897
  }
898
898
 
899
- #validateOrientationInput(input: HTMLInputElement, value: string): boolean {
900
- if (input === this.alphaElement) {
901
- return SDK.EmulationModel.DeviceOrientation.alphaAngleValidator(value);
902
- }
903
- if (input === this.betaElement) {
904
- return SDK.EmulationModel.DeviceOrientation.betaAngleValidator(value);
905
- }
906
- if (input === this.gammaElement) {
907
- return SDK.EmulationModel.DeviceOrientation.gammaAngleValidator(value);
908
- }
909
- return false;
910
- }
911
-
912
- #setOrientationInputValue(input: HTMLInputElement, value: string): void {
913
- input.value = value;
914
- const valid = this.#validateOrientationInput(input, value);
915
- input.classList.toggle('error-input', !valid);
916
- }
917
-
918
899
  private setBoxOrientation(deviceOrientation: SDK.EmulationModel.DeviceOrientation, animate: boolean): void {
919
900
  if (animate) {
920
901
  this.stageElement.classList.add('is-animating');
@@ -35,7 +35,7 @@
35
35
  background-color: var(--sys-color-tonal-container);
36
36
  }
37
37
 
38
- .keybinds-list-item.keybinds-editing {
38
+ .keybinds-list-item-wrapper:has(.keybinds-list-item.keybinds-editing) {
39
39
  background-color: var(--sys-color-neutral-container);
40
40
  }
41
41
 
@@ -168,31 +168,30 @@ button.text-button {
168
168
  }
169
169
 
170
170
  @media (forced-colors: active) {
171
- /* Keyboard focus on wrapper element (shortcut items) */
171
+ .keybinds-list-item.keybinds-editing .keybinds-shortcut {
172
+ & devtools-button {
173
+ --sys-color-primary: buttonFace;
174
+ }
175
+ }
176
+
177
+ .keybinds-list-text input {
178
+ color: buttonText;
179
+ }
180
+
181
+ /* Keyboard focus / hover on wrapper element (shortcut items) */
172
182
  .keybinds-list-item-wrapper {
183
+ &:has(.keybinds-list-item:hover),
184
+ &:has(.keybinds-list-item:not(.keybinds-editing)):focus-within,
173
185
  &:focus,
174
186
  &:focus-visible {
175
- background-color: Highlight !important; /* stylelint-disable-line declaration-no-important */
187
+ background-color: Highlight;
176
188
  forced-color-adjust: none;
177
189
 
190
+ --icon-default: HighlightText;
191
+
178
192
  & .keybinds-list-text,
179
193
  & .keybinds-action-name {
180
- color: HighlightText !important; /* stylelint-disable-line declaration-no-important */
181
- }
182
-
183
- & .keybinds-key {
184
- background: HighlightText;
185
- color: Highlight;
186
- }
187
- }
188
-
189
- /* Hover state (shortcut items) */
190
- &:has(.keybinds-list-item:hover) {
191
- background-color: Highlight !important; /* stylelint-disable-line declaration-no-important */
192
- forced-color-adjust: none;
193
-
194
- & .keybinds-list-text {
195
- color: HighlightText !important; /* stylelint-disable-line declaration-no-important */
194
+ color: HighlightText;
196
195
  }
197
196
 
198
197
  & .keybinds-key {
@@ -203,23 +202,18 @@ button.text-button {
203
202
  }
204
203
 
205
204
  /* Editing state */
206
- .keybinds-list-item.keybinds-editing {
207
- background-color: Highlight !important; /* stylelint-disable-line declaration-no-important */
205
+ .keybinds-list-item-wrapper:has(.keybinds-list-item.keybinds-editing) {
206
+ background-color: Highlight;
208
207
  forced-color-adjust: none;
209
208
 
209
+ --icon-default: HighlightText;
210
+
210
211
  & .keybinds-list-text {
211
- color: HighlightText !important; /* stylelint-disable-line declaration-no-important */
212
+ color: HighlightText;
212
213
  }
213
- }
214
214
 
215
- /* Category headers (e.g., "Background Services", "Debugger") */
216
- .keybinds-category-header {
217
- &:hover,
218
- &:focus,
219
- &:focus-visible {
220
- background-color: Highlight !important; /* stylelint-disable-line declaration-no-important */
221
- color: HighlightText !important; /* stylelint-disable-line declaration-no-important */
222
- forced-color-adjust: none;
215
+ & .keybinds-error {
216
+ color: highlightText;
223
217
  }
224
218
  }
225
219
  }
@@ -87,13 +87,13 @@ export class EventsTimelineTreeView extends TimelineTreeView {
87
87
  }
88
88
 
89
89
  override populateColumns(columns: DataGrid.DataGrid.ColumnDescriptor[]): void {
90
- columns.push(({
90
+ columns.push({
91
91
  id: 'start-time',
92
92
  title: i18nString(UIStrings.startTime),
93
93
  width: '80px',
94
94
  fixedWidth: true,
95
95
  sortable: true,
96
- } as DataGrid.DataGrid.ColumnDescriptor));
96
+ });
97
97
  super.populateColumns(columns);
98
98
  columns.filter(c => c.fixedWidth).forEach(c => {
99
99
  c.width = '80px';
@@ -257,6 +257,8 @@ export class ThirdPartyTreeViewWidget extends TimelineTreeView.TimelineTreeView
257
257
  export class ThirdPartyTreeElement extends UI.Widget.WidgetElement<UI.Widget.Widget> {
258
258
  #treeView?: ThirdPartyTreeViewWidget;
259
259
 
260
+ static readonly observedAttributes = ['max-rows'];
261
+
260
262
  set treeView(treeView: ThirdPartyTreeViewWidget) {
261
263
  this.#treeView = treeView;
262
264
  }
@@ -266,6 +268,12 @@ export class ThirdPartyTreeElement extends UI.Widget.WidgetElement<UI.Widget.Wid
266
268
  this.style.display = 'contents';
267
269
  }
268
270
 
271
+ attributeChangedCallback(name: string, _oldValue: string|null, newValue: string|null): void {
272
+ if (name === 'max-rows' && newValue) {
273
+ this.style.setProperty('--max-rows', newValue);
274
+ }
275
+ }
276
+
269
277
  override createWidget(): UI.Widget.Widget {
270
278
  const containerWidget = new UI.Widget.Widget(this);
271
279
  containerWidget.contentElement.style.display = 'contents';
@@ -62,6 +62,7 @@ import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.
62
62
  import * as UI from '../../ui/legacy/legacy.js';
63
63
  import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
64
64
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
65
+ import * as PanelsCommon from '../common/common.js';
65
66
  import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
66
67
 
67
68
  import {ActiveFilters} from './ActiveFilters.js';
@@ -93,7 +94,7 @@ import {TimelineUIUtils} from './TimelineUIUtils.js';
93
94
  import {createHiddenTracksOverlay} from './TrackConfigBanner.js';
94
95
  import {UIDevtoolsController} from './UIDevtoolsController.js';
95
96
  import {UIDevtoolsUtils} from './UIDevtoolsUtils.js';
96
- import * as Utils from './utils/utils.js';
97
+ import type * as Utils from './utils/utils.js';
97
98
 
98
99
  const UIStrings = {
99
100
  /**
@@ -800,7 +801,7 @@ export class TimelinePanel extends Common.ObjectWrapper.eventMixin<EventTypes, t
800
801
  }
801
802
 
802
803
  #onFieldDataChanged(): void {
803
- const recs = Utils.Helpers.getThrottlingRecommendations();
804
+ const recs = PanelsCommon.ThrottlingUtils.getThrottlingRecommendations();
804
805
  this.cpuThrottlingSelect?.updateRecommendedOption(recs.cpuOption);
805
806
  if (this.networkThrottlingSelect) {
806
807
  this.networkThrottlingSelect.recommendedConditions = recs.networkConditions;
@@ -3281,6 +3282,17 @@ export class CoreVitalsRevealer implements Common.Revealer.Revealer<Utils.Helper
3281
3282
  }
3282
3283
  }
3283
3284
 
3285
+ export class TimeRangeRevealer implements Common.Revealer.Revealer<Utils.Helpers.RevealableTimeRange> {
3286
+ async reveal(revealable: Utils.Helpers.RevealableTimeRange): Promise<void> {
3287
+ await UI.ViewManager.ViewManager.instance().showView('timeline');
3288
+ const panel = TimelinePanel.instance();
3289
+ TraceBounds.TraceBounds.BoundsManager.instance().setTimelineVisibleWindow(
3290
+ revealable.bounds, {ignoreMiniMapBounds: true, shouldAnimate: true});
3291
+ panel.select(null);
3292
+ panel.getFlameChart().selectDetailsViewTab(Tab.Details, null);
3293
+ }
3294
+ }
3295
+
3284
3296
  export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
3285
3297
  handleAction(context: UI.Context.Context, actionId: string): boolean {
3286
3298
  const panel = context.flavor(TimelinePanel);
@@ -264,9 +264,9 @@ export class TimelineTreeView extends
264
264
  this.textFilterInternal = new TimelineRegExp();
265
265
 
266
266
  this.currentThreadSetting = Common.Settings.Settings.instance().createSetting('timeline-tree-current-thread', 0);
267
- this.currentThreadSetting.addChangeListener(this.refreshTree, this);
267
+ this.currentThreadSetting.addChangeListener(() => this.refreshTree());
268
268
 
269
- const columns = ([] as DataGrid.DataGrid.ColumnDescriptor[]);
269
+ const columns: DataGrid.DataGrid.ColumnDescriptor[] = [];
270
270
  this.populateColumns(columns);
271
271
 
272
272
  this.splitWidget = new UI.SplitWidget.SplitWidget(true, true, 'timeline-tree-view-details-split-widget');
@@ -403,8 +403,15 @@ export class TimelineTreeView extends
403
403
  }
404
404
  }
405
405
 
406
- refreshTree(): void {
407
- if (!this.element.parentElement) {
406
+ /**
407
+ * Refreshes the tree. By default, it will only do this
408
+ * if the tree is mounted into the DOM - as in the UI we
409
+ * have multiple trees and we only want to refresh the
410
+ * active one. Pass `true` into this function to force a
411
+ * refresh regardless.
412
+ */
413
+ refreshTree(forceRefresh = false): void {
414
+ if (!this.element.parentElement && !forceRefresh) {
408
415
  // This function can be called in different views (Bottom-Up and
409
416
  // Call Tree) by the same single event whenever the group-by
410
417
  // dropdown changes value. Thus, we bail out whenever the view is
@@ -462,15 +469,10 @@ export class TimelineTreeView extends
462
469
  }
463
470
 
464
471
  populateColumns(columns: DataGrid.DataGrid.ColumnDescriptor[]): void {
472
+ columns.push({id: 'self', title: i18nString(UIStrings.selfTime), width: '120px', fixedWidth: true, sortable: true});
465
473
  columns.push(
466
- ({id: 'self', title: i18nString(UIStrings.selfTime), width: '120px', fixedWidth: true, sortable: true} as
467
- DataGrid.DataGrid.ColumnDescriptor));
468
- columns.push(
469
- ({id: 'total', title: i18nString(UIStrings.totalTime), width: '120px', fixedWidth: true, sortable: true} as
470
- DataGrid.DataGrid.ColumnDescriptor));
471
- columns.push(
472
- ({id: 'activity', title: i18nString(UIStrings.activity), disclosure: true, sortable: true} as
473
- DataGrid.DataGrid.ColumnDescriptor));
474
+ {id: 'total', title: i18nString(UIStrings.totalTime), width: '120px', fixedWidth: true, sortable: true});
475
+ columns.push({id: 'activity', title: i18nString(UIStrings.activity), disclosure: true, sortable: true});
474
476
  }
475
477
 
476
478
  sortingChanged(): void {
@@ -959,7 +961,7 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
959
961
  super();
960
962
  this.groupBySetting = Common.Settings.Settings.instance().createSetting(
961
963
  'timeline-tree-group-by', AggregatedTimelineTreeView.GroupBy.None);
962
- this.groupBySetting.addChangeListener(this.refreshTree.bind(this));
964
+ this.groupBySetting.addChangeListener(() => this.refreshTree());
963
965
  this.init();
964
966
  this.stackView = new TimelineStackView(this);
965
967
  this.stackView.addEventListener(TimelineStackView.Events.SELECTION_CHANGED, this.onStackViewSelectionChanged, this);
@@ -1297,10 +1299,10 @@ export class TimelineStackView extends
1297
1299
  const header = this.element.createChild('div', 'timeline-stack-view-header');
1298
1300
  header.textContent = i18nString(UIStrings.heaviestStack);
1299
1301
  this.treeView = treeView;
1300
- const columns = ([
1301
- {id: 'total', title: i18nString(UIStrings.totalTime), fixedWidth: true, width: '110px'},
1302
- {id: 'activity', title: i18nString(UIStrings.activity)},
1303
- ] as DataGrid.DataGrid.ColumnDescriptor[]);
1302
+ const columns: DataGrid.DataGrid.ColumnDescriptor[] = [
1303
+ {id: 'total', title: i18nString(UIStrings.totalTime), fixedWidth: true, width: '110px', sortable: false},
1304
+ {id: 'activity', title: i18nString(UIStrings.activity), sortable: false},
1305
+ ];
1304
1306
  this.dataGrid = new DataGrid.ViewportDataGrid.ViewportDataGrid({
1305
1307
  displayName: i18nString(UIStrings.timelineStack),
1306
1308
  columns,
@@ -4,7 +4,6 @@
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
5
 
6
6
  import '../../../ui/kit/kit.js';
7
- import './OriginMap.js';
8
7
 
9
8
  import * as i18n from '../../../core/i18n/i18n.js';
10
9
  import * as CrUXManager from '../../../models/crux-manager/crux-manager.js';
@@ -13,11 +12,12 @@ import * as Dialogs from '../../../ui/components/dialogs/dialogs.js';
13
12
  import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
14
13
  import * as Input from '../../../ui/components/input/input.js';
15
14
  import * as uiI18n from '../../../ui/i18n/i18n.js';
15
+ import * as UI from '../../../ui/legacy/legacy.js';
16
16
  import * as Lit from '../../../ui/lit/lit.js';
17
17
  import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
18
18
 
19
19
  import fieldSettingsDialogStyles from './fieldSettingsDialog.css.js';
20
- import type {OriginMap} from './OriginMap.js';
20
+ import {OriginMap} from './OriginMap.js';
21
21
 
22
22
  const UIStrings = {
23
23
  /**
@@ -95,6 +95,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/timeline/components/FieldSettin
95
95
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
96
96
 
97
97
  const {html, nothing, Directives: {ifDefined}} = Lit;
98
+ const {widget, widgetRef} = UI.Widget;
98
99
 
99
100
  export class ShowDialog extends Event {
100
101
  static readonly eventName = 'showdialog';
@@ -309,13 +310,8 @@ export class FieldSettingsDialog extends HTMLElement {
309
310
  // clang-format off
310
311
  return html`
311
312
  <div class="origin-mapping-description">${i18nString(UIStrings.mapDevelopmentOrigins)}</div>
312
- <devtools-origin-map
313
- ${Lit.Directives.ref(el => {
314
- if (el instanceof HTMLElement) {
315
- this.#originMap = el as OriginMap;
316
- }
317
- })}
318
- ></devtools-origin-map>
313
+ <devtools-widget ${widget(OriginMap)} ${widgetRef(OriginMap, el => { this.#originMap = el; })}>
314
+ </devtools-widget>
319
315
  <div class="origin-mapping-button-section">
320
316
  <devtools-button
321
317
  @click=${() => this.#originMap?.startCreation()}
@@ -31,7 +31,6 @@ import * as UI from '../../../ui/legacy/legacy.js';
31
31
  import * as Lit from '../../../ui/lit/lit.js';
32
32
  import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
33
33
  import * as PanelsCommon from '../../common/common.js';
34
- import * as Utils from '../utils/utils.js';
35
34
 
36
35
  import {CPUThrottlingSelector} from './CPUThrottlingSelector.js';
37
36
  import {md} from './insights/Helpers.js';
@@ -636,7 +635,7 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
636
635
  networkRecEl.classList.add('environment-rec');
637
636
  networkRecEl.textContent = this.#getNetworkRecTitle() || i18nString(UIStrings.notEnoughData);
638
637
 
639
- const recs = Utils.Helpers.getThrottlingRecommendations();
638
+ const recs = PanelsCommon.ThrottlingUtils.getThrottlingRecommendations();
640
639
 
641
640
  // clang-format off
642
641
  return html`