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.
- package/AUTHORS +1 -0
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -7
- package/front_end/core/sdk/StorageBucketsModel.ts +0 -6
- package/front_end/entrypoints/inspector_main/InspectorMain.ts +2 -1
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +1 -5
- package/front_end/entrypoints/main/MainImpl.ts +6 -4
- package/front_end/entrypoints/main/main-meta.ts +9 -51
- package/front_end/foundation/Universe.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +12 -22
- package/front_end/generated/protocol-mapping.d.ts +9 -59
- package/front_end/generated/protocol-proxy-api.d.ts +7 -47
- package/front_end/generated/protocol.ts +105 -330
- package/front_end/models/ai_assistance/AiAgent2.ts +12 -4
- package/front_end/models/ai_assistance/AiConversation.ts +25 -7
- package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -19
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +6 -6
- package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
- package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +12 -6
- package/front_end/models/ai_assistance/tools/GetStorageValues.ts +1 -1
- package/front_end/models/ai_assistance/tools/ListStorageKeys.ts +1 -1
- package/front_end/models/ai_assistance/tools/RunLighthouse.ts +5 -8
- package/front_end/models/ai_assistance/tools/Tool.ts +19 -6
- package/front_end/models/issues_manager/DOMIssuesManager.ts +144 -0
- package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +13 -1
- package/front_end/models/issues_manager/GenericIssue.ts +14 -2
- package/front_end/models/issues_manager/IssuesManager.ts +0 -1
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
- package/front_end/models/trace/Processor.ts +1 -0
- package/front_end/panels/ai_assistance/ExternalHandler.ts +89 -0
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/application/BackgroundServiceModel.ts +4 -3
- package/front_end/panels/application/IndexedDBModel.ts +0 -7
- package/front_end/panels/console/ConsoleView.ts +17 -16
- package/front_end/panels/console/ConsoleViewMessage.ts +4 -1
- package/front_end/panels/console/console-meta.ts +4 -19
- package/front_end/panels/elements/ElementIssueUtils.ts +10 -2
- package/front_end/panels/elements/ElementsPanel.ts +8 -3
- package/front_end/panels/elements/ElementsTreeElement.ts +82 -161
- package/front_end/panels/elements/ElementsTreeOutline.ts +26 -105
- package/front_end/panels/elements/StandaloneStylesContainer.ts +5 -11
- package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -0
- package/front_end/panels/elements/StylesContainer.ts +1 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +174 -151
- package/front_end/panels/network/RequestPayloadView.ts +5 -2
- package/front_end/panels/security/SecurityPanelSidebar.ts +0 -32
- package/front_end/panels/settings/KeybindsSettingsTab.ts +5 -2
- package/front_end/panels/sources/SourcesPanel.ts +6 -3
- package/front_end/panels/timeline/components/BreadcrumbsUI.ts +2 -6
- package/front_end/panels/timeline/components/CWVMetrics.ts +9 -10
- package/front_end/panels/timeline/components/DetailsView.ts +12 -16
- package/front_end/panels/timeline/components/ExportTraceOptions.ts +13 -13
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +19 -19
- package/front_end/panels/timeline/components/IgnoreListSetting.ts +7 -9
- package/front_end/panels/timeline/components/InteractionBreakdown.ts +3 -3
- package/front_end/panels/timeline/components/LayoutShiftDetails.ts +13 -13
- package/front_end/panels/timeline/components/LiveMetricsView.ts +64 -64
- package/front_end/panels/timeline/components/MetricCard.ts +25 -25
- package/front_end/panels/timeline/components/NetworkRequestDetails.ts +22 -22
- package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +9 -9
- package/front_end/panels/timeline/components/OriginMap.ts +7 -7
- package/front_end/panels/timeline/components/RelatedInsightChips.ts +2 -2
- package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +19 -20
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
- package/front_end/panels/timeline/components/TimelineSummary.ts +2 -2
- package/front_end/panels/timeline/components/Utils.ts +2 -6
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +6 -9
- package/front_end/panels/timeline/components/insights/Checklist.ts +2 -2
- package/front_end/panels/timeline/components/insights/Table.ts +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/comments/CommentAnchorResolver.ts +94 -0
- package/front_end/ui/comments/CommentOverlayManager.ts +16 -32
- package/front_end/ui/components/text_editor/config.ts +2 -1
- package/front_end/ui/legacy/DockController.ts +4 -1
- package/front_end/ui/legacy/InspectorView.ts +3 -1
- package/front_end/ui/legacy/KeyboardShortcut.ts +4 -7
- package/front_end/ui/legacy/SearchableView.ts +2 -1
- package/front_end/ui/legacy/ShortcutRegistry.ts +6 -3
- package/front_end/ui/legacy/UIUtils.ts +10 -6
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +23 -24
- package/front_end/ui/legacy/components/perf_ui/BrickBreaker.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +6 -6
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +14 -15
- package/front_end/ui/legacy/components/perf_ui/GCActionDelegate.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/NetworkPriorities.ts +5 -5
- package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +5 -5
- package/front_end/ui/legacy/components/perf_ui/PieChart.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +4 -6
- package/front_end/ui/legacy/components/source_frame/FontView.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +13 -13
- package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +15 -18
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/source_frame-meta.ts +10 -10
- package/front_end/ui/legacy/theme_support/ThemeSupport.ts +5 -2
- package/front_end/ui/settings/ConsoleSettings.ts +32 -0
- package/front_end/ui/settings/InspectorMainSettings.ts +7 -0
- package/front_end/ui/settings/MainSettings.ts +80 -0
- package/front_end/ui/settings/settings.ts +4 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +8 -0
- 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
|
-
|
|
257
|
-
this.sectionsContainer.contentElement.addEventListener(
|
|
258
|
-
|
|
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
|
-
|
|
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 =
|
|
270
|
-
this.contentElement,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
475
|
+
contextMenu.defaultSection().appendItem(descriptor.text, descriptor.handler,
|
|
476
|
+
{jslogContext: 'style-sheet-header'});
|
|
470
477
|
}
|
|
471
|
-
contextMenu.footerSection().appendItem(
|
|
472
|
-
|
|
473
|
-
|
|
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
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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
|
-
|
|
528
|
-
|
|
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
|
-
|
|
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,
|
|
641
|
-
|
|
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
|
-
|
|
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|
|
|
667
|
-
|
|
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
|
-
|
|
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
|
-
|
|
810
|
-
|
|
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
|
|
832
|
-
// update
|
|
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
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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 =
|
|
1009
|
-
signal, (matchedStyles as SDK.CSSMatchedStyles.CSSMatchedStyles),
|
|
1010
|
-
|
|
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
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1320
|
-
|
|
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|
|
|
1357
|
-
|
|
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
|
-
|
|
1373
|
-
|
|
1390
|
+
addBlankSection(insertAfterSection: StylePropertiesSection,
|
|
1391
|
+
styleSheetHeader: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader,
|
|
1392
|
+
ruleLocation: TextUtils.TextRange.TextRange): void {
|
|
1374
1393
|
const node = this.node();
|
|
1375
|
-
const blankSection =
|
|
1376
|
-
this, insertAfterSection.matchedStyles, node ? node.simpleSelector() : '',
|
|
1377
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
2162
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2526
|
-
|
|
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}));
|