chrome-devtools-frontend 1.0.1595925 → 1.0.1596535

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/.stylelintrc.json +3 -1
  2. package/docs/ui_engineering.md +0 -36
  3. package/front_end/core/common/Console.ts +6 -6
  4. package/front_end/core/common/Settings.ts +12 -8
  5. package/front_end/core/host/UserMetrics.ts +0 -1
  6. package/front_end/core/root/DevToolsContext.ts +13 -7
  7. package/front_end/core/root/ExperimentNames.ts +0 -1
  8. package/front_end/core/sdk/CPUThrottlingManager.ts +12 -9
  9. package/front_end/core/sdk/DOMModel.ts +206 -0
  10. package/front_end/core/sdk/FrameManager.ts +7 -8
  11. package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
  12. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +1 -1
  13. package/front_end/entrypoints/greendev_floaty/floaty.css +2 -2
  14. package/front_end/entrypoints/main/MainImpl.ts +1 -7
  15. package/front_end/foundation/Universe.ts +22 -11
  16. package/front_end/generated/InspectorBackendCommands.ts +7 -0
  17. package/front_end/generated/protocol-mapping.d.ts +16 -0
  18. package/front_end/generated/protocol-proxy-api.d.ts +25 -0
  19. package/front_end/generated/protocol.ts +71 -0
  20. package/front_end/models/ai_assistance/AiConversation.ts +6 -95
  21. package/front_end/models/ai_assistance/ConversationHandler.ts +1 -1
  22. package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -1
  23. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +14 -0
  24. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
  25. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +3 -0
  26. package/front_end/panels/ai_assistance/components/ChatMessage.ts +73 -35
  27. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -6
  28. package/front_end/panels/ai_assistance/components/chatMessage.css +4 -2
  29. package/front_end/panels/application/IndexedDBModel.ts +2 -4
  30. package/front_end/panels/application/ServiceWorkersView.ts +3 -11
  31. package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
  32. package/front_end/panels/elements/ComputedStyleWidget.ts +25 -16
  33. package/front_end/panels/elements/ElementsPanel.ts +0 -1
  34. package/front_end/panels/elements/StandaloneStylesContainer.ts +48 -12
  35. package/front_end/panels/elements/StylePropertiesSection.ts +97 -1
  36. package/front_end/panels/elements/StylePropertyTreeElement.ts +27 -5
  37. package/front_end/panels/elements/StylesContainer.ts +1 -0
  38. package/front_end/panels/elements/StylesSidebarPane.ts +48 -32
  39. package/front_end/panels/elements/nodeStackTraceWidget.css +1 -1
  40. package/front_end/panels/elements/stylePropertiesTreeOutline.css +1 -1
  41. package/front_end/panels/emulation/DeviceModeToolbar.ts +171 -89
  42. package/front_end/panels/greendev/GreenDevPanel.css +2 -2
  43. package/front_end/panels/issues/AffectedPermissionElementsView.ts +9 -6
  44. package/front_end/panels/lighthouse/LighthouseController.ts +13 -5
  45. package/front_end/panels/lighthouse/LighthousePanel.ts +22 -5
  46. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +11 -3
  47. package/front_end/panels/recorder/components/StepView.ts +0 -2
  48. package/front_end/panels/recorder/components/stepView.css +13 -13
  49. package/front_end/panels/recorder/components/timelineSection.css +6 -7
  50. package/front_end/panels/settings/components/SyncSection.ts +4 -13
  51. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +2 -15
  52. package/front_end/panels/timeline/RecordingMetadata.ts +1 -1
  53. package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
  54. package/front_end/panels/timeline/TimelinePanel.ts +18 -0
  55. package/front_end/panels/timeline/TimelineUIUtils.ts +7 -4
  56. package/front_end/panels/timeline/components/CWVMetrics.ts +339 -0
  57. package/front_end/panels/timeline/components/Sidebar.ts +17 -0
  58. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +10 -0
  59. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +25 -267
  60. package/front_end/panels/timeline/components/Utils.ts +2 -2
  61. package/front_end/panels/timeline/components/components.ts +2 -0
  62. package/front_end/panels/timeline/components/cwvMetrics.css +107 -0
  63. package/front_end/panels/timeline/components/sidebarSingleInsightSet.css +0 -102
  64. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  65. package/front_end/panels/timeline/utils/Helpers.ts +5 -1
  66. package/front_end/panels/webauthn/webauthnPane.css +1 -1
  67. package/front_end/third_party/chromium/README.chromium +1 -1
  68. package/front_end/third_party/puppeteer/README.chromium +2 -2
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +7 -0
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +1 -0
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -0
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +1 -0
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -0
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -0
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +5 -0
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +7 -0
  91. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +14 -3
  92. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +7 -0
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +1 -0
  96. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -0
  98. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +1 -0
  100. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -0
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -0
  104. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +5 -0
  106. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  108. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  109. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  110. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/types.d.ts +7 -0
  112. package/front_end/third_party/puppeteer/package/package.json +1 -1
  113. package/front_end/third_party/puppeteer/package/src/api/Page.ts +8 -0
  114. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +4 -0
  115. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +7 -0
  116. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +6 -0
  117. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  118. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  119. package/front_end/ui/components/text_editor/AutocompleteHistory.ts +89 -5
  120. package/front_end/ui/components/tree_outline/TreeOutline.ts +1 -1
  121. package/front_end/ui/legacy/ProgressIndicator.ts +1 -1
  122. package/front_end/ui/legacy/Toolbar.ts +1 -1
  123. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
  124. package/front_end/ui/legacy/legacy.ts +0 -2
  125. package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
  126. package/inspector_overlay/loadCSS.rollup.js +2 -2
  127. package/inspector_overlay/tool_source_order.css +1 -0
  128. package/package.json +1 -1
  129. package/front_end/ui/legacy/Fragment.ts +0 -234
@@ -43,6 +43,7 @@ import * as SDK from '../../core/sdk/sdk.js';
43
43
  import * as Protocol from '../../generated/protocol.js';
44
44
  import * as Badges from '../../models/badges/badges.js';
45
45
  import * as Bindings from '../../models/bindings/bindings.js';
46
+ import * as ComputedStyle from '../../models/computed_style/computed_style.js';
46
47
  import * as TextUtils from '../../models/text_utils/text_utils.js';
47
48
  import * as Buttons from '../../ui/components/buttons/buttons.js';
48
49
  import * as Tooltips from '../../ui/components/tooltips/tooltips.js';
@@ -55,7 +56,7 @@ import {FontEditorSectionManager} from './ColorSwatchPopoverIcon.js';
55
56
  import * as ElementsComponents from './components/components.js';
56
57
  import {ElementsPanel} from './ElementsPanel.js';
57
58
  import stylePropertiesTreeOutlineStyles from './stylePropertiesTreeOutline.css.js';
58
- import {type Context, StylePropertyTreeElement} from './StylePropertyTreeElement.js';
59
+ import {type Context, GhostStylePropertyTreeElement, StylePropertyTreeElement} from './StylePropertyTreeElement.js';
59
60
  import type {StylesContainer} from './StylesContainer.js';
60
61
 
61
62
  const UIStrings = {
@@ -166,6 +167,8 @@ export class StylePropertiesSection {
166
167
  static #nextSectionTooltipIdPrefix = 0;
167
168
  readonly sectionTooltipIdPrefix = StylePropertiesSection.#nextSectionTooltipIdPrefix++;
168
169
 
170
+ private ghostStyleTreeElements: GhostStylePropertyTreeElement[] = [];
171
+
169
172
  constructor(
170
173
  stylesContainer: StylesContainer, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
171
174
  style: SDK.CSSStyleDeclaration.CSSStyleDeclaration, sectionIdx: number, computedStyles: Map<string, string>|null,
@@ -323,12 +326,55 @@ export class StylePropertiesSection {
323
326
  this.#isHidden = false;
324
327
  this.markSelectorMatches();
325
328
  this.onpopulate();
329
+
330
+ this.stylesContainer.computedStyleModel().addEventListener(
331
+ ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.#onCSSModelChanged, this);
326
332
  }
327
333
 
328
334
  setComputedStyles(computedStyles: Map<string, string>|null): void {
329
335
  this.computedStyles = computedStyles;
330
336
  }
331
337
 
338
+ #onCSSModelChanged(event: Common.EventTarget.EventTargetEvent<ComputedStyle.ComputedStyleModel.CSSModelChangedEvent>):
339
+ void {
340
+ const edit = event?.data && 'edit' in event.data ? event.data.edit : null;
341
+ if (edit) {
342
+ this.styleSheetEdited(edit);
343
+ void this.refreshComputedValues();
344
+ return;
345
+ }
346
+
347
+ if (this.stylesContainer.isEditingStyle || this.stylesContainer.userOperation) {
348
+ void this.refreshComputedValues();
349
+ }
350
+ }
351
+
352
+ async refreshComputedValues(): Promise<void> {
353
+ const node = this.stylesContainer.node();
354
+ if (!node) {
355
+ return;
356
+ }
357
+
358
+ const cssModel = node.domModel().cssModel();
359
+ const computedStyleModel = this.stylesContainer.computedStyleModel();
360
+
361
+ const matchedStyles = await cssModel.cachedMatchedCascadeForNode(node);
362
+ const parentNodeId = matchedStyles?.getParentLayoutNodeId();
363
+
364
+ const [computedStyles, parentsComputedStyles] = await Promise.all([
365
+ computedStyleModel.fetchComputedStyle(),
366
+ parentNodeId ? cssModel.getComputedStyle(parentNodeId) : null,
367
+ ]);
368
+
369
+ if (computedStyles) {
370
+ this.setComputedStyles(computedStyles.computedStyle);
371
+ }
372
+ if (parentsComputedStyles) {
373
+ this.setParentsComputedStyles(parentsComputedStyles);
374
+ }
375
+ this.updateAuthoringHint();
376
+ }
377
+
332
378
  setParentsComputedStyles(parentsComputedStyles: Map<string, string>|null): void {
333
379
  this.parentsComputedStyles = parentsComputedStyles;
334
380
  }
@@ -349,6 +395,11 @@ export class StylePropertiesSection {
349
395
  }
350
396
  }
351
397
 
398
+ dispose(): void {
399
+ this.stylesContainer.computedStyleModel().removeEventListener(
400
+ ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.#onCSSModelChanged, this);
401
+ }
402
+
352
403
  setSectionIdx(sectionIdx: number): void {
353
404
  this.sectionIdx = sectionIdx;
354
405
  this.onpopulate();
@@ -778,6 +829,51 @@ export class StylePropertiesSection {
778
829
  return;
779
830
  }
780
831
 
832
+ clearGhostStyleTreeElements(): void {
833
+ // Clear existing ghost elements
834
+ for (const ghost of this.ghostStyleTreeElements) {
835
+ this.propertiesTreeOutline.removeChild(ghost);
836
+ }
837
+ this.ghostStyleTreeElements = [];
838
+ }
839
+
840
+ renderGhostStyleTreeElements(suggestion: string): void {
841
+ this.clearGhostStyleTreeElements();
842
+ if (!suggestion) {
843
+ return;
844
+ }
845
+
846
+ const suggestionLines = suggestion.split(';').map(line => line.trim());
847
+ for (const line of suggestionLines) {
848
+ const colonIdx = line.indexOf(':');
849
+ if (colonIdx === -1) {
850
+ continue;
851
+ }
852
+
853
+ const name = line.substring(0, colonIdx).trim();
854
+ const value = line.substring(colonIdx + 1).trim();
855
+ if (!name || !value) {
856
+ continue;
857
+ }
858
+
859
+ // Create a fake property attached to this style
860
+ const fakeProperty = new SDK.CSSProperty.CSSProperty(
861
+ this.styleInternal,
862
+ this.styleInternal.allProperties().length,
863
+ name,
864
+ value,
865
+ false,
866
+ false,
867
+ true,
868
+ false,
869
+ );
870
+
871
+ const ghost = new GhostStylePropertyTreeElement(this.stylesContainer, this, this.matchedStyles, fakeProperty);
872
+ this.propertiesTreeOutline.appendChild(ghost);
873
+ this.ghostStyleTreeElements.push(ghost);
874
+ }
875
+ }
876
+
781
877
  private onNewRuleClick(event: Common.EventTarget.EventTargetEvent<Event>): void {
782
878
  event.data.consume();
783
879
  const rule = this.styleInternal.parentRule;
@@ -1575,11 +1575,17 @@ export class GridTemplateRenderer extends rendererBase(SDK.CSSPropertyParserMatc
1575
1575
 
1576
1576
  const indent = Common.Settings.Settings.instance().moduleSetting('text-editor-indent').get();
1577
1577
  const container = document.createDocumentFragment();
1578
- for (const line of match.lines) {
1579
- const value = Renderer.render(line, context);
1580
- const lineBreak = UI.Fragment.html`<br /><span class='styles-clipboard-only'>${indent.repeat(2)}</span>`;
1581
- container.append(lineBreak, ...value.nodes);
1582
- }
1578
+
1579
+ const template = html`
1580
+ ${match.lines.map(line => {
1581
+ const lines = Renderer.render(line, context).nodes;
1582
+ return html`
1583
+ <span class='styles-clipboard-only'>${indent.repeat(2)}</span>
1584
+ ${lines}`;
1585
+ })}
1586
+ `;
1587
+
1588
+ render(template, container);
1583
1589
  return [container];
1584
1590
  }
1585
1591
  }
@@ -3542,6 +3548,22 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
3542
3548
  override isEventWithinDisclosureTriangle(event: Event): boolean {
3543
3549
  return event.target === this.expandElement;
3544
3550
  }
3551
+
3552
+ showGhostTextInValue(text: string): void {
3553
+ if (!this.valueElement) {
3554
+ return;
3555
+ }
3556
+ this.clearGhostTextInValue();
3557
+ this.valueElement.createChild('span', 'ghost-value-prediction').textContent = text;
3558
+ }
3559
+
3560
+ clearGhostTextInValue(): void {
3561
+ if (!this.valueElement) {
3562
+ return;
3563
+ }
3564
+ const ghostElement = this.valueElement.querySelector('.ghost-value-prediction');
3565
+ ghostElement?.remove();
3566
+ }
3545
3567
  }
3546
3568
 
3547
3569
  export class GhostStylePropertyTreeElement extends StylePropertyTreeElement {
@@ -17,6 +17,7 @@ export interface StylesContainer {
17
17
  activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null;
18
18
  readonly webCustomData: WebCustomData|undefined;
19
19
  isEditingStyle: boolean;
20
+ userOperation: boolean;
20
21
  readonly sectionByElement: WeakMap<Node, StylePropertiesSection>;
21
22
  readonly element: HTMLElement;
22
23
  readonly linkifier: Components.Linkifier.Linkifier;
@@ -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.
@@ -6,6 +6,6 @@
6
6
  @scope to (devtools-widget > *) {
7
7
  .stack-trace {
8
8
  font-size: 11px !important; /* stylelint-disable-line declaration-no-important */
9
- font-family: Menlo, monospace;
9
+ font-family: Menlo, var(--monospace-font-family);
10
10
  }
11
11
  }
@@ -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;