chrome-devtools-frontend 1.0.1603822 → 1.0.1604514
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/front_end/core/host/AidaClient.ts +39 -462
- package/front_end/core/host/AidaClientTypes.ts +470 -0
- package/front_end/core/host/AidaGcaTranslation.ts +225 -122
- package/front_end/core/host/GcaTypes.ts +107 -155
- package/front_end/core/protocol_client/DevToolsCDPConnection.ts +1 -1
- package/front_end/core/sdk/DOMModel.ts +24 -22
- package/front_end/core/sdk/EmulationModel.ts +21 -23
- package/front_end/core/sdk/HeapProfilerModel.ts +4 -7
- package/front_end/core/sdk/NetworkManager.ts +35 -28
- package/front_end/core/sdk/OverlayModel.ts +10 -10
- package/front_end/core/sdk/PreloadingModel.ts +3 -4
- package/front_end/core/sdk/ServiceWorkerManager.ts +2 -3
- package/front_end/core/sdk/SourceMapScopesInfo.ts +93 -63
- package/front_end/entrypoints/formatter_worker/FormatterWorker.ts +1 -3
- package/front_end/entrypoints/heap_snapshot_worker/AllocationProfile.ts +22 -48
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +1 -1
- package/front_end/generated/InspectorBackendCommands.ts +4 -0
- package/front_end/generated/SupportedCSSProperties.js +68 -2
- package/front_end/generated/protocol-mapping.d.ts +7 -0
- package/front_end/generated/protocol-proxy-api.d.ts +14 -0
- package/front_end/generated/protocol.ts +22 -0
- package/front_end/models/bindings/TempFile.ts +1 -4
- package/front_end/models/extensions/ExtensionAPI.ts +1 -1
- package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +34 -47
- package/front_end/models/javascript_metadata/NativeFunctions.js +6 -6
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +88 -19
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +14 -20
- package/front_end/panels/ai_assistance/components/ChatView.ts +3 -2
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +35 -7
- package/front_end/panels/elements/ElementsTreeElement.ts +91 -13
- package/front_end/panels/elements/elementsTreeOutline.css +18 -0
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +15 -19
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +4 -2
- package/front_end/panels/profiler/HeapSnapshotProxy.ts +12 -16
- package/front_end/panels/profiler/HeapSnapshotView.ts +3 -10
- package/front_end/panels/profiler/ProfilesPanel.ts +5 -7
- package/front_end/panels/sensors/SensorsView.ts +0 -2
- package/front_end/panels/timeline/TimelinePanel.ts +1 -3
- package/front_end/panels/timeline/components/LiveMetricsView.ts +35 -63
- package/front_end/panels/timeline/components/liveMetricsView.css +4 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/package.json +1 -1
|
@@ -36,7 +36,7 @@ import * as TimelineUtils from '../../timeline/utils/utils.js';
|
|
|
36
36
|
import {PanelUtils} from '../../utils/utils.js';
|
|
37
37
|
|
|
38
38
|
import chatMessageStyles from './chatMessage.css.js';
|
|
39
|
-
import {walkthroughTitle, WalkthroughView} from './WalkthroughView.js';
|
|
39
|
+
import {walkthroughCloseTitle, walkthroughTitle, WalkthroughView} from './WalkthroughView.js';
|
|
40
40
|
|
|
41
41
|
const {html, Directives: {ref, ifDefined}} = Lit;
|
|
42
42
|
const lockedString = i18n.i18n.lockedString;
|
|
@@ -49,10 +49,6 @@ const SCROLL_ROUNDING_OFFSET = 1;
|
|
|
49
49
|
* Strings that don't need to be translated at this time.
|
|
50
50
|
*/
|
|
51
51
|
const UIStringsNotTranslate = {
|
|
52
|
-
/**
|
|
53
|
-
* @description Text used in the button to close an open walkthrough
|
|
54
|
-
*/
|
|
55
|
-
closeAgentWalkthrough: 'Close agent walkthrough',
|
|
56
52
|
/**
|
|
57
53
|
* @description The title of the button that allows submitting positive
|
|
58
54
|
* feedback about the response for AI assistance.
|
|
@@ -174,11 +170,6 @@ const UIStringsNotTranslate = {
|
|
|
174
170
|
* @description Alt text for image when it is not available.
|
|
175
171
|
*/
|
|
176
172
|
imageUnavailable: 'Image unavailable',
|
|
177
|
-
/**
|
|
178
|
-
* @description Title for the button that shows the thinking process (walkthrough).
|
|
179
|
-
*/
|
|
180
|
-
showThinking: 'Show thinking',
|
|
181
|
-
|
|
182
173
|
/**
|
|
183
174
|
* @description Title for the button that takes the user into other DevTools panels to reveal items the AI references.
|
|
184
175
|
*/
|
|
@@ -310,9 +301,10 @@ export interface MessageInput {
|
|
|
310
301
|
walkthrough: {
|
|
311
302
|
onOpen: (message: ModelChatMessage) => void,
|
|
312
303
|
isExpanded: boolean,
|
|
313
|
-
onToggle: (isOpen: boolean) => void,
|
|
304
|
+
onToggle: (isOpen: boolean, message: ModelChatMessage) => void,
|
|
314
305
|
isInlined: boolean,
|
|
315
|
-
|
|
306
|
+
activeSidebarMessage: ModelChatMessage|null,
|
|
307
|
+
inlineExpandedMessages: ModelChatMessage[],
|
|
316
308
|
};
|
|
317
309
|
}
|
|
318
310
|
|
|
@@ -516,9 +508,8 @@ function renderWalkthroughSidebarButton(
|
|
|
516
508
|
}
|
|
517
509
|
|
|
518
510
|
const hasOneStepWithWidget = steps.some(step => step.widgets?.length);
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
const title = isOpen ? lockedString(UIStringsNotTranslate.closeAgentWalkthrough) : walkthroughTitle({
|
|
511
|
+
const isExpanded = walkthrough.isExpanded && input.message === input.walkthrough.activeSidebarMessage;
|
|
512
|
+
const title = isExpanded ? walkthroughCloseTitle({hasWidgets: hasOneStepWithWidget}) : walkthroughTitle({
|
|
522
513
|
isLoading: input.isLoading,
|
|
523
514
|
hasWidgets: hasOneStepWithWidget,
|
|
524
515
|
lastStep,
|
|
@@ -536,12 +527,12 @@ function renderWalkthroughSidebarButton(
|
|
|
536
527
|
<devtools-button
|
|
537
528
|
.variant=${variant}
|
|
538
529
|
.size=${Buttons.Button.Size.SMALL}
|
|
539
|
-
.title=${lastStep.isLoading ? titleForStep(lastStep) :
|
|
530
|
+
.title=${lastStep.isLoading ? titleForStep(lastStep) : title}
|
|
540
531
|
.jslogContext=${walkthrough.isExpanded ? 'ai-hide-walkthrough-sidebar' : 'ai-show-walkthrough-sidebar'}
|
|
541
532
|
data-show-walkthrough
|
|
542
533
|
@click=${() => {
|
|
543
|
-
if(walkthrough.
|
|
544
|
-
walkthrough.onToggle(false);
|
|
534
|
+
if(walkthrough.activeSidebarMessage === input.message && walkthrough.isExpanded) {
|
|
535
|
+
walkthrough.onToggle(false, message as ModelChatMessage);
|
|
545
536
|
} else {
|
|
546
537
|
// Can't just toggle the visibility here; we need to ensure we
|
|
547
538
|
// update the state with this message as the user could have had
|
|
@@ -577,7 +568,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
577
568
|
// A message's walkthrough is considered expanded if the walkthrough is
|
|
578
569
|
// open and it is specifically targeting this message. This is necessary
|
|
579
570
|
// because the walkthrough state is shared across all messages in the chat.
|
|
580
|
-
const isExpanded =
|
|
571
|
+
const isExpanded = input.walkthrough.isInlined ?
|
|
572
|
+
input.walkthrough.inlineExpandedMessages.includes(input.message as ModelChatMessage) :
|
|
573
|
+
(input.walkthrough.isExpanded && input.walkthrough.activeSidebarMessage === input.message);
|
|
581
574
|
|
|
582
575
|
// When a side-effect step is present, it's shown in the main chat UI if the
|
|
583
576
|
// walkthrough is closed, allowing the user to approve it without opening
|
|
@@ -1238,7 +1231,8 @@ export class ChatMessage extends UI.Widget.Widget {
|
|
|
1238
1231
|
onToggle: () => {},
|
|
1239
1232
|
isInlined: false,
|
|
1240
1233
|
isExpanded: false,
|
|
1241
|
-
|
|
1234
|
+
activeSidebarMessage: null,
|
|
1235
|
+
inlineExpandedMessages: [],
|
|
1242
1236
|
};
|
|
1243
1237
|
|
|
1244
1238
|
#suggestionsResizeObserver = new ResizeObserver(() => this.#handleSuggestionsScrollOrResize());
|
|
@@ -88,10 +88,11 @@ export interface Props {
|
|
|
88
88
|
generateConversationSummary: (markdown: string) => Promise<string>;
|
|
89
89
|
walkthrough: {
|
|
90
90
|
onOpen: (message: ModelChatMessage) => void,
|
|
91
|
-
onToggle: (isOpen: boolean) => void,
|
|
91
|
+
onToggle: (isOpen: boolean, message: ModelChatMessage) => void,
|
|
92
92
|
isExpanded: boolean,
|
|
93
93
|
isInlined: boolean,
|
|
94
|
-
|
|
94
|
+
activeSidebarMessage: ModelChatMessage|null,
|
|
95
|
+
inlineExpandedMessages: ModelChatMessage[],
|
|
95
96
|
};
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -36,6 +36,14 @@ const UIStrings = {
|
|
|
36
36
|
* @description Title for the button that shows the walkthrough when there are widgets in the walkthrough.
|
|
37
37
|
*/
|
|
38
38
|
showAgentWalkthrough: 'Show agent walkthrough',
|
|
39
|
+
/**
|
|
40
|
+
* @description Title for the button that hides the walkthrough when there are no widgets in the walkthrough.
|
|
41
|
+
*/
|
|
42
|
+
hideThinking: 'Hide thinking',
|
|
43
|
+
/**
|
|
44
|
+
* @description Title for the button that hides the walkthrough when there are widgets in the walkthrough.
|
|
45
|
+
*/
|
|
46
|
+
hideAgentWalkthrough: 'Hide agent walkthrough',
|
|
39
47
|
} as const;
|
|
40
48
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/components/WalkthroughView.ts', UIStrings);
|
|
41
49
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -46,7 +54,7 @@ export interface ViewInput {
|
|
|
46
54
|
markdownRenderer: MarkdownLitRenderer;
|
|
47
55
|
isInlined: boolean;
|
|
48
56
|
isExpanded: boolean;
|
|
49
|
-
onToggle: (isOpen: boolean) => void;
|
|
57
|
+
onToggle: (isOpen: boolean, message: ModelChatMessage) => void;
|
|
50
58
|
onOpen: (message: ModelChatMessage) => void;
|
|
51
59
|
handleScroll: (ev: Event) => void;
|
|
52
60
|
}
|
|
@@ -70,6 +78,19 @@ export function walkthroughTitle(input: {
|
|
|
70
78
|
return lockedString(UIStrings.showThinking);
|
|
71
79
|
}
|
|
72
80
|
|
|
81
|
+
export function walkthroughCloseTitle(input: {
|
|
82
|
+
hasWidgets: boolean,
|
|
83
|
+
isInlined?: boolean,
|
|
84
|
+
}): string {
|
|
85
|
+
if (input.isInlined) {
|
|
86
|
+
return i18nString(UIStrings.title);
|
|
87
|
+
}
|
|
88
|
+
if (input.hasWidgets) {
|
|
89
|
+
return lockedString(UIStrings.hideAgentWalkthrough);
|
|
90
|
+
}
|
|
91
|
+
return lockedString(UIStrings.hideThinking);
|
|
92
|
+
}
|
|
93
|
+
|
|
73
94
|
function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate, steps: Step[]): Lit.LitTemplate {
|
|
74
95
|
const lastStep = steps.at(-1);
|
|
75
96
|
if (!input.isInlined || !lastStep) {
|
|
@@ -78,10 +99,13 @@ function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate,
|
|
|
78
99
|
|
|
79
100
|
function onToggle(event: Event): void {
|
|
80
101
|
const isOpen = (event.target as HTMLDetailsElement).open;
|
|
81
|
-
if (
|
|
102
|
+
if (!input.message) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (isOpen) {
|
|
82
106
|
input.onOpen(input.message);
|
|
83
107
|
} else {
|
|
84
|
-
input.onToggle(isOpen);
|
|
108
|
+
input.onToggle(isOpen, input.message);
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
111
|
|
|
@@ -92,7 +116,7 @@ function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate,
|
|
|
92
116
|
<details class="walkthrough-inline" ?open=${input.isExpanded} @toggle=${onToggle}>
|
|
93
117
|
<summary ?data-has-widgets=${!input.isLoading && hasWidgets}>
|
|
94
118
|
${input.isLoading ? html`<devtools-spinner></devtools-spinner>` : Lit.nothing}
|
|
95
|
-
${walkthroughTitle({isLoading: input.isLoading, lastStep, hasWidgets})}
|
|
119
|
+
${input.isExpanded ? walkthroughCloseTitle({hasWidgets, isInlined: true}) : walkthroughTitle({isLoading: input.isLoading, lastStep, hasWidgets})}
|
|
96
120
|
<devtools-icon name="chevron-right"></devtools-icon>
|
|
97
121
|
</summary>
|
|
98
122
|
${stepsOutput}
|
|
@@ -118,7 +142,11 @@ function renderSidebarWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate
|
|
|
118
142
|
title: i18nString(UIStrings.close),
|
|
119
143
|
jslogContext: 'close-walkthrough',
|
|
120
144
|
} as Buttons.Button.ButtonData}
|
|
121
|
-
@click=${() =>
|
|
145
|
+
@click=${() => {
|
|
146
|
+
if (input.message) {
|
|
147
|
+
input.onToggle(false, input.message);
|
|
148
|
+
}
|
|
149
|
+
}}
|
|
122
150
|
></devtools-button>
|
|
123
151
|
</div>
|
|
124
152
|
${stepsOutput}
|
|
@@ -184,7 +212,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
184
212
|
#message: ModelChatMessage|null = null;
|
|
185
213
|
#isLoading = false;
|
|
186
214
|
#markdownRenderer: MarkdownLitRenderer|null = null;
|
|
187
|
-
#onToggle: (isOpen: boolean) => void = () => {};
|
|
215
|
+
#onToggle: (isOpen: boolean, message: ModelChatMessage) => void = () => {};
|
|
188
216
|
#onOpen: (message: ModelChatMessage) => void = () => {};
|
|
189
217
|
#isInlined = false;
|
|
190
218
|
#isExpanded = false;
|
|
@@ -318,7 +346,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
318
346
|
this.requestUpdate();
|
|
319
347
|
}
|
|
320
348
|
|
|
321
|
-
set onToggle(onToggle: (isOpen: boolean) => void) {
|
|
349
|
+
set onToggle(onToggle: (isOpen: boolean, message: ModelChatMessage) => void) {
|
|
322
350
|
this.#onToggle = onToggle;
|
|
323
351
|
this.requestUpdate();
|
|
324
352
|
}
|
|
@@ -78,9 +78,25 @@ const {animateOn} = UI.UIUtils;
|
|
|
78
78
|
|
|
79
79
|
const UIStrings = {
|
|
80
80
|
/**
|
|
81
|
-
* @description Title for Ad adorner. This
|
|
81
|
+
* @description Title for Ad adorner. This element is marked as advertisement element.
|
|
82
82
|
*/
|
|
83
|
-
|
|
83
|
+
thisElementWasIdentifiedAsAnAd: 'This element was identified as an ad',
|
|
84
|
+
/**
|
|
85
|
+
* @description Title of a section in the Ad adorner tooltip. Lists the ad script(s) responsible for generating this element.
|
|
86
|
+
*/
|
|
87
|
+
creatorAdScriptAncestry: 'Creator ad script ancestry',
|
|
88
|
+
/**
|
|
89
|
+
* @description Title of a section in the Ad adorner tooltip. The filter list rule that flagged the root script in 'Creator ad script ancestry' as an ad.
|
|
90
|
+
*/
|
|
91
|
+
rootScriptFilterListRule: 'Root script filter list rule',
|
|
92
|
+
/**
|
|
93
|
+
* @description Title of a section in the Ad adorner tooltip. The filter list rule that flagged the element's current resource.
|
|
94
|
+
*/
|
|
95
|
+
filterListRule: 'Filter list rule',
|
|
96
|
+
/**
|
|
97
|
+
* @description Title of a section in the Ad adorner tooltip. This element was identified as an ad, but no provenance data is available.
|
|
98
|
+
*/
|
|
99
|
+
noProvenanceAvailable: 'No provenance data is available',
|
|
84
100
|
/**
|
|
85
101
|
* @description A context menu item in the Elements panel. Force is used as a verb, indicating intention to make the state change.
|
|
86
102
|
*/
|
|
@@ -399,7 +415,10 @@ export interface ViewInput {
|
|
|
399
415
|
gridAdornerActive: boolean;
|
|
400
416
|
popoverAdornerActive: boolean;
|
|
401
417
|
|
|
402
|
-
|
|
418
|
+
adProvenance?: Protocol.Network.AdProvenance;
|
|
419
|
+
target?: SDK.Target.Target;
|
|
420
|
+
adTooltipId: string;
|
|
421
|
+
|
|
403
422
|
showContainerAdorner: boolean;
|
|
404
423
|
containerType?: string;
|
|
405
424
|
showFlexAdorner: boolean;
|
|
@@ -851,8 +870,66 @@ function renderTag(
|
|
|
851
870
|
attributes.map(attr => html` ${renderAttribute(attr, updateRecord, false, node)}`)}></span>\u200B`;
|
|
852
871
|
}
|
|
853
872
|
|
|
873
|
+
function maybeRenderAdAdorner(input: ViewInput): Lit.TemplateResult|typeof nothing {
|
|
874
|
+
if (!input.adProvenance) {
|
|
875
|
+
return nothing;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// clang-format off
|
|
879
|
+
return html`
|
|
880
|
+
<devtools-adorner
|
|
881
|
+
aria-describedby=${input.adTooltipId}
|
|
882
|
+
aria-label=${i18nString(UIStrings.thisElementWasIdentifiedAsAnAd)}
|
|
883
|
+
.name=${ElementsComponents.AdornerManager.RegisteredAdorners.AD}
|
|
884
|
+
jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.AD)}
|
|
885
|
+
${adornerRef()}>
|
|
886
|
+
<span>${ElementsComponents.AdornerManager.RegisteredAdorners.AD}</span>
|
|
887
|
+
</devtools-adorner>
|
|
888
|
+
|
|
889
|
+
<!--
|
|
890
|
+
Prevent the copy event from bubbling up to the Elements tree outline. Otherwise, DevTools
|
|
891
|
+
copies the underlying DOM node's HTML instead of the user's highlighted text.
|
|
892
|
+
-->
|
|
893
|
+
<devtools-tooltip id=${input.adTooltipId} variant=rich @copy=${(e: Event) => e.stopPropagation()}>
|
|
894
|
+
<div class="ad-provenance-tooltip">
|
|
895
|
+
${input.adProvenance.filterlistRule ? html`
|
|
896
|
+
<div class="ad-provenance-tooltip-title">${i18nString(UIStrings.filterListRule)}</div>
|
|
897
|
+
<div class="ad-provenance-tooltip-content">${input.adProvenance.filterlistRule}</div>
|
|
898
|
+
` : nothing}
|
|
899
|
+
|
|
900
|
+
${input.adProvenance.adScriptAncestry && input.target ? html`
|
|
901
|
+
<div class="ad-provenance-tooltip-title">${i18nString(UIStrings.creatorAdScriptAncestry)}</div>
|
|
902
|
+
<div class="ad-provenance-tooltip-content">
|
|
903
|
+
${input.adProvenance.adScriptAncestry.ancestryChain.map(script => html`
|
|
904
|
+
<div>
|
|
905
|
+
${UI.Widget.widget(Components.Linkifier.ScriptLocationLink, {
|
|
906
|
+
target: input.target,
|
|
907
|
+
scriptId: script.scriptId,
|
|
908
|
+
options: { jslogContext: 'ad-script' },
|
|
909
|
+
})}
|
|
910
|
+
</div>
|
|
911
|
+
`)}
|
|
912
|
+
</div>
|
|
913
|
+
|
|
914
|
+
${input.adProvenance.adScriptAncestry.rootScriptFilterlistRule ? html`
|
|
915
|
+
<div class="ad-provenance-tooltip-title">${i18nString(UIStrings.rootScriptFilterListRule)}</div>
|
|
916
|
+
<div class="ad-provenance-tooltip-content">
|
|
917
|
+
${input.adProvenance.adScriptAncestry.rootScriptFilterlistRule}
|
|
918
|
+
</div>
|
|
919
|
+
` : nothing}
|
|
920
|
+
` : nothing}
|
|
921
|
+
|
|
922
|
+
${!input.adProvenance.adScriptAncestry && !input.adProvenance.filterlistRule ? html`
|
|
923
|
+
<div class="ad-provenance-tooltip-title">${i18nString(UIStrings.noProvenanceAvailable)}</div>
|
|
924
|
+
` : nothing}
|
|
925
|
+
</div>
|
|
926
|
+
</devtools-tooltip>
|
|
927
|
+
`;
|
|
928
|
+
// clang-format on
|
|
929
|
+
}
|
|
930
|
+
|
|
854
931
|
export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
|
|
855
|
-
const hasAdorners = input.
|
|
932
|
+
const hasAdorners = !!input.adProvenance || input.showContainerAdorner || input.showFlexAdorner ||
|
|
856
933
|
input.showGridAdorner || input.showGridLanesAdorner || input.showMediaAdorner || input.showPopoverAdorner ||
|
|
857
934
|
input.showTopLayerAdorner || input.showViewSourceAdorner || input.showScrollAdorner ||
|
|
858
935
|
input.showScrollSnapAdorner || input.showSlotAdorner || input.showStartingStyleAdorner;
|
|
@@ -888,13 +965,7 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
|
888
965
|
</div>` : nothing}
|
|
889
966
|
</div>
|
|
890
967
|
${hasAdorners ? html`<div class="adorner-container ${!hasAdorners ? 'hidden' : ''}">
|
|
891
|
-
${input
|
|
892
|
-
aria-label=${i18nString(UIStrings.thisFrameWasIdentifiedAsAnAd)}
|
|
893
|
-
.name=${ElementsComponents.AdornerManager.RegisteredAdorners.AD}
|
|
894
|
-
jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.AD)}
|
|
895
|
-
${adornerRef()}>
|
|
896
|
-
<span>${ElementsComponents.AdornerManager.RegisteredAdorners.AD}</span>
|
|
897
|
-
</devtools-adorner>` : nothing}
|
|
968
|
+
${maybeRenderAdAdorner(input)}
|
|
898
969
|
${input.showViewSourceAdorner ? html`<devtools-adorner
|
|
899
970
|
.name=${ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE}
|
|
900
971
|
jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE)}
|
|
@@ -1102,6 +1173,9 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
1102
1173
|
#descendantDecorations: Decoration[] = [];
|
|
1103
1174
|
#decorationsTooltip = '';
|
|
1104
1175
|
|
|
1176
|
+
static #adTooltipIdCounter = 0;
|
|
1177
|
+
#adTooltipId = `ad-tooltip-${++ElementsTreeElement.#adTooltipIdCounter}`;
|
|
1178
|
+
|
|
1105
1179
|
#updateRecord: Elements.ElementUpdateRecord.ElementUpdateRecord|null = null;
|
|
1106
1180
|
|
|
1107
1181
|
// Used to add the content to TreeElement's title element.
|
|
@@ -1230,7 +1304,9 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
1230
1304
|
onExpand: () => this.expand(),
|
|
1231
1305
|
|
|
1232
1306
|
containerAdornerActive: this.#containerAdornerActive,
|
|
1233
|
-
|
|
1307
|
+
adProvenance: this.nodeInternal.adProvenance(),
|
|
1308
|
+
adTooltipId: this.#adTooltipId,
|
|
1309
|
+
target: this.nodeInternal.domModel().target(),
|
|
1234
1310
|
showContainerAdorner: Boolean(this.#layout?.containerType) && !this.isClosingTag(),
|
|
1235
1311
|
containerType: this.#layout?.containerType,
|
|
1236
1312
|
showFlexAdorner: Boolean(this.#layout?.isFlex) && !this.isClosingTag(),
|
|
@@ -1565,7 +1641,9 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
1565
1641
|
onHighlightSearchResults: () => {},
|
|
1566
1642
|
onExpand: () => {},
|
|
1567
1643
|
containerAdornerActive: false,
|
|
1568
|
-
|
|
1644
|
+
adProvenance: undefined,
|
|
1645
|
+
target: undefined,
|
|
1646
|
+
adTooltipId: '',
|
|
1569
1647
|
showContainerAdorner: false,
|
|
1570
1648
|
containerType: this.#layout?.containerType,
|
|
1571
1649
|
showFlexAdorner: false,
|
|
@@ -384,3 +384,21 @@ li.hovered:not(.always-parent) + ol.children:not(.shadow-root) {
|
|
|
384
384
|
background-position: bottom;
|
|
385
385
|
padding-bottom: 1px;
|
|
386
386
|
}
|
|
387
|
+
|
|
388
|
+
/* Ad Provenance Tooltip */
|
|
389
|
+
.ad-provenance-tooltip {
|
|
390
|
+
user-select: text;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.ad-provenance-tooltip-title {
|
|
394
|
+
color: var(--sys-color-on-surface-subtle);
|
|
395
|
+
margin-top: 4px;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.ad-provenance-tooltip-title:first-child {
|
|
399
|
+
margin-top: 0;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.ad-provenance-tooltip-content {
|
|
403
|
+
padding-left: 16px;
|
|
404
|
+
}
|
|
@@ -132,13 +132,13 @@ class HeapSnapshotSortableDataGridBase extends DataGrid.DataGrid.DataGridImpl<He
|
|
|
132
132
|
export class HeapSnapshotSortableDataGrid extends Common.ObjectWrapper
|
|
133
133
|
.eventMixin<EventTypes, typeof HeapSnapshotSortableDataGridBase>(
|
|
134
134
|
HeapSnapshotSortableDataGridBase) {
|
|
135
|
-
snapshot: HeapSnapshotProxy|null;
|
|
136
|
-
override selectedNode: HeapSnapshotGridNode|null;
|
|
135
|
+
snapshot: HeapSnapshotProxy|null = null;
|
|
136
|
+
override selectedNode: HeapSnapshotGridNode|null = null;
|
|
137
137
|
readonly heapProfilerModelInternal: SDK.HeapProfilerModel.HeapProfilerModel|null;
|
|
138
138
|
readonly dataDisplayDelegateInternal: DataDisplayDelegate;
|
|
139
|
-
recursiveSortingDepth
|
|
140
|
-
populatedAndSorted
|
|
141
|
-
nameFilter: UI.Toolbar.ToolbarInput|null;
|
|
139
|
+
recursiveSortingDepth = 0;
|
|
140
|
+
populatedAndSorted = false;
|
|
141
|
+
nameFilter: UI.Toolbar.ToolbarInput|null = null;
|
|
142
142
|
nodeFilterInternal: HeapSnapshotModel.HeapSnapshotModel.NodeFilter|undefined;
|
|
143
143
|
lastSortColumnId?: string|null;
|
|
144
144
|
lastSortAscending?: boolean;
|
|
@@ -147,8 +147,6 @@ export class HeapSnapshotSortableDataGrid extends Common.ObjectWrapper
|
|
|
147
147
|
dataGridParameters: DataGrid.DataGrid.Parameters) {
|
|
148
148
|
// TODO(allada) This entire class needs to be converted to use the templates in DataGridNode.
|
|
149
149
|
super(dataGridParameters);
|
|
150
|
-
this.snapshot = null;
|
|
151
|
-
this.selectedNode = null;
|
|
152
150
|
this.heapProfilerModelInternal = heapProfilerModel;
|
|
153
151
|
this.dataDisplayDelegateInternal = dataDisplayDelegate;
|
|
154
152
|
const tooltips = [
|
|
@@ -743,9 +741,9 @@ export enum HeapSnapshotRetainmentDataGridEvents {
|
|
|
743
741
|
}
|
|
744
742
|
|
|
745
743
|
export class HeapSnapshotConstructorsDataGrid extends HeapSnapshotViewportDataGrid {
|
|
746
|
-
profileIndex
|
|
747
|
-
objectIdToSelect: string|null;
|
|
748
|
-
nextRequestedFilter: HeapSnapshotModel.HeapSnapshotModel.NodeFilter|null;
|
|
744
|
+
profileIndex = -1;
|
|
745
|
+
objectIdToSelect: string|null = null;
|
|
746
|
+
nextRequestedFilter: HeapSnapshotModel.HeapSnapshotModel.NodeFilter|null = null;
|
|
749
747
|
lastFilter?: HeapSnapshotModel.HeapSnapshotModel.NodeFilter|null;
|
|
750
748
|
filterInProgress?: HeapSnapshotModel.HeapSnapshotModel.NodeFilter|null;
|
|
751
749
|
|
|
@@ -773,14 +771,13 @@ export class HeapSnapshotConstructorsDataGrid extends HeapSnapshotViewportDataGr
|
|
|
773
771
|
},
|
|
774
772
|
];
|
|
775
773
|
super(
|
|
776
|
-
heapProfilerModel,
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
this.nextRequestedFilter = null;
|
|
774
|
+
heapProfilerModel,
|
|
775
|
+
dataDisplayDelegate,
|
|
776
|
+
{
|
|
777
|
+
displayName: i18nString(UIStrings.heapSnapshotConstructors).toString(),
|
|
778
|
+
columns,
|
|
779
|
+
},
|
|
780
|
+
);
|
|
784
781
|
}
|
|
785
782
|
|
|
786
783
|
override sortFields(sortColumn: string, sortAscending: boolean):
|
|
@@ -1015,7 +1012,6 @@ export class AllocationDataGrid extends HeapSnapshotViewportDataGrid {
|
|
|
1015
1012
|
super(
|
|
1016
1013
|
heapProfilerModel, dataDisplayDelegate,
|
|
1017
1014
|
({displayName: i18nString(UIStrings.allocation).toString(), columns} as DataGrid.DataGrid.Parameters));
|
|
1018
|
-
// clang-format on
|
|
1019
1015
|
this.linkifierInternal = new Components.Linkifier.Linkifier();
|
|
1020
1016
|
}
|
|
1021
1017
|
|
|
@@ -1290,8 +1290,10 @@ export class HeapSnapshotDiffNode extends HeapSnapshotGridNode {
|
|
|
1290
1290
|
readonly classKey: string;
|
|
1291
1291
|
|
|
1292
1292
|
constructor(
|
|
1293
|
-
dataGrid: HeapSnapshotDiffDataGrid,
|
|
1294
|
-
|
|
1293
|
+
dataGrid: HeapSnapshotDiffDataGrid,
|
|
1294
|
+
classKey: string,
|
|
1295
|
+
diffForClass: HeapSnapshotModel.HeapSnapshotModel.Diff,
|
|
1296
|
+
) {
|
|
1295
1297
|
super(dataGrid, true);
|
|
1296
1298
|
this.nameInternal = diffForClass.name;
|
|
1297
1299
|
this.addedCount = diffForClass.addedCount;
|
|
@@ -20,26 +20,19 @@ const UIStrings = {
|
|
|
20
20
|
const str_ = i18n.i18n.registerUIStrings('panels/profiler/HeapSnapshotProxy.ts', UIStrings);
|
|
21
21
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
22
22
|
export class HeapSnapshotWorkerProxy extends Common.ObjectWrapper.ObjectWrapper<HeapSnapshotWorkerProxy.EventTypes> {
|
|
23
|
+
readonly eventHandler: (arg0: string, arg1: string) => void;
|
|
24
|
+
nextObjectId = 1;
|
|
25
|
+
nextCallId = 1;
|
|
23
26
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
|
24
27
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
nextCallId: number;
|
|
28
|
-
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
-
callbacks: Map<number, (arg0: any) => void>;
|
|
31
|
-
readonly previousCallbacks: Set<number>;
|
|
28
|
+
callbacks = new Map<number, (arg0: any) => void>();
|
|
29
|
+
readonly previousCallbacks = new Set<number>();
|
|
32
30
|
readonly worker: PlatformApi.HostRuntime.Worker;
|
|
33
31
|
interval?: number;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
constructor(eventHandler: (arg0: string, arg1: any) => void) {
|
|
32
|
+
|
|
33
|
+
constructor(eventHandler: (arg0: string, arg1: string) => void) {
|
|
37
34
|
super();
|
|
38
35
|
this.eventHandler = eventHandler;
|
|
39
|
-
this.nextObjectId = 1;
|
|
40
|
-
this.nextCallId = 1;
|
|
41
|
-
this.callbacks = new Map();
|
|
42
|
-
this.previousCallbacks = new Set();
|
|
43
36
|
this.worker = Platform.HostRuntime.HOST_RUNTIME.createWorker(
|
|
44
37
|
new URL('../../entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.js', import.meta.url)
|
|
45
38
|
.toString());
|
|
@@ -243,8 +236,11 @@ export class HeapSnapshotLoaderProxy extends HeapSnapshotProxyObject implements
|
|
|
243
236
|
readonly profileUid: number;
|
|
244
237
|
readonly snapshotReceivedCallback: (arg0: HeapSnapshotProxy) => void;
|
|
245
238
|
constructor(
|
|
246
|
-
worker: HeapSnapshotWorkerProxy,
|
|
247
|
-
|
|
239
|
+
worker: HeapSnapshotWorkerProxy,
|
|
240
|
+
objectId: number,
|
|
241
|
+
profileUid: number,
|
|
242
|
+
snapshotReceivedCallback: (arg0: HeapSnapshotProxy) => void,
|
|
243
|
+
) {
|
|
248
244
|
super(worker, objectId);
|
|
249
245
|
this.profileUid = profileUid;
|
|
250
246
|
this.snapshotReceivedCallback = snapshotReceivedCallback;
|
|
@@ -1557,9 +1557,6 @@ export class TrackingHeapSnapshotProfileType extends
|
|
|
1557
1557
|
}
|
|
1558
1558
|
this.setProfileBeingRecorded(new HeapProfileHeader(heapProfilerModel, this, undefined));
|
|
1559
1559
|
this.profileSamples = new Samples();
|
|
1560
|
-
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
|
1561
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1562
|
-
(this.profileBeingRecorded() as any)._profileSamples = this.profileSamples;
|
|
1563
1560
|
this.recording = true;
|
|
1564
1561
|
this.addProfile((this.profileBeingRecorded() as ProfileHeader));
|
|
1565
1562
|
(this.profileBeingRecorded() as HeapProfileHeader).updateStatus(i18nString(UIStrings.recording));
|
|
@@ -1733,20 +1730,16 @@ export class HeapProfileHeader extends ProfileHeader {
|
|
|
1733
1730
|
this.receiver = this.workerProxy.createLoader(this.uid, this.snapshotReceived.bind(this));
|
|
1734
1731
|
}
|
|
1735
1732
|
|
|
1736
|
-
|
|
1737
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1738
|
-
handleWorkerEvent(eventName: string, data: any): void {
|
|
1733
|
+
handleWorkerEvent(eventName: string, data: string): void {
|
|
1739
1734
|
if (HeapSnapshotModel.HeapSnapshotModel.HeapSnapshotProgressEvent.BrokenSnapshot === eventName) {
|
|
1740
|
-
|
|
1741
|
-
Common.Console.Console.instance().error(error);
|
|
1735
|
+
Common.Console.Console.instance().error(data);
|
|
1742
1736
|
return;
|
|
1743
1737
|
}
|
|
1744
1738
|
|
|
1745
1739
|
if (HeapSnapshotModel.HeapSnapshotModel.HeapSnapshotProgressEvent.Update !== eventName) {
|
|
1746
1740
|
return;
|
|
1747
1741
|
}
|
|
1748
|
-
const
|
|
1749
|
-
const messageObject = i18n.i18n.deserializeUIString(serializedMessage);
|
|
1742
|
+
const messageObject = i18n.i18n.deserializeUIString(data);
|
|
1750
1743
|
// We know all strings from the worker are declared inside a single file so we can
|
|
1751
1744
|
// use a custom function.
|
|
1752
1745
|
this.updateStatus(moduleI18nString(messageObject.string, messageObject.values));
|
|
@@ -499,7 +499,10 @@ export class ProfileTypeSidebarSection extends UI.TreeOutline.TreeElement {
|
|
|
499
499
|
const profileTitle = profile.title;
|
|
500
500
|
let group: ProfileGroup = this.profileGroups[profileTitle];
|
|
501
501
|
if (!group) {
|
|
502
|
-
group =
|
|
502
|
+
group = {
|
|
503
|
+
profileSidebarTreeElements: [],
|
|
504
|
+
sidebarTreeElement: null,
|
|
505
|
+
};
|
|
503
506
|
this.profileGroups[profileTitle] = group;
|
|
504
507
|
}
|
|
505
508
|
group.profileSidebarTreeElements.push(profileTreeElement);
|
|
@@ -604,19 +607,14 @@ export class ProfileTypeSidebarSection extends UI.TreeOutline.TreeElement {
|
|
|
604
607
|
}
|
|
605
608
|
}
|
|
606
609
|
|
|
607
|
-
export
|
|
610
|
+
export interface ProfileGroup {
|
|
608
611
|
profileSidebarTreeElements: ProfileSidebarTreeElement[];
|
|
609
612
|
sidebarTreeElement: ProfileGroupSidebarTreeElement|null;
|
|
610
|
-
constructor() {
|
|
611
|
-
this.profileSidebarTreeElements = [];
|
|
612
|
-
this.sidebarTreeElement = null;
|
|
613
|
-
}
|
|
614
613
|
}
|
|
615
614
|
|
|
616
615
|
export class ProfileGroupSidebarTreeElement extends UI.TreeOutline.TreeElement {
|
|
617
616
|
readonly dataDisplayDelegate: DataDisplayDelegate;
|
|
618
617
|
profileTitle: string;
|
|
619
|
-
override toggleOnClick: boolean;
|
|
620
618
|
|
|
621
619
|
constructor(dataDisplayDelegate: DataDisplayDelegate, title: string) {
|
|
622
620
|
super('', true);
|
|
@@ -203,7 +203,6 @@ export class SensorsView extends UI.Widget.VBox {
|
|
|
203
203
|
private betaElement!: HTMLInputElement;
|
|
204
204
|
private gammaElement!: HTMLInputElement;
|
|
205
205
|
private orientationLayer!: HTMLDivElement;
|
|
206
|
-
private boxElement?: HTMLElement;
|
|
207
206
|
private boxMatrix?: DOMMatrix;
|
|
208
207
|
private mouseDownVector?: Geometry.Vector|null;
|
|
209
208
|
private originalBoxMatrix?: DOMMatrix;
|
|
@@ -731,7 +730,6 @@ export class SensorsView extends UI.Widget.VBox {
|
|
|
731
730
|
<div class="orientation-layer" ${Directives.ref((el: Element | undefined) => { if (el) { this.orientationLayer = el as HTMLDivElement; } })}>
|
|
732
731
|
<section
|
|
733
732
|
class="orientation-box orientation-element"
|
|
734
|
-
${Directives.ref((el: Element | undefined) => { if (el) { this.boxElement = el as HTMLElement; } })}
|
|
735
733
|
>
|
|
736
734
|
<section class="orientation-front orientation-element"></section>
|
|
737
735
|
<section class="orientation-top orientation-element"></section>
|
|
@@ -54,7 +54,6 @@ import * as TraceBounds from '../../services/trace_bounds/trace_bounds.js';
|
|
|
54
54
|
import * as Tracing from '../../services/tracing/tracing.js';
|
|
55
55
|
import * as Adorners from '../../ui/components/adorners/adorners.js';
|
|
56
56
|
import * as Dialogs from '../../ui/components/dialogs/dialogs.js';
|
|
57
|
-
import * as LegacyWrapper from '../../ui/components/legacy_wrapper/legacy_wrapper.js';
|
|
58
57
|
import * as Snackbars from '../../ui/components/snackbars/snackbars.js';
|
|
59
58
|
import {Link} from '../../ui/kit/kit.js';
|
|
60
59
|
import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|
|
@@ -2463,8 +2462,7 @@ export class TimelinePanel extends Common.ObjectWrapper.eventMixin<EventTypes, t
|
|
|
2463
2462
|
return;
|
|
2464
2463
|
}
|
|
2465
2464
|
|
|
2466
|
-
|
|
2467
|
-
this.landingPage = LegacyWrapper.LegacyWrapper.legacyWrapper(UI.Widget.Widget, liveMetrics);
|
|
2465
|
+
this.landingPage = new TimelineComponents.LiveMetricsView.LiveMetricsView();
|
|
2468
2466
|
this.landingPage.element.classList.add('timeline-landing-page', 'fill');
|
|
2469
2467
|
this.landingPage.contentElement.classList.add('fill');
|
|
2470
2468
|
this.landingPage.show(this.statusPaneContainer);
|