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.
- package/.stylelintrc.json +3 -1
- package/docs/ui_engineering.md +0 -36
- package/front_end/core/common/Console.ts +6 -6
- package/front_end/core/common/Settings.ts +12 -8
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/root/DevToolsContext.ts +13 -7
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/CPUThrottlingManager.ts +12 -9
- package/front_end/core/sdk/DOMModel.ts +206 -0
- package/front_end/core/sdk/FrameManager.ts +7 -8
- package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/floaty.css +2 -2
- package/front_end/entrypoints/main/MainImpl.ts +1 -7
- package/front_end/foundation/Universe.ts +22 -11
- package/front_end/generated/InspectorBackendCommands.ts +7 -0
- package/front_end/generated/protocol-mapping.d.ts +16 -0
- package/front_end/generated/protocol-proxy-api.d.ts +25 -0
- package/front_end/generated/protocol.ts +71 -0
- package/front_end/models/ai_assistance/AiConversation.ts +6 -95
- package/front_end/models/ai_assistance/ConversationHandler.ts +1 -1
- package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +14 -0
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +3 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +73 -35
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -6
- package/front_end/panels/ai_assistance/components/chatMessage.css +4 -2
- package/front_end/panels/application/IndexedDBModel.ts +2 -4
- package/front_end/panels/application/ServiceWorkersView.ts +3 -11
- package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
- package/front_end/panels/elements/ComputedStyleWidget.ts +25 -16
- package/front_end/panels/elements/ElementsPanel.ts +0 -1
- package/front_end/panels/elements/StandaloneStylesContainer.ts +48 -12
- package/front_end/panels/elements/StylePropertiesSection.ts +97 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +27 -5
- package/front_end/panels/elements/StylesContainer.ts +1 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +48 -32
- package/front_end/panels/elements/nodeStackTraceWidget.css +1 -1
- package/front_end/panels/elements/stylePropertiesTreeOutline.css +1 -1
- package/front_end/panels/emulation/DeviceModeToolbar.ts +171 -89
- package/front_end/panels/greendev/GreenDevPanel.css +2 -2
- package/front_end/panels/issues/AffectedPermissionElementsView.ts +9 -6
- package/front_end/panels/lighthouse/LighthouseController.ts +13 -5
- package/front_end/panels/lighthouse/LighthousePanel.ts +22 -5
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +11 -3
- package/front_end/panels/recorder/components/StepView.ts +0 -2
- package/front_end/panels/recorder/components/stepView.css +13 -13
- package/front_end/panels/recorder/components/timelineSection.css +6 -7
- package/front_end/panels/settings/components/SyncSection.ts +4 -13
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +2 -15
- package/front_end/panels/timeline/RecordingMetadata.ts +1 -1
- package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +18 -0
- package/front_end/panels/timeline/TimelineUIUtils.ts +7 -4
- package/front_end/panels/timeline/components/CWVMetrics.ts +339 -0
- package/front_end/panels/timeline/components/Sidebar.ts +17 -0
- package/front_end/panels/timeline/components/SidebarInsightsTab.ts +10 -0
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +25 -267
- package/front_end/panels/timeline/components/Utils.ts +2 -2
- package/front_end/panels/timeline/components/components.ts +2 -0
- package/front_end/panels/timeline/components/cwvMetrics.css +107 -0
- package/front_end/panels/timeline/components/sidebarSingleInsightSet.css +0 -102
- package/front_end/panels/timeline/timeline-meta.ts +11 -0
- package/front_end/panels/timeline/utils/Helpers.ts +5 -1
- package/front_end/panels/webauthn/webauthnPane.css +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +7 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +5 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +7 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +14 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +7 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +5 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +7 -0
- package/front_end/third_party/puppeteer/package/package.json +1 -1
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +8 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +4 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +7 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +6 -0
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/text_editor/AutocompleteHistory.ts +89 -5
- package/front_end/ui/components/tree_outline/TreeOutline.ts +1 -1
- package/front_end/ui/legacy/ProgressIndicator.ts +1 -1
- package/front_end/ui/legacy/Toolbar.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/inspector_overlay/loadCSS.rollup.js +2 -2
- package/inspector_overlay/tool_source_order.css +1 -0
- package/package.json +1 -1
- package/front_end/ui/legacy/Fragment.ts +0 -234
|
@@ -11,7 +11,9 @@ import * as i18n from '../../../core/i18n/i18n.js';
|
|
|
11
11
|
import type * as Platform from '../../../core/platform/platform.js';
|
|
12
12
|
import * as Root from '../../../core/root/root.js';
|
|
13
13
|
import * as SDK from '../../../core/sdk/sdk.js';
|
|
14
|
-
import type
|
|
14
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
|
15
|
+
import type {
|
|
16
|
+
AiWidget, ComputedStyleAiWidget, CoreVitalsAiWidget} from '../../../models/ai_assistance/agents/AiAgent.js';
|
|
15
17
|
import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
|
|
16
18
|
import * as ComputedStyle from '../../../models/computed_style/computed_style.js';
|
|
17
19
|
import * as Marked from '../../../third_party/marked/marked.js';
|
|
@@ -24,6 +26,8 @@ import * as UI from '../../../ui/legacy/legacy.js';
|
|
|
24
26
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
25
27
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
26
28
|
import * as Elements from '../../elements/elements.js';
|
|
29
|
+
import * as TimelineComponents from '../../timeline/components/components.js';
|
|
30
|
+
import * as TimelineUtils from '../../timeline/utils/utils.js';
|
|
27
31
|
|
|
28
32
|
import chatMessageStyles from './chatMessage.css.js';
|
|
29
33
|
import {walkthroughTitle, WalkthroughView} from './WalkthroughView.js';
|
|
@@ -278,6 +282,7 @@ export interface MessageInput {
|
|
|
278
282
|
isExpanded: boolean,
|
|
279
283
|
onToggle: (isOpen: boolean) => void,
|
|
280
284
|
isInlined: boolean,
|
|
285
|
+
activeMessage: ModelChatMessage|null,
|
|
281
286
|
};
|
|
282
287
|
}
|
|
283
288
|
|
|
@@ -483,14 +488,18 @@ function renderStepDetails({
|
|
|
483
488
|
|
|
484
489
|
function renderWalkthroughSidebarButton(
|
|
485
490
|
input: ChatMessageViewInput,
|
|
486
|
-
|
|
491
|
+
steps: Step[],
|
|
487
492
|
): Lit.LitTemplate {
|
|
488
493
|
const {message, walkthrough} = input;
|
|
489
|
-
|
|
494
|
+
const lastStep = steps.at(-1);
|
|
495
|
+
if (walkthrough.isInlined || !lastStep) {
|
|
490
496
|
return Lit.nothing;
|
|
491
497
|
}
|
|
498
|
+
|
|
499
|
+
const hasOneStepWithWidget = steps.some(step => step.widgets?.length);
|
|
492
500
|
const title = walkthroughTitle({
|
|
493
501
|
isLoading: input.isLoading,
|
|
502
|
+
hasWidgets: hasOneStepWithWidget,
|
|
494
503
|
lastStep,
|
|
495
504
|
});
|
|
496
505
|
|
|
@@ -505,7 +514,7 @@ function renderWalkthroughSidebarButton(
|
|
|
505
514
|
.jslogContext=${walkthrough.isExpanded ? 'ai-hide-walkthrough-sidebar' : 'ai-show-walkthrough-sidebar'}
|
|
506
515
|
data-show-walkthrough
|
|
507
516
|
@click=${() => {
|
|
508
|
-
if(walkthrough.isExpanded) {
|
|
517
|
+
if(walkthrough.activeMessage === input.message && walkthrough.isExpanded) {
|
|
509
518
|
walkthrough.onToggle(false);
|
|
510
519
|
} else {
|
|
511
520
|
// Can't just toggle the visibility here; we need to ensure we
|
|
@@ -535,7 +544,7 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
535
544
|
// If the walkthrough is in the sidebar, we render a button into the
|
|
536
545
|
// ChatView to open it.
|
|
537
546
|
const openWalkThroughSidebarButton =
|
|
538
|
-
!input.walkthrough.isInlined ? renderWalkthroughSidebarButton(input,
|
|
547
|
+
!input.walkthrough.isInlined ? renderWalkthroughSidebarButton(input, steps) : Lit.nothing;
|
|
539
548
|
|
|
540
549
|
// If there are side-effect steps, and the walkthrough is not open, we render
|
|
541
550
|
// those inline so that the user can see them and approve them.
|
|
@@ -554,6 +563,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
554
563
|
|
|
555
564
|
// If the walkthrough is inlined (narrow width screens), render it here.
|
|
556
565
|
// Note that we force it open if there is a side-effect.
|
|
566
|
+
|
|
567
|
+
const isExpanded = (input.walkthrough.isExpanded && input.walkthrough.activeMessage === input.message) ||
|
|
568
|
+
steps.some(s => s.requestApproval);
|
|
557
569
|
// clang-format off
|
|
558
570
|
const walkthroughInline = input.walkthrough.isInlined ? html`
|
|
559
571
|
<div class="walkthrough-container">
|
|
@@ -562,9 +574,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
562
574
|
isLoading: input.isLoading && input.isLastMessage,
|
|
563
575
|
markdownRenderer: input.markdownRenderer,
|
|
564
576
|
isInlined: true,
|
|
565
|
-
isExpanded
|
|
566
|
-
(input.walkthrough.isExpanded || steps.some(step => Boolean(step.requestApproval))),
|
|
577
|
+
isExpanded,
|
|
567
578
|
onToggle: input.walkthrough.onToggle,
|
|
579
|
+
onOpen: input.walkthrough.onOpen,
|
|
568
580
|
})}></devtools-widget>
|
|
569
581
|
</div>
|
|
570
582
|
` : Lit.nothing;
|
|
@@ -649,37 +661,55 @@ interface WidgetMakerResponse {
|
|
|
649
661
|
revealable: unknown;
|
|
650
662
|
}
|
|
651
663
|
|
|
664
|
+
const computedStyleNodeCache = new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode>();
|
|
665
|
+
|
|
652
666
|
async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promise<WidgetMakerResponse|null> {
|
|
653
|
-
|
|
654
|
-
if (!
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
667
|
+
let domNodeForId = computedStyleNodeCache.get(widgetData.data.backendNodeId);
|
|
668
|
+
if (!domNodeForId) {
|
|
669
|
+
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
670
|
+
if (!target) {
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
const node = new SDK.DOMModel.DeferredDOMNode(
|
|
674
|
+
target,
|
|
675
|
+
widgetData.data.backendNodeId,
|
|
676
|
+
);
|
|
677
|
+
const resolved = await node.resolvePromise();
|
|
678
|
+
if (!resolved) {
|
|
679
|
+
return null;
|
|
680
|
+
}
|
|
681
|
+
domNodeForId = resolved;
|
|
682
|
+
computedStyleNodeCache.set(widgetData.data.backendNodeId, resolved);
|
|
664
683
|
}
|
|
665
|
-
const
|
|
666
|
-
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(resolved, widgetData.data.computedStyles);
|
|
684
|
+
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(domNodeForId, widgetData.data.computedStyles);
|
|
667
685
|
|
|
668
686
|
const widgetConfig = UI.Widget.widgetConfig(Elements.ComputedStyleWidget.ComputedStyleWidget, {
|
|
669
687
|
nodeStyle: styles,
|
|
670
688
|
matchedStyles: widgetData.data.matchedCascade,
|
|
671
689
|
// This disables showing the nested traces and detailed information in the widget.
|
|
672
690
|
propertyTraces: null,
|
|
673
|
-
computedStyleModel: model,
|
|
674
691
|
allowUserControl: false,
|
|
675
692
|
filterText: new RegExp(widgetData.data.properties.join('|'), 'i')
|
|
676
693
|
});
|
|
677
694
|
|
|
678
695
|
// clang-format off
|
|
679
|
-
|
|
696
|
+
const widget = html`<devtools-widget class="computed-styles-widget" .widgetConfig=${widgetConfig}></devtools-widget>`;
|
|
680
697
|
// clang-format on
|
|
681
698
|
|
|
682
|
-
return {renderedWidget: widget, revealable: new Elements.ElementsPanel.NodeComputedStyles(
|
|
699
|
+
return {renderedWidget: widget, revealable: new Elements.ElementsPanel.NodeComputedStyles(domNodeForId)};
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
async function makeCoreVitalsWidget(widgetData: CoreVitalsAiWidget): Promise<WidgetMakerResponse|null> {
|
|
703
|
+
const widgetConfig = UI.Widget.widgetConfig(TimelineComponents.CWVMetrics.CWVMetrics, {data: widgetData.data});
|
|
704
|
+
|
|
705
|
+
// clang-format off
|
|
706
|
+
const widget = html`<devtools-widget class="core-vitals-widget" .widgetConfig=${widgetConfig}></devtools-widget>`;
|
|
707
|
+
// clang-format on
|
|
708
|
+
|
|
709
|
+
return {
|
|
710
|
+
renderedWidget: widget,
|
|
711
|
+
revealable: new TimelineUtils.Helpers.RevealableCoreVitals(widgetData.data.insightSetKey)
|
|
712
|
+
};
|
|
683
713
|
}
|
|
684
714
|
|
|
685
715
|
function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTemplate {
|
|
@@ -696,15 +726,17 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
696
726
|
|
|
697
727
|
// clang-format off
|
|
698
728
|
return html`
|
|
699
|
-
<div class="widget-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
<
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
729
|
+
<div class="widget-and-revealer-container">
|
|
730
|
+
<div class="widget-content-container">
|
|
731
|
+
${response.renderedWidget}
|
|
732
|
+
</div>
|
|
733
|
+
<div class="widget-reveal-container">
|
|
734
|
+
<devtools-button class="widget-reveal"
|
|
735
|
+
.iconName=${'tab-move'}
|
|
736
|
+
.variant=${Buttons.Button.Variant.TEXT}
|
|
737
|
+
@click=${onReveal}
|
|
738
|
+
>${lockedString(UIStringsNotTranslate.reveal)}</devtools-button>
|
|
739
|
+
</div>
|
|
708
740
|
</div>
|
|
709
741
|
`;
|
|
710
742
|
// clang-format on
|
|
@@ -716,10 +748,11 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
716
748
|
* iterates through the `step.widgets` array. For each widget, it determines
|
|
717
749
|
* the appropriate rendering logic based on the `widgetData.name`.
|
|
718
750
|
*
|
|
719
|
-
* Currently, only 'COMPUTED_STYLES' widgets are supported. For these, the
|
|
720
|
-
* `makeComputedStyleWidget`
|
|
751
|
+
* Currently, only 'COMPUTED_STYLES' and 'CORE_VITALS' widgets are supported. For these, the
|
|
752
|
+
* `makeComputedStyleWidget` and `makeCoreVitalsWidget` functions are called to construct the necessary
|
|
721
753
|
* data and configuration for the `Elements.ComputedStyleWidget.ComputedStyleWidget`
|
|
722
|
-
*
|
|
754
|
+
* and `TimelineComponents.CWVMetrics.CWVMetrics`
|
|
755
|
+
* components. The widget is then rendered using the `<devtools-widget>`
|
|
723
756
|
* custom element, which dynamically instantiates and displays the specified
|
|
724
757
|
* UI.Widget subclass with the provided configuration.
|
|
725
758
|
*
|
|
@@ -736,6 +769,10 @@ async function renderStepWidgets(step: Step): Promise<Lit.LitTemplate> {
|
|
|
736
769
|
const response = await makeComputedStyleWidget(widgetData);
|
|
737
770
|
return renderWidgetResponse(response);
|
|
738
771
|
}
|
|
772
|
+
if (widgetData.name === 'CORE_VITALS') {
|
|
773
|
+
const response = await makeCoreVitalsWidget(widgetData);
|
|
774
|
+
return renderWidgetResponse(response);
|
|
775
|
+
}
|
|
739
776
|
return Lit.nothing;
|
|
740
777
|
}));
|
|
741
778
|
return html`${ui}`;
|
|
@@ -994,6 +1031,7 @@ export class ChatMessage extends UI.Widget.Widget {
|
|
|
994
1031
|
onToggle: () => {},
|
|
995
1032
|
isInlined: false,
|
|
996
1033
|
isExpanded: false,
|
|
1034
|
+
activeMessage: null,
|
|
997
1035
|
};
|
|
998
1036
|
|
|
999
1037
|
#suggestionsResizeObserver = new ResizeObserver(() => this.#handleSuggestionsScrollOrResize());
|
|
@@ -25,11 +25,15 @@ const UIStrings = {
|
|
|
25
25
|
/**
|
|
26
26
|
* @description Title for the walkthrough view.
|
|
27
27
|
*/
|
|
28
|
-
title: '
|
|
28
|
+
title: 'Agent walkthrough',
|
|
29
29
|
/**
|
|
30
|
-
* @description Title for the button that shows the
|
|
30
|
+
* @description Title for the button that shows the walkthrough when there are no widgets in the walkthrough.
|
|
31
31
|
*/
|
|
32
32
|
showThinking: 'Show thinking',
|
|
33
|
+
/**
|
|
34
|
+
* @description Title for the button that shows the walkthrough when there are widgets in the walkthrough.
|
|
35
|
+
*/
|
|
36
|
+
showAgentWalkthrough: 'Show agent walkthrough',
|
|
33
37
|
} as const;
|
|
34
38
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/components/WalkthroughView.ts', UIStrings);
|
|
35
39
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -41,14 +45,21 @@ export interface ViewInput {
|
|
|
41
45
|
isInlined: boolean;
|
|
42
46
|
isExpanded: boolean;
|
|
43
47
|
onToggle: (isOpen: boolean) => void;
|
|
48
|
+
onOpen: (message: ModelChatMessage) => void;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
export function walkthroughTitle(input: {
|
|
47
52
|
isLoading: boolean,
|
|
53
|
+
hasWidgets: boolean,
|
|
48
54
|
lastStep: Step,
|
|
49
55
|
}): string {
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
if (input.isLoading) {
|
|
57
|
+
return titleForStep(input.lastStep);
|
|
58
|
+
}
|
|
59
|
+
if (input.hasWidgets) {
|
|
60
|
+
return lockedString(UIStrings.showAgentWalkthrough);
|
|
61
|
+
}
|
|
62
|
+
return lockedString(UIStrings.showThinking);
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate, steps: Step[]): Lit.LitTemplate {
|
|
@@ -61,12 +72,14 @@ function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate,
|
|
|
61
72
|
input.onToggle((event.target as HTMLDetailsElement).open);
|
|
62
73
|
}
|
|
63
74
|
|
|
75
|
+
const hasWidgets = steps.some(s => s.widgets?.length);
|
|
76
|
+
|
|
64
77
|
// clang-format off
|
|
65
78
|
return html`
|
|
66
79
|
<details class="walkthrough-inline" ?open=${input.isExpanded} @toggle=${onToggle}>
|
|
67
80
|
<summary>
|
|
68
81
|
${input.isLoading ? html`<devtools-spinner></devtools-spinner>` : Lit.nothing}
|
|
69
|
-
${walkthroughTitle({isLoading: input.isLoading, lastStep,})}
|
|
82
|
+
${walkthroughTitle({isLoading: input.isLoading, lastStep, hasWidgets})}
|
|
70
83
|
<devtools-icon name="chevron-down"></devtools-icon>
|
|
71
84
|
</summary>
|
|
72
85
|
${stepsOutput}
|
|
@@ -88,7 +101,7 @@ function renderSidebarWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate
|
|
|
88
101
|
<devtools-button
|
|
89
102
|
.data=${{
|
|
90
103
|
variant: Buttons.Button.Variant.TOOLBAR,
|
|
91
|
-
iconName: '
|
|
104
|
+
iconName: 'cross',
|
|
92
105
|
title: i18nString(UIStrings.close),
|
|
93
106
|
jslogContext: 'close-walkthrough',
|
|
94
107
|
} as Buttons.Button.ButtonData}
|
|
@@ -155,6 +168,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
155
168
|
#isLoading = false;
|
|
156
169
|
#markdownRenderer: MarkdownLitRenderer|null = null;
|
|
157
170
|
#onToggle: (isOpen: boolean) => void = () => {};
|
|
171
|
+
#onOpen: (message: ModelChatMessage) => void = () => {};
|
|
158
172
|
#isInlined = false;
|
|
159
173
|
#isExpanded = false;
|
|
160
174
|
|
|
@@ -185,6 +199,15 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
185
199
|
return this.#message;
|
|
186
200
|
}
|
|
187
201
|
|
|
202
|
+
get onOpen(): (message: ModelChatMessage) => void {
|
|
203
|
+
return this.#onOpen;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
set onOpen(onOpen: (message: ModelChatMessage) => void) {
|
|
207
|
+
this.#onOpen = onOpen;
|
|
208
|
+
this.requestUpdate();
|
|
209
|
+
}
|
|
210
|
+
|
|
188
211
|
set message(message: ModelChatMessage|null) {
|
|
189
212
|
this.#message = message;
|
|
190
213
|
this.requestUpdate();
|
|
@@ -214,6 +237,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
214
237
|
isLoading: this.#isLoading,
|
|
215
238
|
markdownRenderer: this.#markdownRenderer,
|
|
216
239
|
onToggle: this.#onToggle,
|
|
240
|
+
onOpen: this.#onOpen,
|
|
217
241
|
isInlined: this.#isInlined,
|
|
218
242
|
isExpanded: this.#isExpanded,
|
|
219
243
|
message: this.#message,
|
|
@@ -364,10 +364,13 @@
|
|
|
364
364
|
|
|
365
365
|
.step-widgets-wrapper {
|
|
366
366
|
width: fit-content;
|
|
367
|
+
display: flex;
|
|
368
|
+
flex-direction: column;
|
|
369
|
+
align-items: flex-start;
|
|
370
|
+
gap: var(--sys-size-5);
|
|
367
371
|
}
|
|
368
372
|
|
|
369
373
|
.widget-reveal-container {
|
|
370
|
-
width: 100%;
|
|
371
374
|
background: var(--sys-color-surface5);
|
|
372
375
|
border-bottom-right-radius: var(--sys-shape-corner-medium);
|
|
373
376
|
border-bottom-left-radius: var(--sys-shape-corner-medium);
|
|
@@ -378,7 +381,6 @@
|
|
|
378
381
|
padding: var(--sys-size-4);
|
|
379
382
|
border-top-left-radius: var(--sys-shape-corner-medium);
|
|
380
383
|
border-top-right-radius: var(--sys-shape-corner-medium);
|
|
381
|
-
width: 100%;
|
|
382
384
|
overflow-x: auto;
|
|
383
385
|
background-color: var(--sys-color-surface3);
|
|
384
386
|
|
|
@@ -143,8 +143,7 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
for (const [storageBucketName] of this.databaseNamesByStorageKeyAndBucket.get(storageKey) || []) {
|
|
146
|
-
const storageBucket =
|
|
147
|
-
this.storageBucketModel?.getBucketByName(storageKey, storageBucketName ?? undefined)?.bucket;
|
|
146
|
+
const storageBucket = this.storageBucketModel?.getBucketByName(storageKey, storageBucketName)?.bucket;
|
|
148
147
|
if (storageBucket) {
|
|
149
148
|
this.removeStorageBucket(storageBucket);
|
|
150
149
|
}
|
|
@@ -169,8 +168,7 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
|
|
|
169
168
|
for (const [storageKey] of this.databaseNamesByStorageKeyAndBucket) {
|
|
170
169
|
const storageBucketNames = this.databaseNamesByStorageKeyAndBucket.get(storageKey)?.keys() || [];
|
|
171
170
|
for (const storageBucketName of storageBucketNames) {
|
|
172
|
-
const storageBucket =
|
|
173
|
-
this.storageBucketModel?.getBucketByName(storageKey, storageBucketName ?? undefined)?.bucket;
|
|
171
|
+
const storageBucket = this.storageBucketModel?.getBucketByName(storageKey, storageBucketName)?.bucket;
|
|
174
172
|
if (storageBucket) {
|
|
175
173
|
await this.loadDatabaseNamesByStorageBucket(storageBucket);
|
|
176
174
|
}
|
|
@@ -10,6 +10,7 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
10
10
|
import type * as Protocol from '../../generated/protocol.js';
|
|
11
11
|
import * as NetworkForward from '../../panels/network/forward/forward.js';
|
|
12
12
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
13
|
+
import {Link} from '../../ui/kit/kit.js';
|
|
13
14
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
14
15
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
15
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -227,17 +228,8 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
227
228
|
othersView.show(othersDiv);
|
|
228
229
|
const othersSection = othersView.appendSection(i18nString(UIStrings.serviceWorkersFromOtherOrigins));
|
|
229
230
|
const othersSectionRow = othersSection.appendRow();
|
|
230
|
-
const seeOthers =
|
|
231
|
-
|
|
232
|
-
.html`<a class="devtools-link" role="link" tabindex="0" href="chrome://serviceworker-internals" target="_blank" style="display: inline; cursor: pointer;">${
|
|
233
|
-
i18nString(UIStrings.seeAllRegistrations)}</a>`;
|
|
234
|
-
seeOthers.setAttribute('jslog', `${VisualLogging.link('view-all').track({click: true})}`);
|
|
235
|
-
self.onInvokeElement(seeOthers, event => {
|
|
236
|
-
const rootTarget = SDK.TargetManager.TargetManager.instance().rootTarget();
|
|
237
|
-
rootTarget &&
|
|
238
|
-
void rootTarget.targetAgent().invoke_createTarget({url: 'chrome://serviceworker-internals?devtools'});
|
|
239
|
-
event.consume(true);
|
|
240
|
-
});
|
|
231
|
+
const seeOthers = Link.create(
|
|
232
|
+
'chrome://serviceworker-internals', i18nString(UIStrings.seeAllRegistrations), undefined, 'view-all');
|
|
241
233
|
othersSectionRow.appendChild(seeOthers);
|
|
242
234
|
|
|
243
235
|
this.toolbar.appendToolbarItem(
|
|
@@ -104,7 +104,7 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
104
104
|
if (!filter?.regex) {
|
|
105
105
|
return '';
|
|
106
106
|
}
|
|
107
|
-
const matches = filter.regex.exec(textContent
|
|
107
|
+
const matches = filter.regex.exec(textContent);
|
|
108
108
|
if (!matches?.length) {
|
|
109
109
|
return '';
|
|
110
110
|
}
|
|
@@ -294,7 +294,14 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
294
294
|
};
|
|
295
295
|
|
|
296
296
|
export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
297
|
-
|
|
297
|
+
/**
|
|
298
|
+
* We store these because they are used when calculating the dimensions for the image preview.
|
|
299
|
+
* When we need to get those dimensions, we try to resolve them against the
|
|
300
|
+
* node fresh (in case the dimensions have changed), but if that doesn't work,
|
|
301
|
+
* we fallback to the precomputed ones, which helps to deal with situations
|
|
302
|
+
* where the node might have been removed from the DOM.
|
|
303
|
+
*/
|
|
304
|
+
#storedNodeFeatures: Components.ImagePreview.PrecomputedFeatures|null = null;
|
|
298
305
|
#nodeStyle: ComputedStyleModule.ComputedStyleModel.ComputedStyle|null = null;
|
|
299
306
|
#matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null = null;
|
|
300
307
|
#propertyTraces: Map<string, SDK.CSSProperty.CSSProperty[]>|null = null;
|
|
@@ -363,7 +370,8 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
363
370
|
return null;
|
|
364
371
|
},
|
|
365
372
|
async () => {
|
|
366
|
-
|
|
373
|
+
const liveFeatures = await Components.ImagePreview.loadPrecomputedFeatures(this.#nodeStyle?.node);
|
|
374
|
+
return liveFeatures ?? this.#storedNodeFeatures ?? undefined;
|
|
367
375
|
});
|
|
368
376
|
|
|
369
377
|
this.#updateView({hasMatches: true});
|
|
@@ -430,7 +438,13 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
430
438
|
|
|
431
439
|
set nodeStyle(nodeStyle: ComputedStyleModule.ComputedStyleModel.ComputedStyle|null) {
|
|
432
440
|
this.#nodeStyle = nodeStyle;
|
|
433
|
-
|
|
441
|
+
if (nodeStyle) {
|
|
442
|
+
// Make sure we get the node features before we request an update so we
|
|
443
|
+
// don't run the update before we have the features fetched.
|
|
444
|
+
void this.#storeNodeFeatures(nodeStyle.node).then(() => this.requestUpdate());
|
|
445
|
+
} else {
|
|
446
|
+
this.requestUpdate();
|
|
447
|
+
}
|
|
434
448
|
}
|
|
435
449
|
|
|
436
450
|
get matchedStyles(): SDK.CSSMatchedStyles.CSSMatchedStyles|null {
|
|
@@ -447,13 +461,13 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
447
461
|
this.requestUpdate();
|
|
448
462
|
}
|
|
449
463
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
464
|
+
async #storeNodeFeatures(node: SDK.DOMModel.DOMNode|null): Promise<void> {
|
|
465
|
+
if (node) {
|
|
466
|
+
const features = await Components.ImagePreview.loadPrecomputedFeatures(node);
|
|
467
|
+
this.#storedNodeFeatures = features ?? null;
|
|
468
|
+
} else {
|
|
469
|
+
this.#storedNodeFeatures = null;
|
|
470
|
+
}
|
|
457
471
|
}
|
|
458
472
|
|
|
459
473
|
#shouldGroupStyles(): boolean {
|
|
@@ -483,10 +497,6 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
483
497
|
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles): Promise<void> {
|
|
484
498
|
this.imagePreviewPopover.hide();
|
|
485
499
|
this.linkifier.reset();
|
|
486
|
-
const cssModel = this.#computedStyleModel?.cssModel();
|
|
487
|
-
if (!cssModel) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
500
|
|
|
491
501
|
const uniqueProperties = [...nodeStyle.computedStyle.keys()];
|
|
492
502
|
uniqueProperties.sort(propertySorter);
|
|
@@ -526,8 +536,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
526
536
|
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null): Promise<void> {
|
|
527
537
|
this.imagePreviewPopover.hide();
|
|
528
538
|
this.linkifier.reset();
|
|
529
|
-
|
|
530
|
-
if (!nodeStyle || !matchedStyles || !cssModel) {
|
|
539
|
+
if (!nodeStyle || !matchedStyles) {
|
|
531
540
|
this.#updateView({hasMatches: false});
|
|
532
541
|
return;
|
|
533
542
|
}
|
|
@@ -316,7 +316,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
316
316
|
|
|
317
317
|
this.stylesWidget = new StylesSidebarPane(this.#computedStyleModel);
|
|
318
318
|
this.#computedStyleWidget = new ComputedStyleWidget();
|
|
319
|
-
this.#computedStyleWidget.computedStyleModel = this.#computedStyleModel;
|
|
320
319
|
this.#computedStyleModel.addEventListener(
|
|
321
320
|
ComputedStyle.ComputedStyleModel.Events.COMPUTED_STYLE_CHANGED, this.#updateComputedStyles, this);
|
|
322
321
|
this.#computedStyleModel.addEventListener(
|
|
@@ -40,7 +40,16 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
40
40
|
target);
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
export
|
|
43
|
+
export const enum Events {
|
|
44
|
+
STYLES_UPDATE_COMPLETED = 'StylesUpdateCompleted',
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface EventTypes {
|
|
48
|
+
[Events.STYLES_UPDATE_COMPLETED]: void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<EventTypes, typeof UI.Widget.VBox>(
|
|
52
|
+
UI.Widget.VBox) implements StylesContainer {
|
|
44
53
|
activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null = null;
|
|
45
54
|
isEditingStyle = false;
|
|
46
55
|
readonly sectionByElement = new WeakMap<Node, StylePropertiesSection>();
|
|
@@ -49,7 +58,7 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
49
58
|
new Components.Linkifier.Linkifier(23, /* useLinkDecorator */ true);
|
|
50
59
|
|
|
51
60
|
#webCustomData: WebCustomData|undefined;
|
|
52
|
-
|
|
61
|
+
userOperation = false;
|
|
53
62
|
#sections: StylePropertiesSection[] = [];
|
|
54
63
|
#swatchPopoverHelper = new InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper();
|
|
55
64
|
#computedStyleModelInternal = new ComputedStyle.ComputedStyleModel.ComputedStyleModel();
|
|
@@ -58,10 +67,24 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
58
67
|
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
59
68
|
super(element, {useShadowDom: true});
|
|
60
69
|
this.#view = view;
|
|
70
|
+
this.#computedStyleModelInternal.addEventListener(
|
|
71
|
+
ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.#onCSSModelChanged, this);
|
|
61
72
|
}
|
|
62
73
|
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
async #onCSSModelChanged(
|
|
75
|
+
event: Common.EventTarget.EventTargetEvent<ComputedStyle.ComputedStyleModel.CSSModelChangedEvent>):
|
|
76
|
+
Promise<void> {
|
|
77
|
+
// We only recreate sections if this update is more than an "edit" operation.
|
|
78
|
+
// Sections will pull their own updates in the case of an "edit".
|
|
79
|
+
if (event?.data && 'edit' in event.data && event?.data.edit) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (this.isEditingStyle || this.userOperation) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.requestUpdate();
|
|
65
88
|
}
|
|
66
89
|
|
|
67
90
|
get webCustomData(): WebCustomData|undefined {
|
|
@@ -73,10 +96,12 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
async #updateSections(): Promise<void> {
|
|
99
|
+
for (const section of this.#sections) {
|
|
100
|
+
section.dispose();
|
|
101
|
+
}
|
|
76
102
|
const node = this.node();
|
|
77
103
|
if (!node) {
|
|
78
104
|
this.#sections = [];
|
|
79
|
-
this.requestUpdate();
|
|
80
105
|
return;
|
|
81
106
|
}
|
|
82
107
|
|
|
@@ -106,9 +131,8 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
106
131
|
}
|
|
107
132
|
|
|
108
133
|
override async performUpdate(): Promise<void> {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
134
|
+
this.hideAllPopovers();
|
|
135
|
+
this.node()?.domModel().cssModel().discardCachedMatchedCascade();
|
|
112
136
|
|
|
113
137
|
await this.#updateSections();
|
|
114
138
|
|
|
@@ -116,6 +140,11 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
116
140
|
sections: this.#sections,
|
|
117
141
|
};
|
|
118
142
|
this.#view(viewInput, undefined, this.contentElement);
|
|
143
|
+
this.#onUpdateFinished();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
#onUpdateFinished(): void {
|
|
147
|
+
this.dispatchEventToListeners(Events.STYLES_UPDATE_COMPLETED);
|
|
119
148
|
}
|
|
120
149
|
|
|
121
150
|
swatchPopoverHelper(): InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper {
|
|
@@ -154,6 +183,7 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
154
183
|
}
|
|
155
184
|
|
|
156
185
|
if (this.isEditingStyle) {
|
|
186
|
+
this.#onUpdateFinished();
|
|
157
187
|
return;
|
|
158
188
|
}
|
|
159
189
|
|
|
@@ -161,6 +191,7 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
161
191
|
section.update(section === editedSection);
|
|
162
192
|
}
|
|
163
193
|
this.swatchPopoverHelper().reposition();
|
|
194
|
+
this.#onUpdateFinished();
|
|
164
195
|
}
|
|
165
196
|
|
|
166
197
|
filterRegex(): RegExp|null {
|
|
@@ -172,16 +203,19 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
172
203
|
}
|
|
173
204
|
|
|
174
205
|
setUserOperation(userOperation: boolean): void {
|
|
175
|
-
this
|
|
206
|
+
this.userOperation = userOperation;
|
|
176
207
|
}
|
|
177
208
|
|
|
178
209
|
forceUpdate(): void {
|
|
179
|
-
this.hideAllPopovers();
|
|
180
210
|
this.requestUpdate();
|
|
181
211
|
}
|
|
182
212
|
|
|
183
213
|
hideAllPopovers(): void {
|
|
184
214
|
this.#swatchPopoverHelper.hide();
|
|
215
|
+
if (this.activeCSSAngle) {
|
|
216
|
+
this.activeCSSAngle.minify();
|
|
217
|
+
this.activeCSSAngle = null;
|
|
218
|
+
}
|
|
185
219
|
}
|
|
186
220
|
|
|
187
221
|
allSections(): StylePropertiesSection[] {
|
|
@@ -246,9 +280,11 @@ export class StandaloneStylesContainer extends UI.Widget.VBox implements StylesC
|
|
|
246
280
|
jumpToDeclaration(_valueSource: SDK.CSSMatchedStyles.CSSValueSource): void {
|
|
247
281
|
}
|
|
248
282
|
|
|
249
|
-
addStyleUpdateListener(
|
|
283
|
+
addStyleUpdateListener(listener: () => void): void {
|
|
284
|
+
this.addEventListener(Events.STYLES_UPDATE_COMPLETED, listener);
|
|
250
285
|
}
|
|
251
286
|
|
|
252
|
-
removeStyleUpdateListener(
|
|
287
|
+
removeStyleUpdateListener(listener: () => void): void {
|
|
288
|
+
this.removeEventListener(Events.STYLES_UPDATE_COMPLETED, listener);
|
|
253
289
|
}
|
|
254
290
|
}
|