chrome-devtools-frontend 1.0.1682249 → 1.0.1684555

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 (103) hide show
  1. package/AUTHORS +1 -0
  2. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -7
  3. package/front_end/core/sdk/StorageBucketsModel.ts +0 -6
  4. package/front_end/entrypoints/inspector_main/InspectorMain.ts +2 -1
  5. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +1 -5
  6. package/front_end/entrypoints/main/MainImpl.ts +6 -4
  7. package/front_end/entrypoints/main/main-meta.ts +9 -51
  8. package/front_end/foundation/Universe.ts +7 -0
  9. package/front_end/generated/InspectorBackendCommands.ts +12 -22
  10. package/front_end/generated/protocol-mapping.d.ts +9 -59
  11. package/front_end/generated/protocol-proxy-api.d.ts +7 -47
  12. package/front_end/generated/protocol.ts +105 -330
  13. package/front_end/models/ai_assistance/AiAgent2.ts +12 -4
  14. package/front_end/models/ai_assistance/AiConversation.ts +25 -7
  15. package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -19
  16. package/front_end/models/ai_assistance/agents/StorageAgent.ts +6 -6
  17. package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
  18. package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +12 -6
  19. package/front_end/models/ai_assistance/tools/GetStorageValues.ts +1 -1
  20. package/front_end/models/ai_assistance/tools/ListStorageKeys.ts +1 -1
  21. package/front_end/models/ai_assistance/tools/RunLighthouse.ts +5 -8
  22. package/front_end/models/ai_assistance/tools/Tool.ts +19 -6
  23. package/front_end/models/issues_manager/DOMIssuesManager.ts +144 -0
  24. package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +13 -1
  25. package/front_end/models/issues_manager/GenericIssue.ts +14 -2
  26. package/front_end/models/issues_manager/IssuesManager.ts +0 -1
  27. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  28. package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
  29. package/front_end/models/trace/Processor.ts +1 -0
  30. package/front_end/panels/ai_assistance/ExternalHandler.ts +89 -0
  31. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  32. package/front_end/panels/application/BackgroundServiceModel.ts +4 -3
  33. package/front_end/panels/application/IndexedDBModel.ts +0 -7
  34. package/front_end/panels/console/ConsoleView.ts +17 -16
  35. package/front_end/panels/console/ConsoleViewMessage.ts +4 -1
  36. package/front_end/panels/console/console-meta.ts +4 -19
  37. package/front_end/panels/elements/ElementIssueUtils.ts +10 -2
  38. package/front_end/panels/elements/ElementsPanel.ts +8 -3
  39. package/front_end/panels/elements/ElementsTreeElement.ts +82 -161
  40. package/front_end/panels/elements/ElementsTreeOutline.ts +26 -105
  41. package/front_end/panels/elements/StandaloneStylesContainer.ts +5 -11
  42. package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -0
  43. package/front_end/panels/elements/StylesContainer.ts +1 -0
  44. package/front_end/panels/elements/StylesSidebarPane.ts +174 -151
  45. package/front_end/panels/network/RequestPayloadView.ts +5 -2
  46. package/front_end/panels/security/SecurityPanelSidebar.ts +0 -32
  47. package/front_end/panels/settings/KeybindsSettingsTab.ts +5 -2
  48. package/front_end/panels/sources/SourcesPanel.ts +6 -3
  49. package/front_end/panels/timeline/components/BreadcrumbsUI.ts +2 -6
  50. package/front_end/panels/timeline/components/CWVMetrics.ts +9 -10
  51. package/front_end/panels/timeline/components/DetailsView.ts +12 -16
  52. package/front_end/panels/timeline/components/ExportTraceOptions.ts +13 -13
  53. package/front_end/panels/timeline/components/FieldSettingsDialog.ts +19 -19
  54. package/front_end/panels/timeline/components/IgnoreListSetting.ts +7 -9
  55. package/front_end/panels/timeline/components/InteractionBreakdown.ts +3 -3
  56. package/front_end/panels/timeline/components/LayoutShiftDetails.ts +13 -13
  57. package/front_end/panels/timeline/components/LiveMetricsView.ts +64 -64
  58. package/front_end/panels/timeline/components/MetricCard.ts +25 -25
  59. package/front_end/panels/timeline/components/NetworkRequestDetails.ts +22 -22
  60. package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +9 -9
  61. package/front_end/panels/timeline/components/OriginMap.ts +7 -7
  62. package/front_end/panels/timeline/components/RelatedInsightChips.ts +2 -2
  63. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +19 -20
  64. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
  65. package/front_end/panels/timeline/components/TimelineSummary.ts +2 -2
  66. package/front_end/panels/timeline/components/Utils.ts +2 -6
  67. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +6 -9
  68. package/front_end/panels/timeline/components/insights/Checklist.ts +2 -2
  69. package/front_end/panels/timeline/components/insights/Table.ts +1 -1
  70. package/front_end/third_party/chromium/README.chromium +1 -1
  71. package/front_end/ui/comments/CommentAnchorResolver.ts +94 -0
  72. package/front_end/ui/comments/CommentOverlayManager.ts +16 -32
  73. package/front_end/ui/components/text_editor/config.ts +2 -1
  74. package/front_end/ui/legacy/DockController.ts +4 -1
  75. package/front_end/ui/legacy/InspectorView.ts +3 -1
  76. package/front_end/ui/legacy/KeyboardShortcut.ts +4 -7
  77. package/front_end/ui/legacy/SearchableView.ts +2 -1
  78. package/front_end/ui/legacy/ShortcutRegistry.ts +6 -3
  79. package/front_end/ui/legacy/UIUtils.ts +10 -6
  80. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +23 -24
  81. package/front_end/ui/legacy/components/perf_ui/BrickBreaker.ts +2 -2
  82. package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +6 -6
  83. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +14 -15
  84. package/front_end/ui/legacy/components/perf_ui/GCActionDelegate.ts +1 -1
  85. package/front_end/ui/legacy/components/perf_ui/NetworkPriorities.ts +5 -5
  86. package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +5 -5
  87. package/front_end/ui/legacy/components/perf_ui/PieChart.ts +1 -1
  88. package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +4 -6
  89. package/front_end/ui/legacy/components/source_frame/FontView.ts +2 -2
  90. package/front_end/ui/legacy/components/source_frame/ImageView.ts +13 -13
  91. package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -1
  92. package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +2 -2
  93. package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +1 -1
  94. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +15 -18
  95. package/front_end/ui/legacy/components/source_frame/XMLView.ts +1 -1
  96. package/front_end/ui/legacy/components/source_frame/source_frame-meta.ts +10 -10
  97. package/front_end/ui/legacy/theme_support/ThemeSupport.ts +5 -2
  98. package/front_end/ui/settings/ConsoleSettings.ts +32 -0
  99. package/front_end/ui/settings/InspectorMainSettings.ts +7 -0
  100. package/front_end/ui/settings/MainSettings.ts +80 -0
  101. package/front_end/ui/settings/settings.ts +4 -0
  102. package/front_end/ui/visual_logging/KnownContextValues.ts +8 -0
  103. package/package.json +1 -1
@@ -213,6 +213,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
213
213
  private sectionBlocks: SectionBlock[] = [];
214
214
  private idleCallbackManager: IdleCallbackManager|null = null;
215
215
  private needsForceUpdate = false;
216
+ private isSuppressingResets = false;
216
217
  private readonly resizeThrottler = new Common.Throttler.Throttler(100);
217
218
  private readonly resetUpdateThrottler = new Common.Throttler.Throttler(500);
218
219
  private readonly computedStyleUpdateThrottler = new Common.Throttler.Throttler(500);
@@ -231,6 +232,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
231
232
  aiCodeCompletionProvider?: StylesAiCodeCompletionProvider.StylesAiCodeCompletionProvider;
232
233
  #aiCodeCompletionSummaryToolbarContainer?: HTMLElement;
233
234
  #aiCodeCompletionSummaryToolbar?: PanelsCommon.AiCodeCompletionSummaryToolbar.AiCodeCompletionSummaryToolbar;
235
+ #aiCodeCompletionEnabled = false;
234
236
  #shouldRenderLazily = false;
235
237
  #lazyRenderObserver?: IntersectionObserver;
236
238
  #lazyRenderCallbacks = new WeakMap<Element, () => void>();
@@ -252,13 +254,13 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
252
254
  this.sectionsContainer.show(this.contentElement);
253
255
  UI.ARIAUtils.markAsList(this.sectionsContainer.contentElement);
254
256
  this.sectionsContainer.contentElement.addEventListener('keydown', this.sectionsContainerKeyDown.bind(this), false);
255
- this.sectionsContainer.contentElement.addEventListener(
256
- 'focusin', this.sectionsContainerFocusChanged.bind(this), false);
257
- this.sectionsContainer.contentElement.addEventListener(
258
- 'focusout', this.sectionsContainerFocusChanged.bind(this), false);
257
+ this.sectionsContainer.contentElement.addEventListener('focusin', this.sectionsContainerFocusChanged.bind(this),
258
+ false);
259
+ this.sectionsContainer.contentElement.addEventListener('focusout', this.sectionsContainerFocusChanged.bind(this),
260
+ false);
259
261
 
260
- this.#swatchPopoverHelper.addEventListener(
261
- InlineEditor.SwatchPopoverHelper.Events.WILL_SHOW_POPOVER, this.hideAllPopovers, this);
262
+ this.#swatchPopoverHelper.addEventListener(InlineEditor.SwatchPopoverHelper.Events.WILL_SHOW_POPOVER,
263
+ this.hideAllPopovers, this);
262
264
  this.decorator = new StylePropertyHighlighter(this);
263
265
  this.contentElement.classList.add('styles-pane');
264
266
 
@@ -266,19 +268,19 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
266
268
  this.contentElement.addEventListener('copy', this.clipboardCopy.bind(this));
267
269
 
268
270
  this.boundOnScroll = this.onScroll.bind(this);
269
- this.imagePreviewPopover = new ImagePreviewPopover(
270
- this.contentElement,
271
- event => {
272
- const link = event.composedPath()[0];
273
- if (link instanceof Element) {
274
- return link;
275
- }
276
- return null;
277
- },
278
- async () => {
279
- const features = await Components.ImagePreview.loadPrecomputedFeatures(this.node());
280
- return features;
281
- });
271
+ this.imagePreviewPopover =
272
+ new ImagePreviewPopover(this.contentElement,
273
+ event => {
274
+ const link = event.composedPath()[0];
275
+ if (link instanceof Element) {
276
+ return link;
277
+ }
278
+ return null;
279
+ },
280
+ async () => {
281
+ const features = await Components.ImagePreview.loadPrecomputedFeatures(this.node());
282
+ return features;
283
+ });
282
284
 
283
285
  UI.ViewManager.ViewManager.instance().addEventListener(UI.ViewManager.Events.VIEW_VISIBILITY_CHANGED, event => {
284
286
  if (event.data.revealedViewId === 'animations' || event.data.hiddenViewId === 'animations') {
@@ -291,9 +293,11 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
291
293
  completionContext: {},
292
294
  generationContext: {},
293
295
  onFeatureEnabled: () => {
296
+ this.#aiCodeCompletionEnabled = true;
294
297
  this.#createAiCodeCompletionSummaryToolbar();
295
298
  },
296
299
  onFeatureDisabled: () => {
300
+ this.#aiCodeCompletionEnabled = false;
297
301
  this.#cleanupAiCodeCompletion();
298
302
  },
299
303
  onSuggestionAccepted: this.#onAiCodeCompletionSuggestionAccepted.bind(this),
@@ -325,6 +329,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
325
329
  }
326
330
 
327
331
  setUserOperation(userOperation: boolean): void {
332
+ if (userOperation) {
333
+ this.isSuppressingResets = false;
334
+ }
328
335
  this.userOperation = userOperation;
329
336
  }
330
337
 
@@ -465,23 +472,22 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
465
472
  const contextMenu = new UI.ContextMenu.ContextMenu(event);
466
473
  for (let i = 0; i < contextMenuDescriptors.length; ++i) {
467
474
  const descriptor = contextMenuDescriptors[i];
468
- contextMenu.defaultSection().appendItem(
469
- descriptor.text, descriptor.handler, {jslogContext: 'style-sheet-header'});
475
+ contextMenu.defaultSection().appendItem(descriptor.text, descriptor.handler,
476
+ {jslogContext: 'style-sheet-header'});
470
477
  }
471
- contextMenu.footerSection().appendItem(
472
- 'inspector-stylesheet', this.createNewRuleInViaInspectorStyleSheet.bind(this),
473
- {jslogContext: 'inspector-stylesheet'});
478
+ contextMenu.footerSection().appendItem('inspector-stylesheet',
479
+ this.createNewRuleInViaInspectorStyleSheet.bind(this),
480
+ {jslogContext: 'inspector-stylesheet'});
474
481
  void contextMenu.show();
475
482
 
476
- function compareDescriptors(
477
- descriptor1: {
478
- text: string,
479
- handler: () => Promise<void>,
480
- },
481
- descriptor2: {
482
- text: string,
483
- handler: () => Promise<void>,
484
- }): number {
483
+ function compareDescriptors(descriptor1: {
484
+ text: string,
485
+ handler: () => Promise<void>,
486
+ },
487
+ descriptor2: {
488
+ text: string,
489
+ handler: () => Promise<void>,
490
+ }): number {
485
491
  return Platform.StringUtilities.naturalOrderComparator(descriptor1.text, descriptor2.text);
486
492
  }
487
493
 
@@ -523,9 +529,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
523
529
  if (this.lastFilterChange) {
524
530
  const stillTyping = Date.now() - this.lastFilterChange < FILTER_IDLE_PERIOD;
525
531
  if (!stillTyping) {
526
- UI.ARIAUtils.LiveAnnouncer.alert(
527
- this.visibleSections ? i18nString(UIStrings.visibleSelectors, {n: this.visibleSections}) :
528
- i18nString(UIStrings.noMatchingSelectorOrStyle));
532
+ UI.ARIAUtils.LiveAnnouncer.alert(this.visibleSections ?
533
+ i18nString(UIStrings.visibleSelectors, {n: this.visibleSections}) :
534
+ i18nString(UIStrings.noMatchingSelectorOrStyle));
529
535
  }
530
536
  }
531
537
  }, FILTER_IDLE_PERIOD);
@@ -608,8 +614,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
608
614
 
609
615
  signal?.throwIfAborted();
610
616
 
611
- await this.innerRebuildUpdate(
612
- signal, this.matchedStyles, computedStyles, parentsComputedStyles, computedStyleExtraFields);
617
+ await this.innerRebuildUpdate(signal, this.matchedStyles, computedStyles, parentsComputedStyles,
618
+ computedStyleExtraFields);
613
619
 
614
620
  signal?.throwIfAborted();
615
621
 
@@ -637,17 +643,16 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
637
643
  return registration ? {registration, goToDefinition} : undefined;
638
644
  }
639
645
 
640
- getVariableParserError(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, variableName: string):
641
- ElementsComponents.CSSVariableValueView.CSSVariableParserError|null {
646
+ getVariableParserError(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
647
+ variableName: string): ElementsComponents.CSSVariableValueView.CSSVariableParserError|null {
642
648
  const registrationDetails = this.#getRegisteredPropertyDetails(matchedStyles, variableName);
643
649
  return registrationDetails ?
644
650
  new ElementsComponents.CSSVariableValueView.CSSVariableParserError(registrationDetails) :
645
651
  null;
646
652
  }
647
653
 
648
- getVariablePopoverContents(
649
- matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, variableName: string,
650
- computedValue: string|null): ElementsComponents.CSSVariableValueView.CSSVariableValueView {
654
+ getVariablePopoverContents(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, variableName: string,
655
+ computedValue: string|null): ElementsComponents.CSSVariableValueView.CSSVariableValueView {
651
656
  return new ElementsComponents.CSSVariableValueView.CSSVariableValueView({
652
657
  variableName,
653
658
  value: computedValue ?? undefined,
@@ -663,8 +668,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
663
668
  return await node.domModel().cssModel().getComputedStyle(nodeId);
664
669
  }
665
670
 
666
- private async fetchComputedStyleExtraFieldsFor(nodeId: Protocol.DOM.NodeId|undefined):
667
- Promise<Protocol.CSS.ComputedStyleExtraFields|null> {
671
+ private async fetchComputedStyleExtraFieldsFor(nodeId: Protocol.DOM.NodeId|
672
+ undefined): Promise<Protocol.CSS.ComputedStyleExtraFields|null> {
668
673
  const node = this.node();
669
674
  if (node === null || nodeId === undefined) {
670
675
  return null;
@@ -686,6 +691,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
686
691
  }
687
692
 
688
693
  private resetCache(): void {
694
+ this.isSuppressingResets = false;
689
695
  const cssModel = this.cssModel();
690
696
  if (cssModel) {
691
697
  cssModel.discardCachedMatchedCascade();
@@ -711,6 +717,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
711
717
  }
712
718
 
713
719
  setEditingStyle(editing: boolean): void {
720
+ if (editing) {
721
+ this.isSuppressingResets = false;
722
+ }
714
723
  if (this.isEditingStyle === editing) {
715
724
  return;
716
725
  }
@@ -743,8 +752,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
743
752
  if (!node) {
744
753
  continue;
745
754
  }
746
- node.domModel().overlayModel().highlightInOverlay(
747
- {node: (this.node() as SDK.DOMModel.DOMNode), selectorList}, mode);
755
+ node.domModel().overlayModel().highlightInOverlay({node: (this.node() as SDK.DOMModel.DOMNode), selectorList},
756
+ mode);
748
757
  this.isActivePropertyHighlighted = true;
749
758
  break;
750
759
  }
@@ -788,9 +797,17 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
788
797
  this.requestUpdate();
789
798
  }
790
799
 
800
+ suppressResets(): void {
801
+ this.isSuppressingResets = true;
802
+ }
803
+
791
804
  #scheduleResetUpdateIfNotEditing(): void {
792
805
  this.scheduleResetUpdateIfNotEditingCalledForTest();
793
806
 
807
+ if (this.isSuppressingResets) {
808
+ return;
809
+ }
810
+
794
811
  // Don't schedule if editing; the edit completion will handle the update.
795
812
  if (this.userOperation || this.isEditingStyle) {
796
813
  return;
@@ -805,10 +822,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
805
822
  }
806
823
 
807
824
  #hasAnimatedStyles(animatedStyles: Protocol.CSS.GetAnimatedStylesForNodeResponse): boolean {
808
- return Boolean(
809
- animatedStyles.animationStyles?.length || animatedStyles.transitionsStyle?.cssProperties.length ||
810
- animatedStyles.inherited?.some(
811
- inherited => inherited.animationStyles?.length || inherited.transitionsStyle?.cssProperties.length));
825
+ return Boolean(animatedStyles.animationStyles?.length || animatedStyles.transitionsStyle?.cssProperties.length ||
826
+ animatedStyles.inherited?.some(inherited => inherited.animationStyles?.length ||
827
+ inherited.transitionsStyle?.cssProperties.length));
812
828
  }
813
829
 
814
830
  async #updateAnimatedStyles(): Promise<void> {
@@ -828,8 +844,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
828
844
 
829
845
  if (!this.#hasAnimatedStyles(animatedStyles)) {
830
846
  // A computed style change that doesn't correspond to any animation is
831
- // likely to be a change in the matched styles. In this case, we should
832
- // update the matched styles.
847
+ // likely to be a change in the matched styles, which is already handled
848
+ // by CSSModelChanged events. We still schedule a reset update here for
849
+ // DevTools garbage collection purposes.
833
850
  this.#scheduleResetUpdateIfNotEditing();
834
851
  return;
835
852
  }
@@ -838,40 +855,39 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
838
855
  return;
839
856
  }
840
857
 
841
- const updateStyleSection =
842
- (currentStyle: SDK.CSSStyleDeclaration.CSSStyleDeclaration|null, newStyle: Protocol.CSS.CSSStyle|null):
843
- void => {
844
- // The newly fetched matched styles contain a new style.
845
- if (newStyle) {
846
- // If the number of CSS properties in the new style
847
- // differs from the current style, it indicates a potential change
848
- // in property overrides. In this case, re-fetch the entire style
849
- // cascade to ensure accurate updates.
850
- if (currentStyle?.allProperties().length !== newStyle.cssProperties.length) {
851
- this.#scheduleResetUpdateIfNotEditing();
852
- return;
853
- }
854
-
855
- // If the number of properties remains the same, update the
856
- // existing style properties with the new values from the
857
- // fetched style.
858
- currentStyle.allProperties().forEach((property, index) => {
859
- const newProperty = newStyle.cssProperties[index];
860
- if (!newProperty) {
861
- return;
862
- }
863
-
864
- property.setLocalValue(newProperty.value);
865
- });
866
- } else if (currentStyle) {
867
- // If no new style is fetched while a current style exists,
868
- // it implies the style has been removed (e.g., animation or
869
- // transition ended). Trigger a reset and update the UI to
870
- // reflect this change.
871
- this.#scheduleResetUpdateIfNotEditing();
872
- return;
873
- }
874
- };
858
+ const updateStyleSection = (currentStyle: SDK.CSSStyleDeclaration.CSSStyleDeclaration|null,
859
+ newStyle: Protocol.CSS.CSSStyle|null): void => {
860
+ // The newly fetched matched styles contain a new style.
861
+ if (newStyle) {
862
+ // If the number of CSS properties in the new style
863
+ // differs from the current style, it indicates a potential change
864
+ // in property overrides. In this case, re-fetch the entire style
865
+ // cascade to ensure accurate updates.
866
+ if (currentStyle?.allProperties().length !== newStyle.cssProperties.length) {
867
+ this.#scheduleResetUpdateIfNotEditing();
868
+ return;
869
+ }
870
+
871
+ // If the number of properties remains the same, update the
872
+ // existing style properties with the new values from the
873
+ // fetched style.
874
+ currentStyle.allProperties().forEach((property, index) => {
875
+ const newProperty = newStyle.cssProperties[index];
876
+ if (!newProperty) {
877
+ return;
878
+ }
879
+
880
+ property.setLocalValue(newProperty.value);
881
+ });
882
+ } else if (currentStyle) {
883
+ // If no new style is fetched while a current style exists,
884
+ // it implies the style has been removed (e.g., animation or
885
+ // transition ended). Trigger a reset and update the UI to
886
+ // reflect this change.
887
+ this.#scheduleResetUpdateIfNotEditing();
888
+ return;
889
+ }
890
+ };
875
891
 
876
892
  updateStyleSection(this.matchedStyles.transitionsStyle() ?? null, animatedStyles.transitionsStyle ?? null);
877
893
 
@@ -894,9 +910,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
894
910
  inheritedStyles.filter(style => style.type === SDK.CSSStyleDeclaration.Type.Transition);
895
911
  const newInheritedTransitionsStyles =
896
912
  animatedStyles.inherited?.map(inherited => inherited.transitionsStyle)
897
- .filter(
898
- style => style?.cssProperties.some(
899
- cssProperty => SDK.CSSMetadata.cssMetadata().isPropertyInherited(cssProperty.name))) ??
913
+ .filter(style => style?.cssProperties.some(
914
+ cssProperty => SDK.CSSMetadata.cssMetadata().isPropertyInherited(cssProperty.name))) ??
900
915
  [];
901
916
  if (currentInheritedTransitionsStyles.length !== newInheritedTransitionsStyles.length) {
902
917
  this.#scheduleResetUpdateIfNotEditing();
@@ -913,9 +928,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
913
928
  inheritedStyles.filter(style => style.type === SDK.CSSStyleDeclaration.Type.Animation);
914
929
  const newInheritedAnimationsStyles =
915
930
  animatedStyles.inherited?.flatMap(inherited => inherited.animationStyles)
916
- .filter(
917
- animationStyle => animationStyle?.style.cssProperties.some(
918
- cssProperty => SDK.CSSMetadata.cssMetadata().isPropertyInherited(cssProperty.name))) ??
931
+ .filter(animationStyle => animationStyle?.style.cssProperties.some(
932
+ cssProperty => SDK.CSSMetadata.cssMetadata().isPropertyInherited(cssProperty.name))) ??
919
933
  [];
920
934
  if (currentInheritedAnimationsStyles.length !== newInheritedAnimationsStyles.length) {
921
935
  this.#scheduleResetUpdateIfNotEditing();
@@ -976,10 +990,12 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
976
990
  }
977
991
  }
978
992
 
979
- private async innerRebuildUpdate(
980
- signal: AbortSignal|undefined, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null,
981
- computedStyles: Map<string, string>|null, parentsComputedStyles: Map<string, string>|null,
982
- computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): Promise<void> {
993
+ private async innerRebuildUpdate(signal: AbortSignal|undefined,
994
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null,
995
+ computedStyles: Map<string, string>|null,
996
+ parentsComputedStyles: Map<string, string>|null,
997
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|
998
+ null): Promise<void> {
983
999
  // ElementsSidebarPane's throttler schedules this method. Usually,
984
1000
  // rebuild is suppressed while editing (see onCSSModelChanged()), but we need a
985
1001
  // 'force' flag since the currently running throttler process cannot be canceled.
@@ -1005,9 +1021,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1005
1021
  return;
1006
1022
  }
1007
1023
 
1008
- const blocks = await this.rebuildSectionsForMatchedStyleRules(
1009
- signal, (matchedStyles as SDK.CSSMatchedStyles.CSSMatchedStyles), computedStyles, parentsComputedStyles,
1010
- computedStyleExtraFields);
1024
+ const blocks =
1025
+ await this.rebuildSectionsForMatchedStyleRules(signal, (matchedStyles as SDK.CSSMatchedStyles.CSSMatchedStyles),
1026
+ computedStyles, parentsComputedStyles, computedStyleExtraFields);
1011
1027
 
1012
1028
  signal?.throwIfAborted();
1013
1029
 
@@ -1087,18 +1103,21 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1087
1103
  this.matchedStyles = matchedStyles;
1088
1104
  }
1089
1105
 
1090
- rebuildSectionsForMatchedStyleRulesForTest(
1091
- matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>|null,
1092
- parentsComputedStyles: Map<string, string>|null,
1093
- computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): Promise<SectionBlock[]> {
1094
- return this.rebuildSectionsForMatchedStyleRules(
1095
- undefined, matchedStyles, computedStyles, parentsComputedStyles, computedStyleExtraFields);
1106
+ rebuildSectionsForMatchedStyleRulesForTest(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
1107
+ computedStyles: Map<string, string>|null,
1108
+ parentsComputedStyles: Map<string, string>|null,
1109
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|
1110
+ null): Promise<SectionBlock[]> {
1111
+ return this.rebuildSectionsForMatchedStyleRules(undefined, matchedStyles, computedStyles, parentsComputedStyles,
1112
+ computedStyleExtraFields);
1096
1113
  }
1097
1114
 
1098
- private async rebuildSectionsForMatchedStyleRules(
1099
- signal: AbortSignal|undefined, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
1100
- computedStyles: Map<string, string>|null, parentsComputedStyles: Map<string, string>|null,
1101
- computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): Promise<SectionBlock[]> {
1115
+ private async rebuildSectionsForMatchedStyleRules(signal: AbortSignal|undefined,
1116
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
1117
+ computedStyles: Map<string, string>|null,
1118
+ parentsComputedStyles: Map<string, string>|null,
1119
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|
1120
+ null): Promise<SectionBlock[]> {
1102
1121
  if (this.idleCallbackManager) {
1103
1122
  this.idleCallbackManager.discard();
1104
1123
  }
@@ -1164,8 +1183,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1164
1183
  if (signal?.aborted) {
1165
1184
  return;
1166
1185
  }
1167
- const section = new StylePropertiesSection(
1168
- this, matchedStyles, style, sectionIdx, computedStyles, parentsComputedStyles, computedStyleExtraFields);
1186
+ const section = new StylePropertiesSection(this, matchedStyles, style, sectionIdx, computedStyles,
1187
+ parentsComputedStyles, computedStyleExtraFields);
1169
1188
  sectionIdx++;
1170
1189
  lastBlock.sections.push(section);
1171
1190
  });
@@ -1284,8 +1303,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1284
1303
  if (signal?.aborted) {
1285
1304
  return;
1286
1305
  }
1287
- block.sections.push(new PositionTryRuleSection(
1288
- this, matchedStyles, positionTryRule.style, sectionIdx, positionTryRule.active()));
1306
+ block.sections.push(new PositionTryRuleSection(this, matchedStyles, positionTryRule.style, sectionIdx,
1307
+ positionTryRule.active()));
1289
1308
  sectionIdx++;
1290
1309
  });
1291
1310
  blocks.push(block);
@@ -1299,8 +1318,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1299
1318
  if (signal?.aborted) {
1300
1319
  return;
1301
1320
  }
1302
- block.sections.push(new RegisteredPropertiesSection(
1303
- this, matchedStyles, propertyRule.style(), sectionIdx, propertyRule.propertyName(), expandedByDefault));
1321
+ block.sections.push(new RegisteredPropertiesSection(this, matchedStyles, propertyRule.style(), sectionIdx,
1322
+ propertyRule.propertyName(), expandedByDefault));
1304
1323
  sectionIdx++;
1305
1324
  });
1306
1325
  }
@@ -1315,9 +1334,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1315
1334
  if (signal?.aborted) {
1316
1335
  return;
1317
1336
  }
1318
- block.sections.push(new FunctionRuleSection(
1319
- this, matchedStyles, functionRule.style, functionRule.children(), sectionIdx,
1320
- functionRule.nameWithParameters(), expandedByDefault));
1337
+ block.sections.push(new FunctionRuleSection(this, matchedStyles, functionRule.style, functionRule.children(),
1338
+ sectionIdx, functionRule.nameWithParameters(),
1339
+ expandedByDefault));
1321
1340
  sectionIdx++;
1322
1341
  });
1323
1342
  }
@@ -1353,8 +1372,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1353
1372
  await this.createNewRuleInStyleSheet(styleSheetHeader);
1354
1373
  }
1355
1374
 
1356
- private async createNewRuleInStyleSheet(styleSheetHeader: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|null):
1357
- Promise<void> {
1375
+ private async createNewRuleInStyleSheet(styleSheetHeader: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader|
1376
+ null): Promise<void> {
1358
1377
  if (!styleSheetHeader) {
1359
1378
  return;
1360
1379
  }
@@ -1368,13 +1387,13 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1368
1387
  }
1369
1388
  }
1370
1389
 
1371
- addBlankSection(
1372
- insertAfterSection: StylePropertiesSection, styleSheetHeader: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader,
1373
- ruleLocation: TextUtils.TextRange.TextRange): void {
1390
+ addBlankSection(insertAfterSection: StylePropertiesSection,
1391
+ styleSheetHeader: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader,
1392
+ ruleLocation: TextUtils.TextRange.TextRange): void {
1374
1393
  const node = this.node();
1375
- const blankSection = new BlankStylePropertiesSection(
1376
- this, insertAfterSection.matchedStyles, node ? node.simpleSelector() : '', styleSheetHeader, ruleLocation,
1377
- insertAfterSection.style(), 0);
1394
+ const blankSection =
1395
+ new BlankStylePropertiesSection(this, insertAfterSection.matchedStyles, node ? node.simpleSelector() : '',
1396
+ styleSheetHeader, ruleLocation, insertAfterSection.style(), 0);
1378
1397
 
1379
1398
  this.sectionsContainer.contentElement.insertBefore(blankSection.element, insertAfterSection.element.nextSibling);
1380
1399
 
@@ -1425,6 +1444,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1425
1444
  override wasShown(): void {
1426
1445
  UI.Context.Context.instance().setFlavor(StylesSidebarPane, this);
1427
1446
  super.wasShown();
1447
+ if (this.#aiCodeCompletionEnabled && !this.#aiCodeCompletionSummaryToolbar) {
1448
+ this.#createAiCodeCompletionSummaryToolbar();
1449
+ }
1428
1450
  }
1429
1451
 
1430
1452
  override willHide(): void {
@@ -1464,9 +1486,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1464
1486
  const hbox = container.createChild('div', 'hbox styles-sidebar-pane-toolbar');
1465
1487
  const toolbar = hbox.createChild('devtools-toolbar', 'styles-pane-toolbar');
1466
1488
  toolbar.role = 'presentation';
1467
- const filterInput = new UI.Toolbar.ToolbarFilter(
1468
- undefined, 1, 1, undefined, undefined, false, undefined, undefined, /* showRegexToggle=*/ true,
1469
- this.onRegexToggled.bind(this));
1489
+ const filterInput = new UI.Toolbar.ToolbarFilter(undefined, 1, 1, undefined, undefined, false, undefined, undefined,
1490
+ /* showRegexToggle=*/ true, this.onRegexToggled.bind(this));
1470
1491
  filterInput.addEventListener(UI.Toolbar.ToolbarInput.Event.TEXT_CHANGED, this.onFilterChanged, this);
1471
1492
  toolbar.appendToolbarItem(filterInput);
1472
1493
  void toolbar.appendItemsAtLocation('styles-sidebarpane-toolbar');
@@ -1565,8 +1586,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1565
1586
  Common.Settings.Settings.instance().resolve(SDK.SDKSettings.emulateAutoDarkModeSettingDescriptor);
1566
1587
  const decorateStatus = (condition: boolean, title: string): string => `${condition ? '✓ ' : ''}${title}`;
1567
1588
 
1568
- const button = new UI.Toolbar.ToolbarToggle(
1569
- i18nString(UIStrings.toggleRenderingEmulations), 'brush', 'brush-filled', undefined, false);
1589
+ const button = new UI.Toolbar.ToolbarToggle(i18nString(UIStrings.toggleRenderingEmulations), 'brush',
1590
+ 'brush-filled', undefined, false);
1570
1591
  button.element.setAttribute('jslog', `${VisualLogging.dropDown('rendering-emulations').track({click: true})}`);
1571
1592
  button.element.addEventListener('click', event => {
1572
1593
  const boundingRect = button.element.getBoundingClientRect();
@@ -1611,7 +1632,12 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1611
1632
  }
1612
1633
 
1613
1634
  #createAiCodeCompletionSummaryToolbar(): void {
1614
- if (this.#aiCodeCompletionSummaryToolbar) {
1635
+ if (!this.#aiCodeCompletionEnabled || this.#aiCodeCompletionSummaryToolbar) {
1636
+ return;
1637
+ }
1638
+ const containingPane =
1639
+ this.contentElement.enclosingNodeOrSelfWithClass('style-panes-wrapper') as HTMLElement | null;
1640
+ if (!containingPane) {
1615
1641
  return;
1616
1642
  }
1617
1643
  this.#aiCodeCompletionSummaryToolbar =
@@ -1621,7 +1647,6 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1621
1647
  spinnerTooltipId: SPINNER_TOOLTIP_ID,
1622
1648
  disclaimerTextVariant: 'styles',
1623
1649
  });
1624
- const containingPane = this.contentElement.enclosingNodeOrSelfWithClass('style-panes-wrapper') as HTMLElement;
1625
1650
  this.#aiCodeCompletionSummaryToolbarContainer =
1626
1651
  containingPane.createChild('div', 'ai-code-completion-summary-toolbar-container');
1627
1652
  this.#aiCodeCompletionSummaryToolbarContainer.role = 'toolbar';
@@ -1782,9 +1807,8 @@ export class SectionBlock {
1782
1807
  return new SectionBlock(separatorElement);
1783
1808
  }
1784
1809
 
1785
- static async createInheritedPseudoTypeBlock(
1786
- pseudoType: Protocol.DOM.PseudoType, pseudoArgument: string|null,
1787
- node: SDK.DOMModel.DOMNode): Promise<SectionBlock> {
1810
+ static async createInheritedPseudoTypeBlock(pseudoType: Protocol.DOM.PseudoType, pseudoArgument: string|null,
1811
+ node: SDK.DOMModel.DOMNode): Promise<SectionBlock> {
1788
1812
  const separatorElement = document.createElement('div');
1789
1813
  separatorElement.className = 'sidebar-separator';
1790
1814
  separatorElement.setAttribute('jslog', `${VisualLogging.sectionHeader('inherited-pseudotype')}`);
@@ -2141,9 +2165,8 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2141
2165
 
2142
2166
  // Handle numeric value increment/decrement only at this point.
2143
2167
  if (!this.isEditingName && this.treeElement.valueElement &&
2144
- UI.UIUtils.handleElementValueModifications(
2145
- event, this.treeElement.valueElement, finishHandler.bind(this), this.isValueSuggestion.bind(this),
2146
- customNumberHandler.bind(this))) {
2168
+ UI.UIUtils.handleElementValueModifications(event, this.treeElement.valueElement, finishHandler.bind(this),
2169
+ this.isValueSuggestion.bind(this), customNumberHandler.bind(this))) {
2147
2170
  return true;
2148
2171
  }
2149
2172
 
@@ -2158,8 +2181,8 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2158
2181
  return this.cssCompletions.indexOf(word) !== -1 || word.startsWith('--');
2159
2182
  }
2160
2183
 
2161
- private async buildPropertyCompletions(expression: string, query: string, force?: boolean):
2162
- Promise<UI.SuggestBox.Suggestions> {
2184
+ private async buildPropertyCompletions(expression: string, query: string,
2185
+ force?: boolean): Promise<UI.SuggestBox.Suggestions> {
2163
2186
  const lowerQuery = query.toLowerCase();
2164
2187
  const editingVariable = !this.isEditingName && expression.trim().endsWith('var(');
2165
2188
  if (this.isEditingName && expression) {
@@ -2204,8 +2227,8 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2204
2227
  const node = this.treeElement.node();
2205
2228
  if (this.isEditingName && node) {
2206
2229
  const nameValuePresets = SDK.CSSMetadata.cssMetadata().nameValuePresets(node.isSVGNode());
2207
- nameValuePresets.forEach(
2208
- preset => filterCompletions.call(this, preset, false /* variable */, true /* nameValue */));
2230
+ nameValuePresets.forEach(preset =>
2231
+ filterCompletions.call(this, preset, false /* variable */, true /* nameValue */));
2209
2232
  }
2210
2233
  if (this.isEditingName || editingVariable) {
2211
2234
  this.cssVariables.forEach(variable => filterCompletions.call(this, variable, true /* variable */));
@@ -2285,8 +2308,8 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2285
2308
  }
2286
2309
  return await Promise.resolve(results);
2287
2310
 
2288
- function filterCompletions(
2289
- this: CSSPropertyPrompt, completion: string, variable: boolean, nameValue?: boolean): void {
2311
+ function filterCompletions(this: CSSPropertyPrompt, completion: string, variable: boolean,
2312
+ nameValue?: boolean): void {
2290
2313
  const index = completion.toLowerCase().indexOf(lowerQuery);
2291
2314
  const result: CompletionResult = {
2292
2315
  text: completion,
@@ -2377,8 +2400,8 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2377
2400
  if (!cssModel) {
2378
2401
  return;
2379
2402
  }
2380
- await this.aiCodeCompletionProvider.triggerAiCodeCompletion(
2381
- userInput, range.endOffset, this.isEditingName, this.treeElement.property, cssModel);
2403
+ await this.aiCodeCompletionProvider.triggerAiCodeCompletion(userInput, range.endOffset, this.isEditingName,
2404
+ this.treeElement.property, cssModel);
2382
2405
  }
2383
2406
 
2384
2407
  private setAiAutoCompletion(args: {
@@ -2521,9 +2544,9 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2521
2544
  const suggestionText = this.treeElement.section().activeAiSuggestion?.text;
2522
2545
  await this.treeElement.section().commitActiveAiSuggestion();
2523
2546
  if (this.activeAiSuggestionInfo) {
2524
- this.aiCodeCompletionProvider?.onSuggestionAccepted(
2525
- this.activeAiSuggestionInfo.citations, this.activeAiSuggestionInfo.rpcGlobalId,
2526
- this.activeAiSuggestionInfo.sampleId);
2547
+ this.aiCodeCompletionProvider?.onSuggestionAccepted(this.activeAiSuggestionInfo.citations,
2548
+ this.activeAiSuggestionInfo.rpcGlobalId,
2549
+ this.activeAiSuggestionInfo.sampleId);
2527
2550
  }
2528
2551
  if (suggestionText) {
2529
2552
  UI.ARIAUtils.LiveAnnouncer.status(i18nString(UIStrings.aiSuggestionAccepted, {PH1: suggestionText}));