chrome-devtools-frontend 1.0.1596260 → 1.0.1596535

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/front_end/core/common/Console.ts +6 -6
  2. package/front_end/core/common/Settings.ts +12 -8
  3. package/front_end/core/root/DevToolsContext.ts +13 -7
  4. package/front_end/core/sdk/CPUThrottlingManager.ts +12 -9
  5. package/front_end/core/sdk/FrameManager.ts +7 -8
  6. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +1 -1
  7. package/front_end/entrypoints/main/MainImpl.ts +1 -2
  8. package/front_end/foundation/Universe.ts +22 -11
  9. package/front_end/generated/InspectorBackendCommands.ts +7 -0
  10. package/front_end/generated/protocol-mapping.d.ts +16 -0
  11. package/front_end/generated/protocol-proxy-api.d.ts +25 -0
  12. package/front_end/generated/protocol.ts +71 -0
  13. package/front_end/models/ai_assistance/AiConversation.ts +6 -95
  14. package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -1
  15. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +14 -0
  16. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +1 -0
  17. package/front_end/panels/ai_assistance/components/ChatMessage.ts +25 -4
  18. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +2 -2
  19. package/front_end/panels/elements/StandaloneStylesContainer.ts +48 -12
  20. package/front_end/panels/elements/StylePropertiesSection.ts +97 -1
  21. package/front_end/panels/elements/StylePropertyTreeElement.ts +16 -0
  22. package/front_end/panels/elements/StylesContainer.ts +1 -0
  23. package/front_end/panels/elements/StylesSidebarPane.ts +48 -32
  24. package/front_end/panels/elements/stylePropertiesTreeOutline.css +1 -1
  25. package/front_end/panels/lighthouse/LighthouseController.ts +13 -5
  26. package/front_end/panels/lighthouse/LighthousePanel.ts +22 -5
  27. package/front_end/panels/recorder/components/StepView.ts +0 -2
  28. package/front_end/panels/recorder/components/stepView.css +13 -13
  29. package/front_end/panels/recorder/components/timelineSection.css +6 -7
  30. package/front_end/panels/timeline/TimelinePanel.ts +18 -0
  31. package/front_end/panels/timeline/components/CWVMetrics.ts +339 -0
  32. package/front_end/panels/timeline/components/Sidebar.ts +17 -0
  33. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +10 -0
  34. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +25 -267
  35. package/front_end/panels/timeline/components/components.ts +2 -0
  36. package/front_end/panels/timeline/components/cwvMetrics.css +107 -0
  37. package/front_end/panels/timeline/components/sidebarSingleInsightSet.css +0 -102
  38. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  39. package/front_end/panels/timeline/utils/Helpers.ts +5 -1
  40. package/front_end/third_party/chromium/README.chromium +1 -1
  41. package/front_end/third_party/puppeteer/README.chromium +2 -2
  42. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +7 -0
  43. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  44. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  45. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +1 -0
  46. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  47. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -0
  48. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  49. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +1 -0
  50. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  51. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -0
  52. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  53. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -0
  54. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  55. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +5 -0
  56. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  57. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  59. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +7 -0
  64. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +14 -3
  65. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +7 -0
  66. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  67. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +1 -0
  69. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -0
  71. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +1 -0
  73. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -0
  75. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -0
  77. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +5 -0
  79. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  81. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  82. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/types.d.ts +7 -0
  85. package/front_end/third_party/puppeteer/package/package.json +1 -1
  86. package/front_end/third_party/puppeteer/package/src/api/Page.ts +8 -0
  87. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +4 -0
  88. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +7 -0
  89. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +6 -0
  90. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  91. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  92. package/front_end/ui/components/text_editor/AutocompleteHistory.ts +89 -5
  93. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  94. package/package.json +1 -1
@@ -185,7 +185,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
185
185
  private readonly decorator: StylePropertyHighlighter;
186
186
 
187
187
  private lastRevealedProperty: SDK.CSSProperty.CSSProperty|null = null;
188
- private userOperation = false;
188
+ userOperation = false;
189
189
  isEditingStyle = false;
190
190
  #filterRegex: RegExp|null = null;
191
191
  #isRegex = false;
@@ -208,7 +208,6 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
208
208
 
209
209
  activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null = null;
210
210
  #updateAbortController?: AbortController;
211
- #updateComputedStylesAbortController?: AbortController;
212
211
 
213
212
  constructor(computedStyleModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel) {
214
213
  super(computedStyleModel, {delegatesFocus: true});
@@ -695,12 +694,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
695
694
 
696
695
  override onCSSModelChanged(
697
696
  event: Common.EventTarget.EventTargetEvent<ComputedStyle.ComputedStyleModel.CSSModelChangedEvent>): void {
698
- const edit = event?.data && 'edit' in event.data ? event.data.edit : null;
699
- if (edit) {
700
- for (const section of this.allSections()) {
701
- section.styleSheetEdited(edit);
702
- }
703
- void this.#refreshComputedStyles();
697
+ // We only recreate sections if this update is more than an "edit" operation.
698
+ // Sections will pull their own updates in the case of an "edit".
699
+ if (event?.data && 'edit' in event.data && event.data.edit) {
704
700
  return;
705
701
  }
706
702
 
@@ -723,7 +719,6 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
723
719
 
724
720
  #resetUpdateIfNotEditing(): void {
725
721
  if (this.userOperation || this.isEditingStyle) {
726
- void this.#refreshComputedStyles();
727
722
  return;
728
723
  }
729
724
 
@@ -872,28 +867,6 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
872
867
  }
873
868
  }
874
869
 
875
- async #refreshComputedStyles(): Promise<void> {
876
- this.#updateComputedStylesAbortController?.abort();
877
- this.#updateAbortController = new AbortController();
878
- const signal = this.#updateAbortController.signal;
879
- const matchedStyles = await this.fetchMatchedCascade();
880
- const nodeId = this.node()?.id;
881
- const parentNodeId = matchedStyles?.getParentLayoutNodeId();
882
-
883
- const [computedStyles, parentsComputedStyles] =
884
- await Promise.all([this.fetchComputedStylesFor(nodeId), this.fetchComputedStylesFor(parentNodeId)]);
885
-
886
- if (signal.aborted) {
887
- return;
888
- }
889
-
890
- for (const section of this.allSections()) {
891
- section.setComputedStyles(computedStyles);
892
- section.setParentsComputedStyles(parentsComputedStyles);
893
- section.updateAuthoringHint();
894
- }
895
- }
896
-
897
870
  focusedSectionIndex(): number {
898
871
  let index = 0;
899
872
  for (const block of this.sectionBlocks) {
@@ -936,6 +909,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
936
909
 
937
910
  this.linkifier.reset();
938
911
  const prevSections = this.sectionBlocks.map(block => block.sections).flat();
912
+ for (const section of prevSections) {
913
+ section.dispose();
914
+ }
939
915
  this.sectionBlocks = [];
940
916
 
941
917
  const node = this.node();
@@ -1825,7 +1801,7 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
1825
1801
  getCurrentText: () => {
1826
1802
  return this.text();
1827
1803
  },
1828
- setAiAutoCompletion: () => {},
1804
+ setAiAutoCompletion: this.setAiAutoCompletion.bind(this),
1829
1805
  };
1830
1806
  this.aiCodeCompletionProvider =
1831
1807
  StylesAiCodeCompletionProvider.StylesAiCodeCompletionProvider.createInstance(this.aiCodeCompletionConfig);
@@ -2117,6 +2093,46 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2117
2093
  userInput, range.endOffset, this.isEditingName, this.treeElement.property, cssModel);
2118
2094
  }
2119
2095
 
2096
+ private setAiAutoCompletion(args: {
2097
+ text: string,
2098
+ from: number,
2099
+ startTime: number,
2100
+ onImpression: (rpcGlobalId: Host.AidaClient.RpcGlobalId, latency: number, sampleId?: number) => void,
2101
+ clearCachedRequest: () => void,
2102
+ rpcGlobalId?: Host.AidaClient.RpcGlobalId,
2103
+ sampleId?: number,
2104
+ }|null): void {
2105
+ if (!args) {
2106
+ this.treeElement.section().clearGhostStyleTreeElements();
2107
+ return;
2108
+ }
2109
+ this.showAiGhostText(args?.text);
2110
+ const latency = performance.now() - args.startTime;
2111
+ if (args.rpcGlobalId) {
2112
+ args.onImpression(args.rpcGlobalId, latency, args.sampleId);
2113
+ }
2114
+ }
2115
+
2116
+ private showAiGhostText(text: string): void {
2117
+ const [currentLine, ...nextLinesList] = text.split(';');
2118
+ const nextLines = nextLinesList.join(';').trim();
2119
+
2120
+ if (this.isEditingName && currentLine.includes(':')) {
2121
+ const [namePart, valuePart] = currentLine.split(':').map(s => s.trim());
2122
+ this.applySuggestion({text: this.text() + namePart}, true);
2123
+ this.treeElement.showGhostTextInValue(valuePart);
2124
+ } else {
2125
+ // Only has ghost text for one field - name part or value part
2126
+ this.applySuggestion({text: this.text() + currentLine}, true);
2127
+ }
2128
+
2129
+ if (nextLines) {
2130
+ this.treeElement.section().renderGhostStyleTreeElements(nextLines);
2131
+ } else {
2132
+ this.treeElement.section().clearGhostStyleTreeElements();
2133
+ }
2134
+ }
2135
+
2120
2136
  /**
2121
2137
  * Extracts the remaining portion of the suggestion text that follows the
2122
2138
  * user's current input.
@@ -81,7 +81,7 @@
81
81
  padding-bottom: 3px;
82
82
  }
83
83
 
84
- &.ghost-row {
84
+ &.ghost-row, .ghost-value-prediction {
85
85
  opacity: 50%;
86
86
  font-style: italic;
87
87
  pointer-events: none;
@@ -12,6 +12,7 @@ import * as EmulationModel from '../../models/emulation/emulation.js';
12
12
  import type * as LighthouseModel from '../../models/lighthouse/lighthouse.js';
13
13
  import * as Emulation from '../emulation/emulation.js';
14
14
 
15
+ import type {RunOverrides} from './LighthousePanel.js';
15
16
  import type {LighthouseRun as LighthouseRunType, ProtocolService} from './LighthouseProtocolService.js';
16
17
 
17
18
  const UIStrings = {
@@ -567,9 +568,9 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
567
568
  };
568
569
  }
569
570
 
570
- getCategoryIDs(): string[] {
571
+ getCategoryIDs(): CategoryId[] {
571
572
  const {mode} = this.getFlags();
572
- const categoryIDs = [];
573
+ const categoryIDs: CategoryId[] = [];
573
574
  for (const preset of Presets) {
574
575
  if (mode && !preset.supportedModes.includes(mode)) {
575
576
  continue;
@@ -639,7 +640,12 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
639
640
  }
640
641
  }
641
642
 
642
- async startLighthouse(): Promise<void> {
643
+ /**
644
+ * Starts a LH run. By default it will use the categories based on what the
645
+ * user has selected in the UI, but these can be overridden by passing in the
646
+ * category IDs, in which case these take priority.
647
+ */
648
+ async startLighthouse(overrides?: RunOverrides): Promise<void> {
643
649
  if (this.lastAction) {
644
650
  await this.lastAction;
645
651
  }
@@ -651,7 +657,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
651
657
  }
652
658
 
653
659
  const inspectedURL = await this.getInspectedURL({force: true});
654
- const categoryIDs = this.getCategoryIDs();
660
+ const categoryIDs = overrides?.categoryIds ?? this.getCategoryIDs();
655
661
  const flags = this.getFlags();
656
662
 
657
663
  this.recordMetrics(flags, categoryIDs);
@@ -861,9 +867,11 @@ export interface EventTypes {
861
867
  [Events.AuditProgressChanged]: AuditProgressChangedEvent;
862
868
  }
863
869
 
870
+ export type CategoryId = 'performance'|'accessibility'|'best-practices'|'seo';
871
+
864
872
  export interface Preset {
865
873
  setting: Common.Settings.Setting<boolean>;
866
- configID: string;
874
+ configID: CategoryId;
867
875
  title: () => Common.UIString.LocalizedString;
868
876
  description: () => Common.UIString.LocalizedString;
869
877
  supportedModes: string[];
@@ -13,10 +13,11 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
13
13
 
14
14
  import {
15
15
  type AuditProgressChangedEvent,
16
+ type CategoryId,
16
17
  Events,
17
18
  LighthouseController,
18
19
  type PageAuditabilityChangedEvent,
19
- type PageWarningsChangedEvent,
20
+ type PageWarningsChangedEvent
20
21
  } from './LighthouseController.js';
21
22
  import lighthousePanelStyles from './lighthousePanel.css.js';
22
23
  import {ProtocolService} from './LighthouseProtocolService.js';
@@ -70,7 +71,6 @@ export class LighthousePanel extends UI.Panel.Panel {
70
71
  private warningText: Nullable<string>;
71
72
  private unauditableExplanation: Nullable<string>;
72
73
  private readonly cachedRenderedReports: Map<LighthouseModel.ReporterTypes.ReportJSON, HTMLElement>;
73
- private readonly dropTarget: UI.DropTarget.DropTarget;
74
74
  private readonly auditResultsElement: HTMLElement;
75
75
  private clearButton!: UI.Toolbar.ToolbarButton;
76
76
  private newButton!: UI.Toolbar.ToolbarButton;
@@ -94,7 +94,7 @@ export class LighthousePanel extends UI.Panel.Panel {
94
94
  this.unauditableExplanation = null;
95
95
  this.cachedRenderedReports = new Map();
96
96
 
97
- this.dropTarget = new UI.DropTarget.DropTarget(
97
+ new UI.DropTarget.DropTarget(
98
98
  this.contentElement, [UI.DropTarget.Type.File], i18nString(UIStrings.dropLighthouseJsonHere),
99
99
  this.handleDrop.bind(this));
100
100
 
@@ -147,14 +147,17 @@ export class LighthousePanel extends UI.Panel.Panel {
147
147
  }
148
148
  }
149
149
 
150
- async handleCompleteRun(): Promise<void> {
150
+ async handleCompleteRun(overrides?: RunOverrides):
151
+ Promise<{report: LighthouseModel.ReporterTypes.ReportJSON | null}> {
151
152
  try {
152
- await this.controller.startLighthouse();
153
+ await this.controller.startLighthouse(overrides);
153
154
  this.renderStatusView();
154
155
  const {lhr, artifacts} = await this.controller.collectLighthouseResults();
155
156
  this.buildReportUI(lhr, artifacts);
157
+ return {report: lhr};
156
158
  } catch (err) {
157
159
  this.handleError(err);
160
+ return {report: null};
158
161
  }
159
162
  }
160
163
 
@@ -379,4 +382,18 @@ export class LighthousePanel extends UI.Panel.Panel {
379
382
  event.handled = true;
380
383
  }
381
384
  }
385
+
386
+ static async executeLighthouseRecording(
387
+ overrides?: RunOverrides,
388
+ ): Promise<LighthouseModel.ReporterTypes.ReportJSON|null> {
389
+ const panel = LighthousePanel.instance();
390
+ await UI.ViewManager.ViewManager.instance().showView('lighthouse');
391
+
392
+ const {report} = await panel.handleCompleteRun(overrides);
393
+ return report;
394
+ }
395
+ }
396
+
397
+ export interface RunOverrides {
398
+ categoryIds: CategoryId[];
382
399
  }
@@ -362,7 +362,6 @@ function renderStepActions(input: ViewInput): Lit.TemplateResult|null {
362
362
  }}
363
363
  jslog=${VisualLogging.dropDown('step-actions').track({click: true})}
364
364
  .iconName=${'dots-vertical'}
365
- }
366
365
  ></devtools-menu-button>
367
366
  `;
368
367
  // clang-format on
@@ -459,7 +458,6 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
459
458
  <div class="subtitle" title=${subtitle}>${subtitle}</div>
460
459
  </div>
461
460
  </div>
462
- <div class="filler"></div>
463
461
  ${renderStepActions(input)}
464
462
  </div>
465
463
  <div class="details">
@@ -13,18 +13,18 @@
13
13
  .title-container {
14
14
  /* Vertically center items with min-width: 0; */
15
15
  min-width: 0;
16
- font-size: 13px;
17
- line-height: 16px;
18
- letter-spacing: 0.03em;
16
+ font-size: var(--sys-size-7);
19
17
  display: flex;
20
18
  flex-direction: row;
21
- gap: 3px;
22
- outline-offset: 3px;
19
+ gap: var(--sys-size-2);
20
+ outline-offset: var(--sys-size-2);
21
+ flex-grow: 1;
22
+ align-items: center;
23
23
  }
24
24
 
25
25
  .action {
26
26
  display: flex;
27
- align-items: flex-start;
27
+ align-items: center;
28
28
  }
29
29
 
30
30
  .title {
@@ -58,7 +58,7 @@
58
58
  cy: 8px;
59
59
  }
60
60
 
61
- .is-start-of-group .circle-icon {
61
+ .is-start-of-group:not(:first-of-type) .circle-icon {
62
62
  r: 7px;
63
63
  fill: var(--sys-color-cdt-base-container);
64
64
  stroke: var(--sys-color-primary);
@@ -143,7 +143,7 @@
143
143
  height: 14px;
144
144
  transition: 200ms;
145
145
  position: absolute;
146
- top: 18px;
146
+ top: 14px;
147
147
  left: 24px;
148
148
  transform: rotate(-90deg);
149
149
  color: var(--sys-color-on-surface);
@@ -183,7 +183,11 @@ devtools-recorder-step-editor:hover {
183
183
  }
184
184
 
185
185
  devtools-recorder-step-editor.is-selected {
186
- background-color: color-mix(in srgb, var(--sys-color-tonal-container), var(--sys-color-cdt-base-container) 50%);
186
+ background-color: color-mix(
187
+ in srgb,
188
+ var(--sys-color-tonal-container),
189
+ var(--sys-color-cdt-base-container) 50%
190
+ );
187
191
  border: 1px solid var(--sys-color-tonal-outline);
188
192
  }
189
193
 
@@ -192,10 +196,6 @@ devtools-recorder-step-editor.is-selected {
192
196
  flex-flow: row nowrap;
193
197
  }
194
198
 
195
- .filler {
196
- flex-grow: 1;
197
- }
198
-
199
199
  .subtitle {
200
200
  font-weight: normal;
201
201
  color: var(--sys-color-on-surface-subtle);
@@ -13,7 +13,7 @@
13
13
 
14
14
  .timeline-section {
15
15
  position: relative;
16
- padding: 16px 0 0 40px;
16
+ padding: 8px 0 8px 40px;
17
17
  margin-left: 8px;
18
18
 
19
19
  --override-color-recording-successful-text: #36a854;
@@ -52,12 +52,12 @@
52
52
  z-index: 4;
53
53
  }
54
54
 
55
- .is-start-of-group {
56
- padding-top: 28px;
55
+ .is-start-of-group:not(:first-of-type) {
56
+ padding-top: 16px;
57
57
  }
58
58
 
59
59
  .is-end-of-group {
60
- padding-bottom: 24px;
60
+ padding-bottom: 16px;
61
61
  }
62
62
 
63
63
  .icon {
@@ -73,7 +73,7 @@
73
73
  display: block;
74
74
  transform: translateX(-50%);
75
75
  top: 18px;
76
- height: calc(100% + 8px);
76
+ height: 100%;
77
77
  z-index: 1; /* We want this to be below of `.overlay` for stopped case */
78
78
  }
79
79
 
@@ -86,8 +86,7 @@
86
86
  }
87
87
 
88
88
  .is-first-section .bar {
89
- top: 32px;
90
- height: calc(100% - 8px);
89
+ height: 100%;
91
90
  display: none;
92
91
  }
93
92
 
@@ -3054,6 +3054,17 @@ export class TimelinePanel extends Common.ObjectWrapper.eventMixin<EventTypes, t
3054
3054
  this.#setActiveInsight({model: insightModel, insightSetKey}, {highlightInsight: true});
3055
3055
  }
3056
3056
 
3057
+ revealCoreVitals(revealable: Utils.Helpers.RevealableCoreVitals): void {
3058
+ if (this.#splitWidget.showMode() !== UI.SplitWidget.ShowMode.BOTH) {
3059
+ this.#splitWidget.showBoth();
3060
+ }
3061
+ this.#sideBar.openInsightsTab();
3062
+ if (revealable.insightSetKey) {
3063
+ this.#sideBar.setActiveInsightSet(revealable.insightSetKey);
3064
+ this.#setActiveInsight(null);
3065
+ }
3066
+ }
3067
+
3057
3068
  static async executeRecordAndReload(): Promise<Trace.TraceModel.ParsedTrace> {
3058
3069
  await UI.ViewManager.ViewManager.instance().showView('timeline');
3059
3070
  const panelInstance = TimelinePanel.instance();
@@ -3238,6 +3249,13 @@ export class InsightRevealer implements Common.Revealer.Revealer<Utils.Helpers.R
3238
3249
  }
3239
3250
  }
3240
3251
 
3252
+ export class CoreVitalsRevealer implements Common.Revealer.Revealer<Utils.Helpers.RevealableCoreVitals> {
3253
+ async reveal(revealable: Utils.Helpers.RevealableCoreVitals): Promise<void> {
3254
+ await UI.ViewManager.ViewManager.instance().showView('timeline');
3255
+ TimelinePanel.instance().revealCoreVitals(revealable);
3256
+ }
3257
+ }
3258
+
3241
3259
  export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
3242
3260
  handleAction(context: UI.Context.Context, actionId: string): boolean {
3243
3261
  const panel = context.flavor(TimelinePanel);