Skip to content

Commit feabf29

Browse files
paulirishDevtools-frontend LUCI CQ
authored andcommitted
RPP: Put URL into flamechart popover if appropriate
To speed up identification/attribution of JS functions in particular. Also normalize naming on 'popover', reducing usage of "highlightedEntryInfo". Bug:368541957 Change-Id: I8379d4764512c2eaf5e76fb4c88b7e0a90cb46ec Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6007341 Reviewed-by: Connor Clark <[email protected]> Auto-Submit: Paul Irish <[email protected]> Commit-Queue: Connor Clark <[email protected]>
1 parent a2674c0 commit feabf29

27 files changed

+236
-271
lines changed

front_end/models/trace/extras/URLForEntry.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import type * as Handlers from '../handlers/handlers.js';
77
import * as Types from '../types/types.js';
88

99
/**
10-
* Use this helper whenever resolving an URL's source mapping is not an
11-
* option. For example when processing non-ui data. Otherwise use the
12-
* helper SourceMapsResolver::resolvedURLForEntry
10+
* INSTEAD, you probably want `SourceMapsResolver.resolvedURLForEntry()`!
11+
* If an URL will be displayed in the UI, it's likely you should NOT use `getNonResolved`.
1312
*
14-
* If an URL will be displayed in the UI, it's likely you should not use
15-
* this helper and prefer the other option instead.
13+
* Use `getNonResolved` method whenever resolving an URL's source mapping is not an
14+
* option. For example when processing non-ui data.
15+
*
16+
* TODO: migrate existing uses of this over to resolvedURLForEntry.
1617
*/
1718

1819
export function getNonResolved(

front_end/panels/media/TickingFlameChart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ class TickingFlameChartDataProvider implements PerfUI.FlameChart.FlameChartDataP
493493
return false;
494494
}
495495

496-
prepareHighlightedEntryInfo(index: number): Element|null {
496+
preparePopoverElement(index: number): Element|null {
497497
const element = document.createElement('div');
498498
(this.eventMap.get(index) as Event).decorate(element);
499499
return element;

front_end/panels/profiler/HeapProfileView.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -675,28 +675,28 @@ export class HeapFlameChartDataProvider extends ProfileFlameChartDataProvider {
675675
return this.timelineDataInternal;
676676
}
677677

678-
override prepareHighlightedEntryInfo(entryIndex: number): Element|null {
678+
override preparePopoverElement(entryIndex: number): Element|null {
679679
const node = this.entryNodes[entryIndex];
680680
if (!node) {
681681
return null;
682682
}
683-
const entryInfo: {
683+
const popoverInfo: {
684684
title: string,
685685
value: string,
686686
}[] = [];
687-
function pushEntryInfoRow(title: string, value: string): void {
688-
entryInfo.push({title, value});
687+
function pushRow(title: string, value: string): void {
688+
popoverInfo.push({title, value});
689689
}
690-
pushEntryInfoRow(i18nString(UIStrings.name), UI.UIUtils.beautifyFunctionName(node.functionName));
691-
pushEntryInfoRow(i18nString(UIStrings.selfSize), i18n.ByteUtilities.bytesToString(node.self));
692-
pushEntryInfoRow(i18nString(UIStrings.totalSize), i18n.ByteUtilities.bytesToString(node.total));
690+
pushRow(i18nString(UIStrings.name), UI.UIUtils.beautifyFunctionName(node.functionName));
691+
pushRow(i18nString(UIStrings.selfSize), i18n.ByteUtilities.bytesToString(node.self));
692+
pushRow(i18nString(UIStrings.totalSize), i18n.ByteUtilities.bytesToString(node.total));
693693
const linkifier = new Components.Linkifier.Linkifier();
694694
const link = linkifier.maybeLinkifyConsoleCallFrame(
695695
this.heapProfilerModel ? this.heapProfilerModel.target() : null, node.callFrame);
696696
if (link) {
697-
pushEntryInfoRow(i18nString(UIStrings.url), (link.textContent as string));
697+
pushRow(i18nString(UIStrings.url), (link.textContent as string));
698698
}
699699
linkifier.dispose();
700-
return ProfileView.buildPopoverTable(entryInfo);
700+
return ProfileView.buildPopoverTable(popoverInfo);
701701
}
702702
}

front_end/panels/profiler/ProfileFlameChartDataProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class ProfileFlameChartDataProvider implements PerfUI.FlameChart.FlameCha
9393
throw 'Not implemented.';
9494
}
9595

96-
prepareHighlightedEntryInfo(_entryIndex: number): Element|null {
96+
preparePopoverElement(_entryIndex: number): Element|null {
9797
throw 'Not implemented.';
9898
}
9999

front_end/panels/profiler/ProfileView.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,12 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
223223
this.linkifierInternal = new Components.Linkifier.Linkifier(maxLinkLength);
224224
}
225225

226-
static buildPopoverTable(entryInfo: {
226+
static buildPopoverTable(popoverInfo: {
227227
title: string,
228228
value: string,
229229
}[]): Element {
230230
const table = document.createElement('table');
231-
for (const entry of entryInfo) {
231+
for (const entry of popoverInfo) {
232232
const row = table.createChild('tr');
233233
row.createChild('td').textContent = entry.title;
234234
row.createChild('td').textContent = entry.value;

front_end/panels/timeline/AnimationsTrackAppender.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import * as Trace from '../../models/trace/trace.js';
77
import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
88
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
99

10-
import {addDecorationToEvent, buildGroupStyle, buildTrackHeader, getFormattedTime} from './AppenderUtils.js';
10+
import {addDecorationToEvent, buildGroupStyle, buildTrackHeader} from './AppenderUtils.js';
1111
import {
1212
type CompatibilityTracksAppender,
13-
type HighlightedEntryInfo,
1413
type TrackAppender,
1514
type TrackAppenderName,
1615
VisualLoggingTrackName,
@@ -75,9 +74,4 @@ export class AnimationsTrackAppender implements TrackAppender {
7574
const {displayName} = event.args.data.beginEvent.args.data;
7675
return displayName || event.name;
7776
}
78-
79-
highlightedEntryInfo(event: Trace.Types.Events.SyntheticAnimationPair): HighlightedEntryInfo {
80-
const title = this.titleForEvent(event);
81-
return {title, formattedTime: getFormattedTime(event.dur)};
82-
}
8377
}

front_end/panels/timeline/AppenderUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export function buildTrackHeader(
8181
* Returns the time info shown when an event is hovered in the timeline.
8282
* @param totalTime the total time of the hovered event.
8383
* @param selfTime the self time of the hovered event.
84-
* @returns the formatted time string for highlightedEntryInfo
84+
* @returns the formatted time string for popoverInfo
8585
*/
8686
export function getFormattedTime(
8787
totalTime?: Trace.Types.Timing.MicroSeconds, selfTime?: Trace.Types.Timing.MicroSeconds): string {

front_end/panels/timeline/CompatibilityTracksAppender.ts

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import * as Common from '../../core/common/common.js';
6+
import * as Platform from '../../core/platform/platform.js';
67
import * as Root from '../../core/root/root.js';
78
import * as Trace from '../../models/trace/trace.js';
89
import type * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
@@ -25,11 +26,12 @@ import {
2526
import {TimingsTrackAppender} from './TimingsTrackAppender.js';
2627
import * as TimelineUtils from './utils/utils.js';
2728

28-
export type HighlightedEntryInfo = {
29+
export type PopoverInfo = {
2930
title: string,
3031
formattedTime: string,
31-
warningElements?: HTMLSpanElement[],
32-
additionalElement?: HTMLElement,
32+
url: string|null,
33+
warningElements: HTMLSpanElement[],
34+
additionalElements: HTMLElement[],
3335
};
3436

3537
let showPostMessageEvents: boolean|undefined;
@@ -124,9 +126,9 @@ export interface TrackAppender {
124126
*/
125127
titleForEvent?(event: Trace.Types.Events.Event): string;
126128
/**
127-
* Returns the info shown when an event in the timeline is hovered.
129+
* Updates the standard popover (AKA tooltip) some appender specific details.
128130
*/
129-
highlightedEntryInfo?(event: Trace.Types.Events.Event): Partial<HighlightedEntryInfo>;
131+
setPopoverInfo?(event: Trace.Types.Events.Event, info: PopoverInfo): void;
130132
/**
131133
* Returns the a callback function to draw an event to overrides the normal rectangle draw operation.
132134
*/
@@ -645,47 +647,42 @@ export class CompatibilityTracksAppender {
645647
/**
646648
* Returns the info shown when an event in the timeline is hovered.
647649
*/
648-
highlightedEntryInfo(event: Trace.Types.Events.Event, level: number): HighlightedEntryInfo {
650+
popoverInfo(event: Trace.Types.Events.Event, level: number): PopoverInfo {
649651
const track = this.#trackForLevel.get(level);
650652
if (!track) {
651653
throw new Error('Track not found for level');
652654
}
653655

654-
// Add any warnings information to the tooltip. Done here to avoid duplicating this call in every appender.
655-
// By doing this here, we ensure that any warnings that are
656-
// added to the WarningsHandler are automatically used and added
657-
// to the tooltip.
658-
const warningElements: HTMLSpanElement[] =
659-
TimelineComponents.DetailsView.buildWarningElementsForEvent(event, this.#parsedTrace);
660-
661-
let title = this.titleForEvent(event, level);
662-
let formattedTime = getFormattedTime(event.dur);
663-
let additionalElement;
664-
665-
// If the track defines a custom highlight, call it and use its values.
666-
if (track.highlightedEntryInfo) {
667-
const {
668-
title: customTitle,
669-
formattedTime: customFormattedTime,
670-
warningElements: extraWarningElements,
671-
additionalElement: element,
672-
} = track.highlightedEntryInfo(event);
673-
if (customTitle) {
674-
title = customTitle;
675-
}
676-
if (customFormattedTime) {
677-
formattedTime = customFormattedTime;
678-
}
679-
if (extraWarningElements) {
680-
warningElements.push(...extraWarningElements);
681-
}
682-
additionalElement = element;
683-
}
684-
return {
685-
title,
686-
formattedTime,
687-
warningElements,
688-
additionalElement,
656+
// Defaults here, though tracks may chose to redefine title/formattedTime
657+
const info: PopoverInfo = {
658+
title: this.titleForEvent(event, level),
659+
formattedTime: getFormattedTime(event.dur),
660+
warningElements: TimelineComponents.DetailsView.buildWarningElementsForEvent(event, this.#parsedTrace),
661+
additionalElements: [],
662+
url: null,
689663
};
664+
665+
// If the track defines its own popoverInfo(), it'll update values within
666+
if (track.setPopoverInfo) {
667+
track.setPopoverInfo(event, info);
668+
}
669+
670+
// If there's a url associated, add into additionalElements
671+
const url = URL.parse(
672+
info.url ?? TimelineUtils.SourceMapsResolver.SourceMapsResolver.resolvedURLForEntry(this.#parsedTrace, event) ??
673+
'');
674+
if (url) {
675+
const MAX_PATH_LENGTH = 45;
676+
const MAX_ORIGIN_LENGTH = 30;
677+
const path = Platform.StringUtilities.trimMiddle(url.href.replace(url.origin, ''), MAX_PATH_LENGTH);
678+
const origin =
679+
Platform.StringUtilities.trimEndWithMaxLength(url.origin.replace('https://', ''), MAX_ORIGIN_LENGTH);
680+
const urlElems = document.createElement('div');
681+
urlElems.createChild('span', 'popoverinfo-url-path').textContent = path;
682+
urlElems.createChild('span', 'popoverinfo-url-origin').textContent = `(${origin})`;
683+
info.additionalElements.push(urlElems);
684+
}
685+
686+
return info;
690687
}
691688
}

front_end/panels/timeline/ExtensionTrackAppender.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import * as i18n from '../../core/i18n/i18n.js';
55
import * as Trace from '../../models/trace/trace.js';
66
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
77

8-
import {buildGroupStyle, buildTrackHeader, getFormattedTime} from './AppenderUtils.js';
8+
import {buildGroupStyle, buildTrackHeader} from './AppenderUtils.js';
99
import {
1010
type CompatibilityTracksAppender,
11-
type HighlightedEntryInfo,
1211
type TrackAppender,
1312
type TrackAppenderName,
1413
VisualLoggingTrackName,
@@ -100,17 +99,9 @@ export class ExtensionTrackAppender implements TrackAppender {
10099
}
101100

102101
titleForEvent(event: Trace.Types.Events.Event): string {
102+
if (Trace.Types.Extensions.isSyntheticExtensionEntry(event) && event.args.tooltipText) {
103+
return event.args.tooltipText;
104+
}
103105
return event.name;
104106
}
105-
106-
/**
107-
* Returns the info shown when an event added by this appender
108-
* is hovered in the timeline.
109-
*/
110-
highlightedEntryInfo(event: Trace.Types.Events.Event): HighlightedEntryInfo {
111-
const title = Trace.Types.Extensions.isSyntheticExtensionEntry(event) && event.args.tooltipText ?
112-
event.args.tooltipText :
113-
this.titleForEvent(event);
114-
return {title, formattedTime: getFormattedTime(event.dur)};
115-
}
116107
}

front_end/panels/timeline/InteractionsTrackAppender.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
99
import {buildGroupStyle, buildTrackHeader} from './AppenderUtils.js';
1010
import {
1111
type CompatibilityTracksAppender,
12-
type HighlightedEntryInfo,
12+
type PopoverInfo,
1313
type TrackAppender,
1414
type TrackAppenderName,
1515
VisualLoggingTrackName,
@@ -148,12 +148,11 @@ export class InteractionsTrackAppender implements TrackAppender {
148148
return this.#colorGenerator.colorForID(idForColorGeneration);
149149
}
150150

151-
highlightedEntryInfo(event: Trace.Types.Events.Event): HighlightedEntryInfo {
151+
setPopoverInfo(event: Trace.Types.Events.Event, info: PopoverInfo): void {
152152
if (Trace.Types.Events.isSyntheticInteraction(event)) {
153153
const breakdown = new Components.InteractionBreakdown.InteractionBreakdown();
154154
breakdown.entry = event;
155-
return {title: '', formattedTime: '', additionalElement: breakdown};
155+
info.additionalElements.push(breakdown);
156156
}
157-
return {title: '', formattedTime: ''};
158157
}
159158
}

0 commit comments

Comments
 (0)