chrome-devtools-frontend 1.0.1595090 → 1.0.1596260
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/host/UserMetrics.ts +0 -1
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/DOMModel.ts +206 -0
- package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/floaty.css +2 -2
- package/front_end/entrypoints/main/MainImpl.ts +0 -5
- package/front_end/generated/InspectorBackendCommands.ts +3 -5
- package/front_end/generated/protocol-mapping.d.ts +0 -8
- package/front_end/generated/protocol-proxy-api.d.ts +0 -6
- package/front_end/generated/protocol.ts +1 -19
- package/front_end/models/ai_assistance/ConversationHandler.ts +1 -1
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
- package/front_end/models/javascript_metadata/NativeFunctions.js +5 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +48 -31
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +38 -11
- package/front_end/panels/ai_assistance/components/chatMessage.css +4 -2
- package/front_end/panels/ai_assistance/components/walkthroughView.css +15 -0
- 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/StylePropertyTreeElement.ts +11 -5
- package/front_end/panels/elements/nodeStackTraceWidget.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/profiler/HeapSnapshotGridNodes.ts +11 -3
- 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/TimelineUIUtils.ts +7 -4
- package/front_end/panels/timeline/components/Utils.ts +2 -2
- package/front_end/panels/webauthn/webauthnPane.css +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- 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 +4 -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,6 +11,7 @@ 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 * as Protocol from '../../../generated/protocol.js';
|
|
14
15
|
import type {AiWidget, ComputedStyleAiWidget} from '../../../models/ai_assistance/agents/AiAgent.js';
|
|
15
16
|
import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
|
|
16
17
|
import * as ComputedStyle from '../../../models/computed_style/computed_style.js';
|
|
@@ -278,6 +279,7 @@ export interface MessageInput {
|
|
|
278
279
|
isExpanded: boolean,
|
|
279
280
|
onToggle: (isOpen: boolean) => void,
|
|
280
281
|
isInlined: boolean,
|
|
282
|
+
activeMessage: ModelChatMessage|null,
|
|
281
283
|
};
|
|
282
284
|
}
|
|
283
285
|
|
|
@@ -483,14 +485,18 @@ function renderStepDetails({
|
|
|
483
485
|
|
|
484
486
|
function renderWalkthroughSidebarButton(
|
|
485
487
|
input: ChatMessageViewInput,
|
|
486
|
-
|
|
488
|
+
steps: Step[],
|
|
487
489
|
): Lit.LitTemplate {
|
|
488
490
|
const {message, walkthrough} = input;
|
|
489
|
-
|
|
491
|
+
const lastStep = steps.at(-1);
|
|
492
|
+
if (walkthrough.isInlined || !lastStep) {
|
|
490
493
|
return Lit.nothing;
|
|
491
494
|
}
|
|
495
|
+
|
|
496
|
+
const hasOneStepWithWidget = steps.some(step => step.widgets?.length);
|
|
492
497
|
const title = walkthroughTitle({
|
|
493
498
|
isLoading: input.isLoading,
|
|
499
|
+
hasWidgets: hasOneStepWithWidget,
|
|
494
500
|
lastStep,
|
|
495
501
|
});
|
|
496
502
|
|
|
@@ -505,7 +511,7 @@ function renderWalkthroughSidebarButton(
|
|
|
505
511
|
.jslogContext=${walkthrough.isExpanded ? 'ai-hide-walkthrough-sidebar' : 'ai-show-walkthrough-sidebar'}
|
|
506
512
|
data-show-walkthrough
|
|
507
513
|
@click=${() => {
|
|
508
|
-
if(walkthrough.isExpanded) {
|
|
514
|
+
if(walkthrough.activeMessage === input.message && walkthrough.isExpanded) {
|
|
509
515
|
walkthrough.onToggle(false);
|
|
510
516
|
} else {
|
|
511
517
|
// Can't just toggle the visibility here; we need to ensure we
|
|
@@ -535,7 +541,7 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
535
541
|
// If the walkthrough is in the sidebar, we render a button into the
|
|
536
542
|
// ChatView to open it.
|
|
537
543
|
const openWalkThroughSidebarButton =
|
|
538
|
-
!input.walkthrough.isInlined ? renderWalkthroughSidebarButton(input,
|
|
544
|
+
!input.walkthrough.isInlined ? renderWalkthroughSidebarButton(input, steps) : Lit.nothing;
|
|
539
545
|
|
|
540
546
|
// If there are side-effect steps, and the walkthrough is not open, we render
|
|
541
547
|
// those inline so that the user can see them and approve them.
|
|
@@ -554,6 +560,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
554
560
|
|
|
555
561
|
// If the walkthrough is inlined (narrow width screens), render it here.
|
|
556
562
|
// Note that we force it open if there is a side-effect.
|
|
563
|
+
|
|
564
|
+
const isExpanded = (input.walkthrough.isExpanded && input.walkthrough.activeMessage === input.message) ||
|
|
565
|
+
steps.some(s => s.requestApproval);
|
|
557
566
|
// clang-format off
|
|
558
567
|
const walkthroughInline = input.walkthrough.isInlined ? html`
|
|
559
568
|
<div class="walkthrough-container">
|
|
@@ -562,9 +571,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
562
571
|
isLoading: input.isLoading && input.isLastMessage,
|
|
563
572
|
markdownRenderer: input.markdownRenderer,
|
|
564
573
|
isInlined: true,
|
|
565
|
-
isExpanded
|
|
566
|
-
(input.walkthrough.isExpanded || steps.some(step => Boolean(step.requestApproval))),
|
|
574
|
+
isExpanded,
|
|
567
575
|
onToggle: input.walkthrough.onToggle,
|
|
576
|
+
onOpen: input.walkthrough.onOpen,
|
|
568
577
|
})}></devtools-widget>
|
|
569
578
|
</div>
|
|
570
579
|
` : Lit.nothing;
|
|
@@ -649,37 +658,42 @@ interface WidgetMakerResponse {
|
|
|
649
658
|
revealable: unknown;
|
|
650
659
|
}
|
|
651
660
|
|
|
661
|
+
const computedStyleNodeCache = new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode>();
|
|
662
|
+
|
|
652
663
|
async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promise<WidgetMakerResponse|null> {
|
|
653
|
-
|
|
654
|
-
if (!
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
+
let domNodeForId = computedStyleNodeCache.get(widgetData.data.backendNodeId);
|
|
665
|
+
if (!domNodeForId) {
|
|
666
|
+
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
667
|
+
if (!target) {
|
|
668
|
+
return null;
|
|
669
|
+
}
|
|
670
|
+
const node = new SDK.DOMModel.DeferredDOMNode(
|
|
671
|
+
target,
|
|
672
|
+
widgetData.data.backendNodeId,
|
|
673
|
+
);
|
|
674
|
+
const resolved = await node.resolvePromise();
|
|
675
|
+
if (!resolved) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
domNodeForId = resolved;
|
|
679
|
+
computedStyleNodeCache.set(widgetData.data.backendNodeId, resolved);
|
|
664
680
|
}
|
|
665
|
-
const
|
|
666
|
-
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(resolved, widgetData.data.computedStyles);
|
|
681
|
+
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(domNodeForId, widgetData.data.computedStyles);
|
|
667
682
|
|
|
668
683
|
const widgetConfig = UI.Widget.widgetConfig(Elements.ComputedStyleWidget.ComputedStyleWidget, {
|
|
669
684
|
nodeStyle: styles,
|
|
670
685
|
matchedStyles: widgetData.data.matchedCascade,
|
|
671
686
|
// This disables showing the nested traces and detailed information in the widget.
|
|
672
687
|
propertyTraces: null,
|
|
673
|
-
computedStyleModel: model,
|
|
674
688
|
allowUserControl: false,
|
|
675
689
|
filterText: new RegExp(widgetData.data.properties.join('|'), 'i')
|
|
676
690
|
});
|
|
677
691
|
|
|
678
692
|
// clang-format off
|
|
679
|
-
|
|
693
|
+
const widget = html`<devtools-widget class="computed-styles-widget" .widgetConfig=${widgetConfig}></devtools-widget>`;
|
|
680
694
|
// clang-format on
|
|
681
695
|
|
|
682
|
-
return {renderedWidget: widget, revealable: new Elements.ElementsPanel.NodeComputedStyles(
|
|
696
|
+
return {renderedWidget: widget, revealable: new Elements.ElementsPanel.NodeComputedStyles(domNodeForId)};
|
|
683
697
|
}
|
|
684
698
|
|
|
685
699
|
function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTemplate {
|
|
@@ -696,15 +710,17 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
696
710
|
|
|
697
711
|
// clang-format off
|
|
698
712
|
return html`
|
|
699
|
-
<div class="widget-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
<
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
713
|
+
<div class="widget-and-revealer-container">
|
|
714
|
+
<div class="widget-content-container">
|
|
715
|
+
${response.renderedWidget}
|
|
716
|
+
</div>
|
|
717
|
+
<div class="widget-reveal-container">
|
|
718
|
+
<devtools-button class="widget-reveal"
|
|
719
|
+
.iconName=${'tab-move'}
|
|
720
|
+
.variant=${Buttons.Button.Variant.TEXT}
|
|
721
|
+
@click=${onReveal}
|
|
722
|
+
>${lockedString(UIStringsNotTranslate.reveal)}</devtools-button>
|
|
723
|
+
</div>
|
|
708
724
|
</div>
|
|
709
725
|
`;
|
|
710
726
|
// clang-format on
|
|
@@ -994,6 +1010,7 @@ export class ChatMessage extends UI.Widget.Widget {
|
|
|
994
1010
|
onToggle: () => {},
|
|
995
1011
|
isInlined: false,
|
|
996
1012
|
isExpanded: false,
|
|
1013
|
+
activeMessage: null,
|
|
997
1014
|
};
|
|
998
1015
|
|
|
999
1016
|
#suggestionsResizeObserver = new ResizeObserver(() => this.#handleSuggestionsScrollOrResize());
|
|
@@ -27,9 +27,13 @@ const UIStrings = {
|
|
|
27
27
|
*/
|
|
28
28
|
title: 'Investigation steps',
|
|
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}
|
|
@@ -117,13 +130,16 @@ export const DEFAULT_VIEW = (
|
|
|
117
130
|
const stepsOutput = steps.length > 0 ? html`
|
|
118
131
|
<div class="steps-container">
|
|
119
132
|
${steps.map((step, index) => html`
|
|
120
|
-
<div class="step
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
<div class="walkthrough-step">
|
|
134
|
+
<span class="step-number">${index+1}</span>
|
|
135
|
+
<div class="step-wrapper">
|
|
136
|
+
${renderStep({
|
|
137
|
+
step,
|
|
138
|
+
isLoading: input.isLoading,
|
|
139
|
+
markdownRenderer: input.markdownRenderer,
|
|
140
|
+
isLast: index === steps.length - 1
|
|
141
|
+
})}
|
|
142
|
+
</div>
|
|
127
143
|
</div>
|
|
128
144
|
`)}
|
|
129
145
|
</div>
|
|
@@ -152,6 +168,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
152
168
|
#isLoading = false;
|
|
153
169
|
#markdownRenderer: MarkdownLitRenderer|null = null;
|
|
154
170
|
#onToggle: (isOpen: boolean) => void = () => {};
|
|
171
|
+
#onOpen: (message: ModelChatMessage) => void = () => {};
|
|
155
172
|
#isInlined = false;
|
|
156
173
|
#isExpanded = false;
|
|
157
174
|
|
|
@@ -182,6 +199,15 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
182
199
|
return this.#message;
|
|
183
200
|
}
|
|
184
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
|
+
|
|
185
211
|
set message(message: ModelChatMessage|null) {
|
|
186
212
|
this.#message = message;
|
|
187
213
|
this.requestUpdate();
|
|
@@ -211,6 +237,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
211
237
|
isLoading: this.#isLoading,
|
|
212
238
|
markdownRenderer: this.#markdownRenderer,
|
|
213
239
|
onToggle: this.#onToggle,
|
|
240
|
+
onOpen: this.#onOpen,
|
|
214
241
|
isInlined: this.#isInlined,
|
|
215
242
|
isExpanded: this.#isExpanded,
|
|
216
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
|
|
|
@@ -38,6 +38,21 @@
|
|
|
38
38
|
gap: var(--sys-size-6);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
.walkthrough-step {
|
|
42
|
+
display: flex;
|
|
43
|
+
gap: var(--sys-size-6);
|
|
44
|
+
align-items: flex-start;
|
|
45
|
+
justify-content: flex-start;
|
|
46
|
+
|
|
47
|
+
.step-number {
|
|
48
|
+
font: var(--sys-typescale-body4-regular);
|
|
49
|
+
color: var(--sys-color-on-surface-subtle);
|
|
50
|
+
padding-top:var(--sys-size-4);
|
|
51
|
+
flex-grow: 0;
|
|
52
|
+
flex-shrink: 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
.step-wrapper {
|
|
42
57
|
display: flex;
|
|
43
58
|
flex-direction: column;
|
|
@@ -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(
|
|
@@ -1575,11 +1575,17 @@ export class GridTemplateRenderer extends rendererBase(SDK.CSSPropertyParserMatc
|
|
|
1575
1575
|
|
|
1576
1576
|
const indent = Common.Settings.Settings.instance().moduleSetting('text-editor-indent').get();
|
|
1577
1577
|
const container = document.createDocumentFragment();
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1578
|
+
|
|
1579
|
+
const template = html`
|
|
1580
|
+
${match.lines.map(line => {
|
|
1581
|
+
const lines = Renderer.render(line, context).nodes;
|
|
1582
|
+
return html`
|
|
1583
|
+
<span class='styles-clipboard-only'>${indent.repeat(2)}</span>
|
|
1584
|
+
${lines}`;
|
|
1585
|
+
})}
|
|
1586
|
+
`;
|
|
1587
|
+
|
|
1588
|
+
render(template, container);
|
|
1583
1589
|
return [container];
|
|
1584
1590
|
}
|
|
1585
1591
|
}
|