chrome-devtools-frontend 1.0.1608868 → 1.0.1611099
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/eslint.config.mjs +3 -1
- package/front_end/core/host/AidaGcaTranslation.ts +13 -0
- package/front_end/core/sdk/PreloadingModel.ts +1 -1
- package/front_end/entrypoints/heap_snapshot_worker/AllocationProfile.ts +1 -1
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +1 -11
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +1 -1
- package/front_end/generated/InspectorBackendCommands.ts +1 -2
- package/front_end/generated/SupportedCSSProperties.js +23 -4
- package/front_end/generated/protocol-mapping.d.ts +0 -9
- package/front_end/generated/protocol-proxy-api.d.ts +0 -7
- package/front_end/generated/protocol.ts +0 -20
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +12 -3
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +5 -4
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +24 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +41 -22
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +5 -3
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +10 -5
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +69 -69
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -1
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -12
- package/front_end/models/live-metrics/LiveMetrics.ts +43 -41
- package/front_end/models/trace/EntityMapper.ts +12 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +7 -9
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +66 -34
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +1 -1
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +1 -0
- package/front_end/panels/ai_assistance/components/chatMessage.css +15 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +5 -4
- package/front_end/panels/application/ApplicationPanelSidebar.ts +8 -0
- package/front_end/panels/application/IndexedDBViews.ts +1 -1
- package/front_end/panels/application/ResourcesPanel.ts +8 -0
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
- package/front_end/panels/application/application-meta.ts +11 -0
- package/front_end/panels/application/application.ts +1 -0
- package/front_end/panels/application/components/StorageMetadataView.ts +31 -7
- package/front_end/panels/application/components/backForwardCacheView.css +4 -0
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +29 -0
- package/front_end/panels/elements/ElementsTreeElement.ts +4 -0
- package/front_end/panels/lighthouse/LighthousePanel.ts +3 -1
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +1 -1
- package/front_end/panels/timeline/TimelinePanel.ts +2 -6
- package/front_end/panels/timeline/utils/Helpers.ts +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/InspectorDrawerView.ts +188 -15
- package/front_end/ui/legacy/InspectorView.ts +162 -11
- package/front_end/ui/legacy/TabbedPane.ts +2 -2
- package/front_end/ui/legacy/inspectorDrawerTabbedPane.css +54 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/front_end/ui/visual_logging/LoggingDriver.ts +3 -3
- package/mcp/mcp.ts +2 -1
- package/package.json +4 -5
- /package/front_end/models/{heap_snapshot_model → heap_snapshot}/ChildrenProvider.ts +0 -0
- /package/front_end/models/{heap_snapshot_model → heap_snapshot}/HeapSnapshotModel.ts +0 -0
- /package/front_end/models/{heap_snapshot_model → heap_snapshot}/HeapSnapshotProxy.ts +0 -0
- /package/front_end/models/{heap_snapshot_model/heap_snapshot_model.ts → heap_snapshot/heap_snapshot.ts} +0 -0
|
@@ -10,6 +10,8 @@ import * as Helpers from './helpers/helpers.js';
|
|
|
10
10
|
import type {ParsedTrace} from './ModelImpl.js';
|
|
11
11
|
import type * as Types from './types/types.js';
|
|
12
12
|
|
|
13
|
+
const mapperCache = new WeakMap<ParsedTrace, EntityMapper>();
|
|
14
|
+
|
|
13
15
|
export class EntityMapper {
|
|
14
16
|
#parsedTrace: ParsedTrace;
|
|
15
17
|
#entityMappings: Handlers.Helpers.EntityMappings;
|
|
@@ -30,6 +32,16 @@ export class EntityMapper {
|
|
|
30
32
|
this.#thirdPartyEvents = this.#getThirdPartyEvents();
|
|
31
33
|
}
|
|
32
34
|
|
|
35
|
+
static getOrCreate(parsedTrace: ParsedTrace): EntityMapper {
|
|
36
|
+
const cached = mapperCache.get(parsedTrace);
|
|
37
|
+
if (cached) {
|
|
38
|
+
return cached;
|
|
39
|
+
}
|
|
40
|
+
const instance = new EntityMapper(parsedTrace);
|
|
41
|
+
mapperCache.set(parsedTrace, instance);
|
|
42
|
+
return instance;
|
|
43
|
+
}
|
|
44
|
+
|
|
33
45
|
#findFirstPartyEntity(): Handlers.Helpers.Entity|null {
|
|
34
46
|
// As a starting point, we consider the first navigation as the 1P.
|
|
35
47
|
const nav =
|
|
@@ -539,15 +539,13 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
539
539
|
<div slot="main" class="main-view">
|
|
540
540
|
${renderState()}
|
|
541
541
|
</div>
|
|
542
|
-
|
|
543
|
-
${
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
})}></devtools-widget>` : Lit.nothing}
|
|
550
|
-
</div>
|
|
542
|
+
${shouldShowWalkthrough ? html`
|
|
543
|
+
<devtools-widget slot="sidebar" ${widget(WalkthroughView, {
|
|
544
|
+
message: input.props.walkthrough.activeSidebarMessage,
|
|
545
|
+
isLoading: input.props.isLoading && walkthroughIsForLastMessage,
|
|
546
|
+
markdownRenderer: input.props.markdownRenderer,
|
|
547
|
+
onToggle: input.props.walkthrough.onToggle,
|
|
548
|
+
})}></devtools-widget>` : Lit.nothing}
|
|
551
549
|
</devtools-split-view>
|
|
552
550
|
</div>
|
|
553
551
|
`, target);
|
|
@@ -199,7 +199,7 @@ const UIStringsNotTranslate = {
|
|
|
199
199
|
/**
|
|
200
200
|
* @description The title of the button that allows exporting the conversation for agents.
|
|
201
201
|
*/
|
|
202
|
-
exportForAgents: 'Copy
|
|
202
|
+
exportForAgents: 'Copy to coding agent',
|
|
203
203
|
/**
|
|
204
204
|
* @description Title for the bottom up thread activity widget.
|
|
205
205
|
*/
|
|
@@ -417,6 +417,7 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
|
|
|
417
417
|
` : Lit.nothing}
|
|
418
418
|
${input.showActions ? renderActions(input, output) : Lit.nothing}
|
|
419
419
|
</div>
|
|
420
|
+
${hasAiV2 ? renderSideEffectStepsUI(input, steps) : Lit.nothing}
|
|
420
421
|
</section>
|
|
421
422
|
`, target);
|
|
422
423
|
// clang-format on
|
|
@@ -482,7 +483,6 @@ function renderStepCode(step: Step): Lit.LitTemplate {
|
|
|
482
483
|
<devtools-code-block
|
|
483
484
|
.code=${step.code.trim()}
|
|
484
485
|
.codeLang=${'js'}
|
|
485
|
-
.displayLimit=${MAX_NUM_LINES_IN_CODEBLOCK}
|
|
486
486
|
.displayNotice=${!Boolean(step.output)}
|
|
487
487
|
.header=${codeHeadingText}
|
|
488
488
|
.showCopyButton=${true}
|
|
@@ -493,7 +493,6 @@ function renderStepCode(step: Step): Lit.LitTemplate {
|
|
|
493
493
|
<devtools-code-block
|
|
494
494
|
.code=${step.output}
|
|
495
495
|
.codeLang=${'js'}
|
|
496
|
-
.displayLimit=${MAX_NUM_LINES_IN_CODEBLOCK}
|
|
497
496
|
.displayNotice=${true}
|
|
498
497
|
.header=${lockedString(UIStringsNotTranslate.dataReturned)}
|
|
499
498
|
.showCopyButton=${false}
|
|
@@ -526,7 +525,6 @@ function renderStepDetails({
|
|
|
526
525
|
<devtools-code-block
|
|
527
526
|
.code=${contextDetail.text}
|
|
528
527
|
.codeLang=${contextDetail.codeLang || ''}
|
|
529
|
-
.displayLimit=${MAX_NUM_LINES_IN_CODEBLOCK}
|
|
530
528
|
.displayNotice=${false}
|
|
531
529
|
.header=${contextDetail.title}
|
|
532
530
|
.showCopyButton=${true}
|
|
@@ -568,9 +566,14 @@ function renderWalkthroughSidebarButton(
|
|
|
568
566
|
const variant = hasOneStepWithWidget && !input.isLoading ? Buttons.Button.Variant.TONAL : Buttons.Button.Variant.TEXT;
|
|
569
567
|
const icon = AiAssistanceModel.AiUtils.getIconName();
|
|
570
568
|
|
|
569
|
+
const toggleContainerClasses = Lit.Directives.classMap({
|
|
570
|
+
'walkthrough-toggle-container': true,
|
|
571
|
+
// We only apply the widget styling when loading is complete
|
|
572
|
+
'has-widgets': hasOneStepWithWidget && !input.isLoading,
|
|
573
|
+
});
|
|
571
574
|
// clang-format off
|
|
572
575
|
return html`
|
|
573
|
-
<div class
|
|
576
|
+
<div class=${toggleContainerClasses}>
|
|
574
577
|
${input.isLoading ?
|
|
575
578
|
html`<devtools-spinner></devtools-spinner>` :
|
|
576
579
|
html`<devtools-icon name=${icon}></devtools-icon>`}
|
|
@@ -589,9 +592,7 @@ function renderWalkthroughSidebarButton(
|
|
|
589
592
|
// the walkthrough open with an alternative message.
|
|
590
593
|
walkthrough.onOpen(message as ModelChatMessage);
|
|
591
594
|
}
|
|
592
|
-
}}
|
|
593
|
-
>
|
|
594
|
-
${title}<devtools-icon class="chevron" .name=${isExpanded ? 'cross' : 'chevron-right'}></devtools-icon>
|
|
595
|
+
}}>${title}<devtools-icon class="chevron" .name=${isExpanded ? 'cross' : 'chevron-right'}></devtools-icon>
|
|
595
596
|
</devtools-button>
|
|
596
597
|
</div>
|
|
597
598
|
`;
|
|
@@ -609,7 +610,6 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
609
610
|
// No steps = no walkthrough UI in the chat view.
|
|
610
611
|
return Lit.nothing;
|
|
611
612
|
}
|
|
612
|
-
const sideEffectSteps = steps.filter(s => s.requestApproval);
|
|
613
613
|
// If the walkthrough is in the sidebar, we render a button into the
|
|
614
614
|
// ChatView to open it.
|
|
615
615
|
const openWalkThroughSidebarButton =
|
|
@@ -622,22 +622,6 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
622
622
|
input.walkthrough.inlineExpandedMessages.includes(input.message as ModelChatMessage) :
|
|
623
623
|
(input.walkthrough.isExpanded && input.walkthrough.activeSidebarMessage === input.message);
|
|
624
624
|
|
|
625
|
-
// When a side-effect step is present and needs user approval, it's
|
|
626
|
-
// shown in the main chat UI, regardless of if the walkthrough is
|
|
627
|
-
// open or closed.
|
|
628
|
-
// Once the user has approved/denied it, it goes back into the sidebar.
|
|
629
|
-
// clang-format off
|
|
630
|
-
const sideEffectStepsUI = sideEffectSteps.length > 0 ? sideEffectSteps.map(step => html`
|
|
631
|
-
<div class="side-effect-container">
|
|
632
|
-
${renderStep({
|
|
633
|
-
step,
|
|
634
|
-
isLoading: input.isLoading,
|
|
635
|
-
markdownRenderer: input.markdownRenderer,
|
|
636
|
-
isLast: true
|
|
637
|
-
})}
|
|
638
|
-
</div> `) : Lit.nothing;
|
|
639
|
-
// clang-format on
|
|
640
|
-
|
|
641
625
|
// clang-format off
|
|
642
626
|
const walkthroughInline = input.walkthrough.isInlined ? html`
|
|
643
627
|
<div class="walkthrough-container">
|
|
@@ -656,7 +640,26 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
656
640
|
return html`
|
|
657
641
|
${openWalkThroughSidebarButton}
|
|
658
642
|
${walkthroughInline}
|
|
659
|
-
|
|
643
|
+
`;
|
|
644
|
+
// clang-format on
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function renderSideEffectStepsUI(input: ChatMessageViewInput, steps: Step[]): Lit.LitTemplate {
|
|
648
|
+
const sideEffectSteps = steps.filter(s => s.requestApproval);
|
|
649
|
+
if (sideEffectSteps.length === 0) {
|
|
650
|
+
return Lit.nothing;
|
|
651
|
+
}
|
|
652
|
+
// clang-format off
|
|
653
|
+
return html`
|
|
654
|
+
${sideEffectSteps.map(step => html`
|
|
655
|
+
<div class="side-effect-container">
|
|
656
|
+
${renderStep({
|
|
657
|
+
step,
|
|
658
|
+
isLoading: input.isLoading,
|
|
659
|
+
markdownRenderer: input.markdownRenderer,
|
|
660
|
+
isLast: true
|
|
661
|
+
})}
|
|
662
|
+
</div> `)}
|
|
660
663
|
`;
|
|
661
664
|
// clang-format on
|
|
662
665
|
}
|
|
@@ -761,6 +764,15 @@ async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promi
|
|
|
761
764
|
}
|
|
762
765
|
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(domNodeForId, widgetData.data.computedStyles);
|
|
763
766
|
|
|
767
|
+
let filterText: RegExp|null = null;
|
|
768
|
+
try {
|
|
769
|
+
filterText = new RegExp(widgetData.data.properties.join('|'), 'i');
|
|
770
|
+
} catch {
|
|
771
|
+
// If the AI provides an invalid regex (e.g. "*"), we don't want to crash.
|
|
772
|
+
// We can just skip the widget in this case.
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
|
|
764
776
|
// clang-format off
|
|
765
777
|
const renderedWidget = html`<devtools-widget
|
|
766
778
|
class="computed-styles-widget" ${widget(Elements.ComputedStyleWidget.ComputedStyleWidget, {
|
|
@@ -769,7 +781,7 @@ async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promi
|
|
|
769
781
|
// This disables showing the nested traces and detailed information in the widget.
|
|
770
782
|
propertyTraces: null,
|
|
771
783
|
allowUserControl: false,
|
|
772
|
-
filterText
|
|
784
|
+
filterText,
|
|
773
785
|
enableNarrowViewResizing: false,
|
|
774
786
|
})}></devtools-widget>`;
|
|
775
787
|
// clang-format on
|
|
@@ -777,11 +789,19 @@ async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promi
|
|
|
777
789
|
return {
|
|
778
790
|
renderedWidget,
|
|
779
791
|
revealable: new Elements.ElementsPanel.NodeComputedStyles(domNodeForId),
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
792
|
+
// clang-format off
|
|
793
|
+
title: html`
|
|
794
|
+
<span class="computed-style-title-wrapper">
|
|
795
|
+
<span class="computed-style-title-prefix">Computed styles</span>
|
|
796
|
+
<span class="style-class-wrapper">
|
|
797
|
+
(<devtools-widget
|
|
798
|
+
${widget(PanelsCommon.DOMLinkifier.DOMNodeLink, {
|
|
799
|
+
node: domNodeForId,
|
|
800
|
+
})}
|
|
801
|
+
></devtools-widget>)
|
|
802
|
+
</span>
|
|
803
|
+
</span>`,
|
|
804
|
+
// clang-format on
|
|
785
805
|
};
|
|
786
806
|
}
|
|
787
807
|
|
|
@@ -804,12 +824,21 @@ async function makeStylePropertiesWidget(widgetData: StylePropertiesAiWidget): P
|
|
|
804
824
|
return null;
|
|
805
825
|
}
|
|
806
826
|
|
|
827
|
+
let filter: RegExp|null = null;
|
|
828
|
+
try {
|
|
829
|
+
filter = widgetData.data.selector ? new RegExp(widgetData.data.selector) : null;
|
|
830
|
+
} catch {
|
|
831
|
+
// If the AI provides an invalid regex (e.g. "*"), we don't want to crash.
|
|
832
|
+
// We can just skip the widget in this case.
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
835
|
+
|
|
807
836
|
// clang-format off
|
|
808
837
|
const renderedWidget = html`<devtools-widget
|
|
809
838
|
class="styling-preview-widget"
|
|
810
839
|
${widget(Elements.StandaloneStylesContainer.StandaloneStylesContainer, {
|
|
811
840
|
domNode: domNodeForId,
|
|
812
|
-
filter
|
|
841
|
+
filter,
|
|
813
842
|
})}>
|
|
814
843
|
</devtools-widget>`;
|
|
815
844
|
// clang-format on
|
|
@@ -1519,7 +1548,7 @@ async function makeTimelineRangeSummaryWidget(widgetData: TimelineRangeSummaryAi
|
|
|
1519
1548
|
eventsArray.sort((a, b) => a.ts - b.ts);
|
|
1520
1549
|
|
|
1521
1550
|
const thirdPartyTree = new Timeline.ThirdPartyTreeView.ThirdPartyTreeViewWidget();
|
|
1522
|
-
const mapper =
|
|
1551
|
+
const mapper = Trace.EntityMapper.EntityMapper.getOrCreate(parsedTrace);
|
|
1523
1552
|
thirdPartyTree.model = {selectedEvents: eventsArray, parsedTrace, entityMapper: mapper};
|
|
1524
1553
|
thirdPartyTree.activeSelection = Timeline.TimelineSelection.selectionFromRangeMicroSeconds(bounds.min, bounds.max);
|
|
1525
1554
|
thirdPartyTree.refreshTree(true);
|
|
@@ -1542,6 +1571,9 @@ async function makeTimelineRangeSummaryWidget(widgetData: TimelineRangeSummaryAi
|
|
|
1542
1571
|
entityMapper: thirdPartyTree.entityMapper(),
|
|
1543
1572
|
},
|
|
1544
1573
|
activeSelection: { bounds },
|
|
1574
|
+
onBottomUpButtonClicked: (node: Trace.Extras.TraceTree.Node|null) => {
|
|
1575
|
+
void Common.Revealer.reveal(new TimelineUtils.Helpers.RevealableBottomUpProfile(bounds, node ?? undefined));
|
|
1576
|
+
},
|
|
1545
1577
|
})}`,
|
|
1546
1578
|
} as TimelineComponents.TimelineRangeSummaryView.TimelineRangeSummaryViewData,
|
|
1547
1579
|
})}
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
align-items: center;
|
|
14
14
|
margin-block: calc(-1 * var(--sys-size-3));
|
|
15
15
|
margin-top: var(--sys-size-5);
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
mask-image: linear-gradient(to right, var(--ref-palette-neutral0) calc(100% - var(--sys-size-15)), transparent 100%);
|
|
16
18
|
|
|
17
19
|
&.not-v2 {
|
|
18
20
|
/* Can be removed when AIv2 ships */
|
|
@@ -456,6 +458,19 @@
|
|
|
456
458
|
white-space: nowrap; /* stop the titles going onto multiple lines */
|
|
457
459
|
}
|
|
458
460
|
|
|
461
|
+
/* This widget's title is some text + then a DOM node link, so it
|
|
462
|
+
* needs some extra styling */
|
|
463
|
+
.computed-style-title-wrapper {
|
|
464
|
+
display: flex;
|
|
465
|
+
align-items: center;
|
|
466
|
+
justify-content: flex-start;
|
|
467
|
+
gap: var(--sys-size-3);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.computed-style-title-prefix {
|
|
471
|
+
flex-shrink: 0;
|
|
472
|
+
}
|
|
473
|
+
|
|
459
474
|
.widget-reveal-container {
|
|
460
475
|
padding: 0;
|
|
461
476
|
background: none;
|
|
@@ -99,23 +99,24 @@
|
|
|
99
99
|
|
|
100
100
|
.inline-wrapper {
|
|
101
101
|
display: flex;
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: var(--sys-size-2);
|
|
104
104
|
justify-content: flex-start;
|
|
105
105
|
|
|
106
106
|
.inline-icon {
|
|
107
107
|
display: block;
|
|
108
|
-
|
|
108
|
+
margin-top: var(--sys-size-2);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
.walkthrough-inline {
|
|
113
|
-
border-radius: var(--sys-
|
|
113
|
+
border-radius: var(--sys-shape-corner-full);
|
|
114
114
|
overflow: hidden;
|
|
115
115
|
width: fit-content;
|
|
116
116
|
max-width: 100%;
|
|
117
117
|
|
|
118
118
|
&[open] {
|
|
119
|
+
border-radius: var(--sys-size-5);
|
|
119
120
|
width: auto;
|
|
120
121
|
background-color: var(--sys-color-surface1);
|
|
121
122
|
margin-left: calc(var(--sys-size-6) / 2);
|
|
@@ -1031,6 +1031,14 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
|
|
|
1031
1031
|
}
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
showStorageBucket(bucketInfo: Protocol.Storage.StorageBucketInfo): void {
|
|
1035
|
+
const bucketsModel = SDK.TargetManager.TargetManager.instance().primaryPageTarget()?.model(
|
|
1036
|
+
SDK.StorageBucketsModel.StorageBucketsModel);
|
|
1037
|
+
if (bucketsModel) {
|
|
1038
|
+
this.storageBucketsTreeElement?.getBucketTreeElement(bucketsModel, bucketInfo)?.revealAndSelect(true);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1034
1042
|
private onmousemove(event: MouseEvent): void {
|
|
1035
1043
|
const nodeUnderMouse = (event.target as Node);
|
|
1036
1044
|
if (!nodeUnderMouse) {
|
|
@@ -12,6 +12,7 @@ import * as UI from '../../ui/legacy/legacy.js';
|
|
|
12
12
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
13
13
|
|
|
14
14
|
import {ApplicationPanelSidebar, StorageCategoryView} from './ApplicationPanelSidebar.js';
|
|
15
|
+
import type {StorageMetadataView} from './components/components.js';
|
|
15
16
|
import {CookieItemsView} from './CookieItemsView.js';
|
|
16
17
|
import type {DeviceBoundSessionsModel} from './DeviceBoundSessionsModel.js';
|
|
17
18
|
import {DeviceBoundSessionsView} from './DeviceBoundSessionsView.js';
|
|
@@ -260,3 +261,10 @@ export class AttemptViewWithFilterRevealer implements
|
|
|
260
261
|
sidebar.showPreloadingAttemptViewWithFilter(filter);
|
|
261
262
|
}
|
|
262
263
|
}
|
|
264
|
+
|
|
265
|
+
export class StorageBucketRevealer implements Common.Revealer.Revealer<StorageMetadataView.StorageBucketRevealInfo> {
|
|
266
|
+
async reveal(revealInfo: StorageMetadataView.StorageBucketRevealInfo): Promise<void> {
|
|
267
|
+
const sidebar = await ResourcesPanel.showAndGetSidebar();
|
|
268
|
+
sidebar.showStorageBucket(revealInfo.bucketInfo);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
@@ -133,7 +133,7 @@ export class ServiceWorkerCacheView extends UI.View.SimpleView {
|
|
|
133
133
|
.model(SDK.StorageBucketsModel.StorageBucketsModel)
|
|
134
134
|
?.getBucketByName(cache.storageBucket.storageKey, cache.storageBucket.name);
|
|
135
135
|
|
|
136
|
-
this.metadataView.setShowOnlyBucket(
|
|
136
|
+
this.metadataView.setShowOnlyBucket(true);
|
|
137
137
|
|
|
138
138
|
if (bucketInfo) {
|
|
139
139
|
this.metadataView.setStorageBucket(bucketInfo);
|
|
@@ -174,3 +174,14 @@ Common.Revealer.registerRevealer({
|
|
|
174
174
|
return new Resources.ResourcesPanel.AttemptViewWithFilterRevealer();
|
|
175
175
|
},
|
|
176
176
|
});
|
|
177
|
+
|
|
178
|
+
Common.Revealer.registerRevealer({
|
|
179
|
+
contextTypes() {
|
|
180
|
+
return maybeRetrieveContextTypes(Resources => [Resources.Components.StorageMetadataView.StorageBucketRevealInfo]);
|
|
181
|
+
},
|
|
182
|
+
destination: Common.Revealer.RevealerDestination.APPLICATION_PANEL,
|
|
183
|
+
async loadRevealer() {
|
|
184
|
+
const Resources = await loadResourcesModule();
|
|
185
|
+
return new Resources.ResourcesPanel.StorageBucketRevealer();
|
|
186
|
+
},
|
|
187
|
+
});
|
|
@@ -45,6 +45,7 @@ import * as TrustTokensTreeElement from './TrustTokensTreeElement.js';
|
|
|
45
45
|
import * as WebMCPTreeElement from './WebMCPTreeElement.js';
|
|
46
46
|
import * as WebMCPView from './WebMCPView.js';
|
|
47
47
|
|
|
48
|
+
export * as Components from './components/components.js';
|
|
48
49
|
export {
|
|
49
50
|
ApplicationPanelSidebar,
|
|
50
51
|
AppManifestView,
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
5
5
|
|
|
6
6
|
import '../../../ui/components/report_view/report_view.js';
|
|
7
|
+
import '../../../ui/kit/kit.js';
|
|
7
8
|
|
|
9
|
+
import * as Common from '../../../core/common/common.js';
|
|
8
10
|
import * as i18n from '../../../core/i18n/i18n.js';
|
|
9
11
|
import * as SDK from '../../../core/sdk/sdk.js';
|
|
10
12
|
import type * as Protocol from '../../../generated/protocol.js';
|
|
@@ -13,6 +15,7 @@ import * as LegacyWrapper from '../../../ui/components/legacy_wrapper/legacy_wra
|
|
|
13
15
|
import * as RenderCoordinator from '../../../ui/components/render_coordinator/render_coordinator.js';
|
|
14
16
|
import * as UI from '../../../ui/legacy/legacy.js';
|
|
15
17
|
import {html, type LitTemplate, nothing, render, type TemplateResult} from '../../../ui/lit/lit.js';
|
|
18
|
+
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
16
19
|
|
|
17
20
|
import storageMetadataViewStyle from './storageMetadataView.css.js';
|
|
18
21
|
|
|
@@ -113,12 +116,17 @@ const UIStrings = {
|
|
|
113
116
|
const str_ = i18n.i18n.registerUIStrings('panels/application/components/StorageMetadataView.ts', UIStrings);
|
|
114
117
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
115
118
|
|
|
119
|
+
export class StorageBucketRevealInfo {
|
|
120
|
+
constructor(public bucketInfo: Protocol.Storage.StorageBucketInfo) {
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
116
124
|
export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableComponent {
|
|
117
125
|
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
118
126
|
#storageBucketsModel?: SDK.StorageBucketsModel.StorageBucketsModel;
|
|
119
127
|
#storageKey: SDK.StorageKeyManager.StorageKey|null = null;
|
|
120
128
|
#storageBucket: Protocol.Storage.StorageBucketInfo|null = null;
|
|
121
|
-
#showOnlyBucket =
|
|
129
|
+
#showOnlyBucket = false;
|
|
122
130
|
|
|
123
131
|
setStorageKey(storageKey: string): void {
|
|
124
132
|
this.#storageKey = SDK.StorageKeyManager.parseStorageKey(storageKey);
|
|
@@ -220,20 +228,36 @@ export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableCo
|
|
|
220
228
|
const {bucket: {name}, persistent, durability, quota} = this.#storageBucket;
|
|
221
229
|
const isDefault = !name;
|
|
222
230
|
|
|
223
|
-
|
|
231
|
+
const renderBucketName = (): TemplateResult => {
|
|
224
232
|
if (isDefault) {
|
|
225
|
-
return html
|
|
226
|
-
${this.key(i18nString(UIStrings.bucketName))}
|
|
227
|
-
${this.value(html`<span class="default-bucket">default</span>`)}`;
|
|
233
|
+
return html`<span class="default-bucket">${i18nString(UIStrings.defaultBucket)}</span>`;
|
|
228
234
|
}
|
|
235
|
+
if (!this.#showOnlyBucket) {
|
|
236
|
+
return html`${name}`;
|
|
237
|
+
}
|
|
238
|
+
const revealBucket = (e: Event): void => {
|
|
239
|
+
e.preventDefault();
|
|
240
|
+
void Common.Revealer.reveal(
|
|
241
|
+
new StorageBucketRevealInfo(this.#storageBucket as Protocol.Storage.StorageBucketInfo));
|
|
242
|
+
};
|
|
243
|
+
return html`<devtools-link
|
|
244
|
+
@click=${revealBucket}
|
|
245
|
+
title=${name}
|
|
246
|
+
jslog=${VisualLogging.action('storage-bucket').track({
|
|
247
|
+
click: true
|
|
248
|
+
})}
|
|
249
|
+
>${name}</devtools-link>`;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
if (this.#showOnlyBucket) {
|
|
229
253
|
return html`
|
|
230
254
|
${this.key(i18nString(UIStrings.bucketName))}
|
|
231
|
-
${this.value(
|
|
255
|
+
${this.value(renderBucketName())}`;
|
|
232
256
|
}
|
|
233
257
|
// clang-format off
|
|
234
258
|
return html`
|
|
235
259
|
${this.key(i18nString(UIStrings.bucketName))}
|
|
236
|
-
${this.value(
|
|
260
|
+
${this.value(renderBucketName())}
|
|
237
261
|
${this.key(i18nString(UIStrings.persistent))}
|
|
238
262
|
${this.value(persistent ? i18nString(UIStrings.yes) : i18nString(UIStrings.no))}
|
|
239
263
|
${this.key(i18nString(UIStrings.durability))}
|
|
@@ -54,6 +54,10 @@ const UIStrings = {
|
|
|
54
54
|
* @description Text in details
|
|
55
55
|
*/
|
|
56
56
|
detailsTargetHint: 'Target hint',
|
|
57
|
+
/**
|
|
58
|
+
* @description Text in details
|
|
59
|
+
*/
|
|
60
|
+
detailsFormSubmission: 'Form submission',
|
|
57
61
|
/**
|
|
58
62
|
* @description Text in details
|
|
59
63
|
*/
|
|
@@ -62,6 +66,14 @@ const UIStrings = {
|
|
|
62
66
|
* @description Header of rule set
|
|
63
67
|
*/
|
|
64
68
|
detailsRuleSet: 'Rule set',
|
|
69
|
+
/**
|
|
70
|
+
* @description Text indicating that the preloading field is true.
|
|
71
|
+
*/
|
|
72
|
+
yes: 'Yes',
|
|
73
|
+
/**
|
|
74
|
+
* @description Text indicating that the preloading field is false.
|
|
75
|
+
*/
|
|
76
|
+
no: 'No',
|
|
65
77
|
/**
|
|
66
78
|
* @description Description: status
|
|
67
79
|
*/
|
|
@@ -202,6 +214,7 @@ export class PreloadingDetailsReportView extends LegacyWrapper.LegacyWrapper.Wra
|
|
|
202
214
|
${this.#action(isFallbackToPrefetch)}
|
|
203
215
|
${this.#status(isFallbackToPrefetch)}
|
|
204
216
|
${this.#targetHint()}
|
|
217
|
+
${this.#formSubmission()}
|
|
205
218
|
${this.#maybePrefetchFailureReason()}
|
|
206
219
|
${this.#maybePrerenderFailureReason()}
|
|
207
220
|
|
|
@@ -381,6 +394,22 @@ export class PreloadingDetailsReportView extends LegacyWrapper.LegacyWrapper.Wra
|
|
|
381
394
|
`;
|
|
382
395
|
}
|
|
383
396
|
|
|
397
|
+
#formSubmission(): Lit.LitTemplate {
|
|
398
|
+
assertNotNullOrUndefined(this.#data);
|
|
399
|
+
const attempt = this.#data.pipeline.getOriginallyTriggered();
|
|
400
|
+
const hasFormSubmission = attempt.key.formSubmission !== undefined;
|
|
401
|
+
if (!hasFormSubmission || !this.#isPrerenderLike(attempt.action)) {
|
|
402
|
+
return Lit.nothing;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return html`
|
|
406
|
+
<devtools-report-key>${i18nString(UIStrings.detailsFormSubmission)}</devtools-report-key>
|
|
407
|
+
<devtools-report-value>
|
|
408
|
+
${attempt.key.formSubmission ? i18nString(UIStrings.yes) : i18nString(UIStrings.no)}
|
|
409
|
+
</devtools-report-value>
|
|
410
|
+
`;
|
|
411
|
+
}
|
|
412
|
+
|
|
384
413
|
#maybePrerenderFailureReason(): Lit.LitTemplate {
|
|
385
414
|
assertNotNullOrUndefined(this.#data);
|
|
386
415
|
const attempt = this.#data.pipeline.getOriginallyTriggered();
|
|
@@ -2850,6 +2850,10 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
2850
2850
|
}
|
|
2851
2851
|
|
|
2852
2852
|
updateDecorations(): void {
|
|
2853
|
+
// Important to keep the entire tree node row as a clickable area for that
|
|
2854
|
+
// node.
|
|
2855
|
+
this.listItemElement.style.setProperty('--indent', this.computeLeftIndent() + 'px');
|
|
2856
|
+
|
|
2853
2857
|
if (this.isClosingTag()) {
|
|
2854
2858
|
return;
|
|
2855
2859
|
}
|
|
@@ -159,7 +159,6 @@ export class LighthousePanel extends UI.Panel.Panel {
|
|
|
159
159
|
this.renderStatusView();
|
|
160
160
|
const {lhr, artifacts} = await this.controller.collectLighthouseResults();
|
|
161
161
|
this.buildReportUI(lhr, artifacts);
|
|
162
|
-
UI.Context.Context.instance().setFlavor(ActiveLighthouseReport, new ActiveLighthouseReport(lhr));
|
|
163
162
|
return {report: lhr};
|
|
164
163
|
} catch (err) {
|
|
165
164
|
this.handleError(err);
|
|
@@ -278,6 +277,7 @@ export class LighthousePanel extends UI.Panel.Panel {
|
|
|
278
277
|
this.statusView.hide();
|
|
279
278
|
|
|
280
279
|
this.reportSelector.selectNewReport();
|
|
280
|
+
UI.Context.Context.instance().setFlavor(ActiveLighthouseReport, null);
|
|
281
281
|
this.contentElement.classList.toggle('in-progress', false);
|
|
282
282
|
|
|
283
283
|
this.startView.show(this.contentElement);
|
|
@@ -324,6 +324,8 @@ export class LighthousePanel extends UI.Panel.Panel {
|
|
|
324
324
|
this.newButton.setEnabled(true);
|
|
325
325
|
this.refreshToolbarUI();
|
|
326
326
|
|
|
327
|
+
UI.Context.Context.instance().setFlavor(ActiveLighthouseReport, new ActiveLighthouseReport(lighthouseResult));
|
|
328
|
+
|
|
327
329
|
const cachedRenderedReport = this.cachedRenderedReports.get(lighthouseResult);
|
|
328
330
|
if (cachedRenderedReport) {
|
|
329
331
|
this.auditResultsElement.appendChild(cachedRenderedReport);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import type * as SDK from '../../core/sdk/sdk.js';
|
|
8
|
-
import * as HeapSnapshotModel from '../../models/
|
|
8
|
+
import * as HeapSnapshotModel from '../../models/heap_snapshot/heap_snapshot.js';
|
|
9
9
|
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
|
|
10
10
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
11
11
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
@@ -10,7 +10,7 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
10
10
|
import * as Platform from '../../core/platform/platform.js';
|
|
11
11
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
12
12
|
import type * as Protocol from '../../generated/protocol.js';
|
|
13
|
-
import * as HeapSnapshotModel from '../../models/
|
|
13
|
+
import * as HeapSnapshotModel from '../../models/heap_snapshot/heap_snapshot.js';
|
|
14
14
|
import {createIcon} from '../../ui/kit/kit.js';
|
|
15
15
|
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
|
|
16
16
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
@@ -11,7 +11,7 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
11
11
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
12
12
|
import type * as Protocol from '../../generated/protocol.js';
|
|
13
13
|
import * as Bindings from '../../models/bindings/bindings.js';
|
|
14
|
-
import * as HeapSnapshotModel from '../../models/
|
|
14
|
+
import * as HeapSnapshotModel from '../../models/heap_snapshot/heap_snapshot.js';
|
|
15
15
|
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
|
|
16
16
|
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
|
17
17
|
import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|