Skip to content

Commit a7f67b6

Browse files
Adriana IxbaDevtools-frontend LUCI CQ
authored andcommitted
[RPP] Add source and origin links to profile and function calls
https://screenshot.googleplex.com/5jeio3foDRbzcGz Bug:368541957 Change-Id: I21868eb191108b85eb16c0d02157f945d24f0d3d Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6236790 Reviewed-by: Paul Irish <[email protected]> Commit-Queue: Adriana Ixba <[email protected]> Auto-Submit: Adriana Ixba <[email protected]>
1 parent 592a86d commit a7f67b6

File tree

4 files changed

+124
-22
lines changed

4 files changed

+124
-22
lines changed

front_end/models/trace/helpers/Trace.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,13 @@ export function getZeroIndexedLineAndColumnForEvent(event: Types.Events.Event):
398398
columnNumber: typeof columnNumber === 'number' ? columnNumber - 1 : undefined,
399399
};
400400
}
401+
case Types.Events.Name.PROFILE_CALL: {
402+
const callFrame = (event as Types.Events.SyntheticProfileCall).callFrame;
403+
return {
404+
lineNumber: typeof lineNumber === 'number' ? callFrame.lineNumber - 1 : undefined,
405+
columnNumber: typeof columnNumber === 'number' ? callFrame.columnNumber - 1 : undefined,
406+
};
407+
}
401408
default: {
402409
return numbers;
403410
}

front_end/panels/timeline/TimelineUIUtils.test.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ describeWithMockConnection('TimelineUIUtils', function() {
122122
if (!node) {
123123
throw new Error('Node was unexpectedly null');
124124
}
125-
assert.strictEqual(node.textContent, 'test @ google.com/test.js:1:1');
125+
// URL path
126+
assert.strictEqual(node.textContent, 'test @ /test.js:1:1');
126127
});
127128

128129
it('makes the script location of a call frame a script name when the inspected target is the one the call frame was taken from',
@@ -757,8 +758,8 @@ describeWithMockConnection('TimelineUIUtils', function() {
757758
{title: 'Duration', value: '0.98\xA0ms (self 34\xA0μs)'},
758759
{
759760
title: 'Script',
760-
// URL plus line/col number
761-
value: 'chrome-extension://blijaeebfebmkmekmdnehcmmcjnblkeo/lib/utils.js:1:1',
761+
// URL path plus line/col number
762+
value: '/lib/utils.js:1:1',
762763
},
763764
{
764765
title: 'Streamed',
@@ -1316,10 +1317,10 @@ describeWithMockConnection('TimelineUIUtils', function() {
13161317
entityMapper,
13171318
);
13181319

1319-
const rowData = getRowDataForDetailsElement(details).find(row => row.title?.startsWith('3rd'));
1320+
const rowData = getRowDataForDetailsElement(details).find(row => row.title?.startsWith('Origin'));
13201321
assert.deepEqual(rowData, {
1321-
title: '3rd party',
1322-
value: 'Google Analytics',
1322+
title: 'Origin',
1323+
value: 'www.google-analytics.com (Google Analytics)',
13231324
});
13241325
});
13251326

front_end/panels/timeline/TimelineUIUtils.ts

Lines changed: 98 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -503,14 +503,18 @@ const UIStrings = {
503503
* @description Label for a string that describes the priority at which a task was scheduled, like 'background' for low-priority tasks, and 'user-blocking' for high priority.
504504
*/
505505
priority: 'Priority',
506-
/**
507-
* @description Text to refer to a 3rd Party entity.
508-
*/
509-
entity: '3rd party',
510506
/**
511507
* @description Label for third party table.
512508
*/
513509
thirdPartyTable: '1st / 3rd party table',
510+
/**
511+
* @description Label for the a source URL.
512+
*/
513+
source: 'Source',
514+
/**
515+
* @description Label for a URL origin.
516+
*/
517+
origin: 'Origin',
514518
};
515519
const str_ = i18n.i18n.registerUIStrings('panels/timeline/TimelineUIUtils.ts', UIStrings);
516520
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -527,6 +531,7 @@ interface LinkifyLocationOptions {
527531
linkifier: LegacyComponents.Linkifier.Linkifier;
528532
isFreshRecording?: boolean;
529533
columnNumber?: number;
534+
omitOrigin?: boolean;
530535
}
531536

532537
interface TimeRangeCategoryStats {
@@ -882,6 +887,7 @@ export class TimelineUIUtils {
882887
target,
883888
isFreshRecording,
884889
linkifier,
890+
omitOrigin: true,
885891
});
886892
if (location) {
887893
UI.UIUtils.createTextChild(details, ' @ ');
@@ -918,6 +924,7 @@ export class TimelineUIUtils {
918924
target,
919925
isFreshRecording,
920926
linkifier,
927+
omitOrigin: true,
921928
});
922929
}
923930
break;
@@ -927,8 +934,16 @@ export class TimelineUIUtils {
927934
case Trace.Types.Events.Name.STREAMING_COMPILE_SCRIPT: {
928935
const url = unsafeEventData['url'];
929936
if (url) {
930-
details = this.linkifyLocation(
931-
{scriptId: null, url, lineNumber: 0, columnNumber: 0, target, isFreshRecording, linkifier});
937+
details = this.linkifyLocation({
938+
scriptId: null,
939+
url,
940+
lineNumber: 0,
941+
columnNumber: 0,
942+
target,
943+
isFreshRecording,
944+
linkifier,
945+
omitOrigin: true,
946+
});
932947
}
933948
break;
934949
}
@@ -956,14 +971,15 @@ export class TimelineUIUtils {
956971
}
957972

958973
static linkifyLocation(linkifyOptions: LinkifyLocationOptions): Element|null {
959-
const {scriptId, url, lineNumber, columnNumber, isFreshRecording, linkifier, target} = linkifyOptions;
974+
const {scriptId, url, lineNumber, columnNumber, isFreshRecording, linkifier, target, omitOrigin} = linkifyOptions;
960975
const options = {
961976
lineNumber,
962977
columnNumber,
963978
showColumnNumber: true,
964979
inlineFrameIndex: 0,
965980
className: 'timeline-details',
966981
tabStop: true,
982+
omitOrigin,
967983
};
968984
if (isFreshRecording) {
969985
return linkifier.linkifyScriptLocation(
@@ -1058,6 +1074,7 @@ export class TimelineUIUtils {
10581074
parsedTrace,
10591075
event,
10601076
);
1077+
let entityAppended = false;
10611078

10621079
if (maybeTarget) {
10631080
// @ts-expect-error TODO(crbug.com/1011811): Remove symbol usage.
@@ -1141,7 +1158,13 @@ export class TimelineUIUtils {
11411158
url = event.args.data?.url as Platform.DevToolsPath.UrlString;
11421159
if (url) {
11431160
const {lineNumber, columnNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
1144-
contentHelper.appendLocationRow(i18nString(UIStrings.script), url, lineNumber || 0, columnNumber);
1161+
contentHelper.appendLocationRow(
1162+
i18nString(UIStrings.script), url, lineNumber || 0, columnNumber, undefined, true);
1163+
const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
1164+
if (originWithEntity) {
1165+
contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
1166+
}
1167+
entityAppended = true;
11451168
}
11461169
const isEager = Boolean(event.args.data?.eager);
11471170
if (isEager) {
@@ -1178,12 +1201,34 @@ export class TimelineUIUtils {
11781201
break;
11791202
}
11801203

1181-
case Trace.Types.Events.Name.PROFILE_CALL:
1204+
case Trace.Types.Events.Name.PROFILE_CALL: {
1205+
const profileCall = event as Trace.Types.Events.SyntheticProfileCall;
1206+
const resolvedURL = Utils.SourceMapsResolver.SourceMapsResolver.resolvedURLForEntry(parsedTrace, profileCall);
1207+
if (!resolvedURL) {
1208+
break;
1209+
}
1210+
const callFrame = profileCall.callFrame;
1211+
// Render the URL with its location content.
1212+
contentHelper.appendLocationRow(
1213+
i18nString(UIStrings.source), resolvedURL, callFrame.lineNumber || 0, callFrame.columnNumber, undefined,
1214+
true);
1215+
const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, profileCall);
1216+
if (originWithEntity) {
1217+
contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
1218+
}
1219+
entityAppended = true;
1220+
break;
1221+
}
11821222
case Trace.Types.Events.Name.FUNCTION_CALL: {
11831223
const detailsNode = await TimelineUIUtils.buildDetailsNodeForTraceEvent(
11841224
event, targetForEvent(parsedTrace, event), linkifier, isFreshRecording, parsedTrace);
11851225
if (detailsNode) {
11861226
contentHelper.appendElementRow(i18nString(UIStrings.function), detailsNode);
1227+
const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
1228+
if (originWithEntity) {
1229+
contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
1230+
}
1231+
entityAppended = true;
11871232
}
11881233
break;
11891234
}
@@ -1235,7 +1280,13 @@ export class TimelineUIUtils {
12351280
url = unsafeEventData && unsafeEventData['url'] as Platform.DevToolsPath.UrlString;
12361281
if (url) {
12371282
const {lineNumber, columnNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
1238-
contentHelper.appendLocationRow(i18nString(UIStrings.script), url, lineNumber || 0, columnNumber);
1283+
contentHelper.appendLocationRow(
1284+
i18nString(UIStrings.script), url, lineNumber || 0, columnNumber, undefined, true);
1285+
const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
1286+
if (originWithEntity) {
1287+
contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
1288+
}
1289+
entityAppended = true;
12391290
}
12401291
contentHelper.appendTextRow(
12411292
i18nString(UIStrings.compilationCacheSize),
@@ -1247,7 +1298,13 @@ export class TimelineUIUtils {
12471298
url = unsafeEventData && unsafeEventData['url'] as Platform.DevToolsPath.UrlString;
12481299
if (url) {
12491300
const {lineNumber, columnNumber} = Trace.Helpers.Trace.getZeroIndexedLineAndColumnForEvent(event);
1250-
contentHelper.appendLocationRow(i18nString(UIStrings.script), url, lineNumber || 0, columnNumber);
1301+
contentHelper.appendLocationRow(
1302+
i18nString(UIStrings.script), url, lineNumber || 0, columnNumber, undefined, true);
1303+
const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
1304+
if (originWithEntity) {
1305+
contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
1306+
}
1307+
entityAppended = true;
12511308
}
12521309
break;
12531310
}
@@ -1571,10 +1628,11 @@ export class TimelineUIUtils {
15711628
contentHelper.appendElementRow('', event[previewElementSymbol]);
15721629
}
15731630

1574-
// Third party entity
1575-
const entity = entityMapper?.entityForEvent(event);
1576-
if (entity) {
1577-
contentHelper.appendTextRow(i18nString(UIStrings.entity), entity.name);
1631+
if (!entityAppended) {
1632+
const originWithEntity = this.getOriginWithEntity(entityMapper, parsedTrace, event);
1633+
if (originWithEntity) {
1634+
contentHelper.appendElementRow(i18nString(UIStrings.origin), originWithEntity);
1635+
}
15781636
}
15791637

15801638
const stackTrace = Trace.Helpers.Trace.getZeroIndexedStackTraceForEvent(event);
@@ -2362,6 +2420,27 @@ export class TimelineUIUtils {
23622420
return Common.ParsedURL.schemeIs(url, 'about:') ? `"${Platform.StringUtilities.trimMiddle(frame.name, trimAt)}"` :
23632421
frame.url.slice(0, trimAt);
23642422
}
2423+
2424+
static getOriginWithEntity(
2425+
entityMapper: Utils.EntityMapper.EntityMapper|null, parsedTrace: Trace.Handlers.Types.ParsedTrace,
2426+
event: Trace.Types.Events.Event): string|null {
2427+
const resolvedURL = Utils.SourceMapsResolver.SourceMapsResolver.resolvedURLForEntry(parsedTrace, event);
2428+
if (!resolvedURL) {
2429+
return null;
2430+
}
2431+
const parsedUrl = URL.parse(resolvedURL);
2432+
if (!parsedUrl) {
2433+
return null;
2434+
}
2435+
2436+
const entity = entityMapper?.entityForEvent(event) ?? null;
2437+
if (!entity) {
2438+
return null;
2439+
}
2440+
2441+
const originWithEntity = Utils.Helpers.formatOriginWithEntity(parsedUrl, entity, true);
2442+
return originWithEntity;
2443+
}
23652444
}
23662445

23672446
export const aggregatedStatsKey = Symbol('aggregatedStats');
@@ -2449,7 +2528,8 @@ export class TimelineDetailsContentHelper {
24492528
}
24502529
}
24512530

2452-
appendLocationRow(title: string, url: string, startLine: number, startColumn?: number): void {
2531+
appendLocationRow(
2532+
title: string, url: string, startLine: number, startColumn?: number, text?: string, omitOrigin?: boolean): void {
24532533
if (!this.linkifierInternal) {
24542534
return;
24552535
}
@@ -2459,6 +2539,8 @@ export class TimelineDetailsContentHelper {
24592539
columnNumber: startColumn,
24602540
showColumnNumber: true,
24612541
inlineFrameIndex: 0,
2542+
text,
2543+
omitOrigin,
24622544
};
24632545
const link = this.linkifierInternal.maybeLinkifyScriptLocation(
24642546
this.target, null, url as Platform.DevToolsPath.UrlString, startLine, options);

front_end/ui/legacy/components/utils/Linkifier.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
239239
inlineFrameIndex: options?.inlineFrameIndex ?? 0,
240240
userMetric: options?.userMetric,
241241
jslogContext: options?.jslogContext || 'script-location',
242+
omitOrigin: options?.omitOrigin,
242243
};
243244
const {columnNumber, className = ''} = linkifyURLOptions;
244245
if (sourceURL) {
@@ -528,6 +529,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
528529
const preventClick = options.preventClick;
529530
const maxLength = options.maxLength || UI.UIUtils.MaxLengthForDisplayedURLs;
530531
const bypassURLTrimming = options.bypassURLTrimming;
532+
const omitOrigin = options.omitOrigin;
531533
if (!url || Common.ParsedURL.schemeIs(url, 'javascript:')) {
532534
const element = document.createElement('span');
533535
if (className) {
@@ -539,6 +541,14 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
539541
}
540542

541543
let linkText = text || Bindings.ResourceUtils.displayNameForURL(url);
544+
545+
if (omitOrigin) {
546+
const parsedUrl = URL.parse(url);
547+
if (parsedUrl) {
548+
linkText = url.replace(parsedUrl.origin, '');
549+
}
550+
}
551+
542552
if (typeof lineNumber === 'number' && !text) {
543553
linkText += ':' + (lineNumber + 1);
544554
if (showColumnNumber && typeof columnNumber === 'number') {
@@ -1018,6 +1028,7 @@ export interface LinkifyURLOptions {
10181028
bypassURLTrimming?: boolean;
10191029
userMetric?: Host.UserMetrics.Action;
10201030
jslogContext?: string;
1031+
omitOrigin?: boolean;
10211032
}
10221033

10231034
export interface LinkifyOptions {
@@ -1028,6 +1039,7 @@ export interface LinkifyOptions {
10281039
tabStop?: boolean;
10291040
userMetric?: Host.UserMetrics.Action;
10301041
jslogContext?: string;
1042+
omitOrigin?: boolean;
10311043

10321044
/**
10331045
* {@link LinkDisplayOptions.revealBreakpoint}

0 commit comments

Comments
 (0)