Skip to content

Commit 3e6c7f0

Browse files
Adriana IxbaDevtools-frontend LUCI CQ
authored andcommitted
[RPP] Hover/click on 3P table and 3P grouped AggregatedTimelineTreeView
includes `SyntheticNetworkRequests` Because tree views only consider events on the Main thread, we need to make an exception for when considering 3P (as this includes network requests). So on hover/click we should include network requests for completion using the entity mapper. https://screencast.googleplex.com/cast/NjIyNjk4NzE1OTkxMjQ0OHxjYzJhYjc2MS05Nw Bug: 394651390 Change-Id: I5d127a6dce58bd54a7fbbfeabd4401753b8f3bf8 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6374483 Commit-Queue: Adriana Ixba <aixba@chromium.org> Reviewed-by: Paul Irish <paulirish@chromium.org>
1 parent 86849c0 commit 3e6c7f0

4 files changed

Lines changed: 94 additions & 14 deletions

File tree

front_end/panels/timeline/ThirdPartyTreeView.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,40 @@ export class ThirdPartyTreeViewWidget extends TimelineTreeView.TimelineTreeView
173173
}
174174
}
175175

176+
override onHover(node: Trace.Extras.TraceTree.Node|null): void {
177+
if (!node) {
178+
this.dispatchEventToListeners(TimelineTreeView.TimelineTreeView.Events.TREE_ROW_HOVERED, {node: null});
179+
return;
180+
}
181+
this.#getEventsForEventDispatch(node);
182+
const events = this.#getEventsForEventDispatch(node);
183+
this.dispatchEventToListeners(
184+
TimelineTreeView.TimelineTreeView.Events.TREE_ROW_HOVERED,
185+
{node, events: events && events.length > 0 ? events : undefined});
186+
}
187+
188+
override onClick(node: Trace.Extras.TraceTree.Node|null): void {
189+
if (!node) {
190+
this.dispatchEventToListeners(TimelineTreeView.TimelineTreeView.Events.TREE_ROW_CLICKED, {node: null});
191+
return;
192+
}
193+
const events = this.#getEventsForEventDispatch(node);
194+
this.dispatchEventToListeners(
195+
TimelineTreeView.TimelineTreeView.Events.TREE_ROW_CLICKED,
196+
{node, events: events && events.length > 0 ? events : undefined});
197+
}
198+
199+
// For ThirdPartyTree, we should include everything in our entity mapper for full coverage.
200+
#getEventsForEventDispatch(node: Trace.Extras.TraceTree.Node): Trace.Types.Events.Event[]|null {
201+
const mapper = this.entityMapper();
202+
if (!mapper) {
203+
return null;
204+
}
205+
206+
const entity = mapper.entityForEvent(node.event);
207+
return entity ? mapper.eventsForEntity(entity) ?? [] : [];
208+
}
209+
176210
displayInfoForGroupNode(node: Trace.Extras.TraceTree.Node): {
177211
name: string,
178212
color: string,

front_end/panels/timeline/TimelineDetailsView.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,22 @@ export class TimelineDetailsPane extends
145145
if (view instanceof AggregatedTimelineTreeView) {
146146
view.stackView.addEventListener(
147147
TimelineStackView.Events.TREE_ROW_HOVERED,
148-
node => this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, node.data));
148+
node => this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, {node: node.data}));
149149
}
150150
});
151151
this.#thirdPartyTree.addEventListener(TimelineTreeView.Events.TREE_ROW_HOVERED, node => {
152152
// Re-dispatch through 3P event to get 3P dimmer.
153-
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, node.data);
153+
this.dispatchEventToListeners(
154+
TimelineTreeView.Events.TREE_ROW_HOVERED, {node: node.data.node, events: node.data.events ?? undefined});
154155
});
155156

156157
this.#thirdPartyTree.addEventListener(TimelineTreeView.Events.BOTTOM_UP_BUTTON_CLICKED, node => {
157158
this.selectTab(Tab.BottomUp, node.data, AggregatedTimelineTreeView.GroupBy.ThirdParties);
158159
});
159160
this.#thirdPartyTree.addEventListener(TimelineTreeView.Events.TREE_ROW_CLICKED, node => {
160161
// Re-dispatch through 3P event to get 3P dimmer.
161-
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_CLICKED, node.data);
162+
this.dispatchEventToListeners(
163+
TimelineTreeView.Events.TREE_ROW_CLICKED, {node: node.data.node, events: node.data.events ?? undefined});
162164
});
163165

164166
this.#networkRequestDetails =

front_end/panels/timeline/TimelineFlameChartView.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,17 +374,25 @@ export class TimelineFlameChartView extends Common.ObjectWrapper.eventMixin<Even
374374
this.#overlays.toggleAllOverlaysDisplayed(!event.data);
375375
});
376376

377-
this.detailsView.addEventListener(TimelineTreeView.Events.TREE_ROW_HOVERED, node => {
377+
this.detailsView.addEventListener(TimelineTreeView.Events.TREE_ROW_HOVERED, e => {
378378
if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.TIMELINE_DIM_UNRELATED_EVENTS)) {
379379
return;
380380
}
381381

382-
const events = node?.data?.events ?? null;
382+
if (e.data.events) {
383+
this.#updateFlameChartDimmerWithEvents(this.#treeRowHoverDimmer, e.data.events);
384+
return;
385+
}
386+
const events = e?.data?.node?.events ?? null;
383387
this.#updateFlameChartDimmerWithEvents(this.#treeRowHoverDimmer, events);
384388
});
385389

386-
this.detailsView.addEventListener(TimelineTreeView.Events.TREE_ROW_CLICKED, node => {
387-
const events = node?.data?.events ?? null;
390+
this.detailsView.addEventListener(TimelineTreeView.Events.TREE_ROW_CLICKED, e => {
391+
if (e.data.events) {
392+
this.#updateFlameChartDimmerWithEvents(this.#treeRowClickDimmer, e.data.events);
393+
return;
394+
}
395+
const events = e?.data?.node?.events ?? null;
388396
this.#updateFlameChartDimmerWithEvents(this.#treeRowClickDimmer, events);
389397
});
390398

front_end/panels/timeline/TimelineTreeView.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export class TimelineTreeView extends
266266
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SORTING_CHANGED, this.sortingChanged, this);
267267
this.dataGrid.element.addEventListener('mousemove', this.onMouseMove.bind(this), true);
268268
this.dataGrid.element.addEventListener(
269-
'mouseleave', () => this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, null));
269+
'mouseleave', () => this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, {node: null}));
270270
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.OPENED_NODE, this.onGridNodeOpened, this);
271271
this.dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.LAST);
272272
this.dataGrid.setRowContextMenuCallback(this.onContextMenu.bind(this));
@@ -585,7 +585,11 @@ export class TimelineTreeView extends
585585
}
586586

587587
onHover(node: Trace.Extras.TraceTree.Node|null): void {
588-
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, node);
588+
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, {node});
589+
}
590+
591+
onClick(node: Trace.Extras.TraceTree.Node|null): void {
592+
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_CLICKED, {node});
589593
}
590594

591595
override wasShown(): void {
@@ -603,13 +607,14 @@ export class TimelineTreeView extends
603607
*/
604608
#onDataGridSelectionChange(event: Common.EventTarget.EventTargetEvent<DataGrid.DataGrid.DataGridNode<GridNode>>):
605609
void {
606-
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_CLICKED, (event.data as GridNode).profileNode);
610+
this.onClick((event.data as GridNode).profileNode);
607611
this.onHover((event.data as GridNode).profileNode);
608612
}
609613

610614
onGridNodeOpened(): void {
611615
const gridNode = this.dataGrid.selectedNode as TreeGridNode;
612-
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, gridNode.profileNode);
616+
// Use tree's hover method in case of unique hover experiences (like ThirdPartyTree).
617+
this.onHover(gridNode.profileNode);
613618
this.updateDetailsForSelection();
614619
}
615620

@@ -689,9 +694,9 @@ export namespace TimelineTreeView {
689694
}
690695

691696
export interface EventTypes {
692-
[Events.TREE_ROW_HOVERED]: Trace.Extras.TraceTree.Node|null;
697+
[Events.TREE_ROW_HOVERED]: {node: Trace.Extras.TraceTree.Node|null, events?: Trace.Types.Events.Event[]};
693698
[Events.BOTTOM_UP_BUTTON_CLICKED]: Trace.Extras.TraceTree.Node|null;
694-
[Events.TREE_ROW_CLICKED]: Trace.Extras.TraceTree.Node|null;
699+
[Events.TREE_ROW_CLICKED]: {node: Trace.Extras.TraceTree.Node|null, events?: Trace.Types.Events.Event[]};
695700
}
696701
}
697702

@@ -866,7 +871,7 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
866871
#bottomUpButtonClicked(): void {
867872
// We should also trigger an event to "unhover" the 3P tree row. Since this isn't
868873
// triggered when clicking the bottom up button.
869-
this.treeView.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, null);
874+
this.treeView.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, {node: null});
870875
this.treeView.dispatchEventToListeners(TimelineTreeView.Events.BOTTOM_UP_BUTTON_CLICKED, this.profileNode);
871876
}
872877
}
@@ -1147,6 +1152,37 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
11471152

11481153
private static readonly extensionInternalPrefix = 'extensions::';
11491154
private static readonly v8NativePrefix = 'native ';
1155+
1156+
override onHover(node: Trace.Extras.TraceTree.Node|null): void {
1157+
if (node !== null && this.groupBySetting.get() === AggregatedTimelineTreeView.GroupBy.ThirdParties) {
1158+
const events = this.#getThirdPartyEventsForNode(node);
1159+
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, {node, events});
1160+
return;
1161+
}
1162+
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_HOVERED, {node});
1163+
}
1164+
1165+
override onClick(node: Trace.Extras.TraceTree.Node|null): void {
1166+
if (node !== null && this.groupBySetting.get() === AggregatedTimelineTreeView.GroupBy.ThirdParties) {
1167+
const events = this.#getThirdPartyEventsForNode(node);
1168+
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_CLICKED, {node, events});
1169+
return;
1170+
}
1171+
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_CLICKED, {node});
1172+
}
1173+
1174+
#getThirdPartyEventsForNode(node: Trace.Extras.TraceTree.Node): Trace.Types.Events.Event[]|undefined {
1175+
if (!node.event) {
1176+
return;
1177+
}
1178+
const entity = this.entityMapper()?.entityForEvent(node.event);
1179+
// Should be [unattributed]. Just use the node's events.
1180+
if (!entity) {
1181+
return node.events;
1182+
}
1183+
const events = this.entityMapper()?.eventsForEntity(entity);
1184+
return events;
1185+
}
11501186
}
11511187
export namespace AggregatedTimelineTreeView {
11521188
export enum GroupBy {

0 commit comments

Comments
 (0)