chrome-devtools-frontend 1.0.1605219 → 1.0.1606789
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/Images/src/dots-circle.svg +10 -0
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/platform/api/HostRuntime.ts +9 -6
- package/front_end/core/platform/browser/HostRuntime.ts +2 -2
- package/front_end/core/platform/node/HostRuntime.ts +7 -7
- package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/CrashReportContextModel.ts +28 -0
- package/front_end/core/sdk/sdk.ts +2 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +3 -3
- package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.ts +5 -4
- package/front_end/entrypoints/main/MainImpl.ts +0 -101
- package/front_end/models/ai_assistance/ChangeManager.ts +6 -6
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +112 -5
- package/front_end/models/ai_assistance/agents/AiAgent.ts +9 -25
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -3
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +10 -9
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +313 -0
- package/front_end/models/ai_assistance/agents/FileAgent.ts +15 -1
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +15 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +19 -8
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +35 -278
- package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -5
- package/front_end/models/web_mcp/WebMCPModel.ts +187 -0
- package/front_end/models/web_mcp/web_mcp.ts +9 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -1
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +88 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +149 -49
- package/front_end/panels/ai_assistance/components/ChatView.ts +11 -15
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +13 -4
- package/front_end/panels/ai_assistance/components/chatMessage.css +53 -1
- package/front_end/panels/ai_assistance/components/chatView.css +0 -10
- package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +13 -0
- package/front_end/panels/application/WebMCPView.ts +471 -25
- package/front_end/panels/application/webMCPView.css +53 -2
- package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
- package/front_end/panels/elements/ElementsTreeOutline.ts +87 -0
- package/front_end/panels/elements/StylePropertiesSection.ts +0 -4
- package/front_end/panels/elements/elements.ts +3 -0
- package/front_end/panels/elements/elementsTreeOutline.css +21 -0
- package/front_end/panels/elements/stylePropertiesTreeOutline.css +7 -0
- package/front_end/panels/lighthouse/LighthousePanel.ts +7 -1
- package/front_end/panels/lighthouse/LighthouseProtocolService.ts +25 -2
- package/front_end/panels/profiler/HeapDetachedElementsView.ts +0 -4
- package/front_end/panels/profiler/HeapProfileView.ts +0 -4
- package/front_end/panels/profiler/HeapProfilerPanel.ts +4 -13
- package/front_end/panels/profiler/HeapSnapshotProxy.ts +2 -6
- package/front_end/panels/profiler/HeapSnapshotView.ts +19 -32
- package/front_end/panels/profiler/ProfileHeader.ts +1 -15
- package/front_end/panels/profiler/ProfileTypeRegistry.ts +4 -12
- package/front_end/panels/profiler/ProfileView.ts +1 -6
- package/front_end/panels/profiler/ProfilesPanel.ts +60 -7
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +27 -22
- package/front_end/panels/timeline/EventsTimelineTreeView.ts +1 -1
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +11 -153
- package/front_end/panels/timeline/TimelineTreeView.ts +147 -48
- package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
- package/front_end/panels/timeline/components/CWVMetrics.ts +18 -2
- package/front_end/panels/timeline/timeline-meta.ts +11 -0
- package/front_end/panels/timeline/utils/Helpers.ts +5 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/markdown_view/CodeBlock.ts +47 -1
- package/front_end/ui/components/markdown_view/codeBlock.css +8 -0
- package/front_end/ui/legacy/FilterBar.ts +2 -0
- package/front_end/ui/legacy/SplitWidget.ts +33 -27
- package/front_end/ui/legacy/TabbedPane.ts +123 -3
- package/front_end/ui/legacy/Widget.ts +95 -48
- package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -1
- package/front_end/ui/legacy/components/utils/jsUtils.css +2 -0
- package/front_end/ui/legacy/infobar.css +1 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +6 -1
- package/package.json +1 -1
- package/front_end/core/sdk/WebMCPModel.ts +0 -104
- package/front_end/models/ai_assistance/ConversationHandler.ts +0 -325
|
@@ -178,8 +178,8 @@ export class TimelineTreeView extends
|
|
|
178
178
|
private lastHoveredProfileNode!: Trace.Extras.TraceTree.Node|null;
|
|
179
179
|
private textFilterInternal!: TimelineRegExp;
|
|
180
180
|
private taskFilter!: Trace.Extras.TraceFilter.ExclusiveNameFilter;
|
|
181
|
-
protected
|
|
182
|
-
protected
|
|
181
|
+
protected startTimeInternal!: Trace.Types.Timing.Milli;
|
|
182
|
+
protected endTimeInternal!: Trace.Types.Timing.Milli;
|
|
183
183
|
splitWidget!: UI.SplitWidget.SplitWidget;
|
|
184
184
|
detailsView!: UI.Widget.Widget;
|
|
185
185
|
private searchableView!: UI.SearchableView.SearchableView;
|
|
@@ -197,6 +197,10 @@ export class TimelineTreeView extends
|
|
|
197
197
|
#entityMapper: Trace.EntityMapper.EntityMapper|null = null;
|
|
198
198
|
#lastHighlightedEvent: HTMLElement|null = null;
|
|
199
199
|
eventToTreeNode = new WeakMap<Trace.Types.Events.Event, Trace.Extras.TraceTree.Node>();
|
|
200
|
+
// Compact mode is used to render the tree view in a more compact UI,
|
|
201
|
+
// suitable for AI assistance widgets. It removes sidebars and toolbars.
|
|
202
|
+
#compactMode = false;
|
|
203
|
+
#maxLinkLength: number|undefined = undefined;
|
|
200
204
|
|
|
201
205
|
/**
|
|
202
206
|
* Determines if the first child in the data grid will be selected
|
|
@@ -213,12 +217,85 @@ export class TimelineTreeView extends
|
|
|
213
217
|
this.searchResults = [];
|
|
214
218
|
}
|
|
215
219
|
|
|
220
|
+
get selectedEvents(): Trace.Types.Events.Event[] {
|
|
221
|
+
return this.#selectedEvents || [];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
set selectedEvents(selectedEvents: Trace.Types.Events.Event[]|null) {
|
|
225
|
+
this.#selectedEvents = selectedEvents;
|
|
226
|
+
this.refreshTree();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
set parsedTrace(parsedTrace: Trace.TraceModel.ParsedTrace|null) {
|
|
230
|
+
this.#parsedTrace = parsedTrace;
|
|
231
|
+
this.refreshTree();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
get parsedTrace(): Trace.TraceModel.ParsedTrace|null {
|
|
235
|
+
return this.#parsedTrace;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
set startTime(startTime: Trace.Types.Timing.Milli) {
|
|
239
|
+
if (this.startTimeInternal === startTime) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
this.startTimeInternal = startTime;
|
|
243
|
+
this.refreshTree();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
get startTime(): Trace.Types.Timing.Milli {
|
|
247
|
+
return this.startTimeInternal;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
set endTime(endTime: Trace.Types.Timing.Milli) {
|
|
251
|
+
if (this.endTimeInternal === endTime) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
this.endTimeInternal = endTime;
|
|
255
|
+
this.refreshTree();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
get endTime(): Trace.Types.Timing.Milli {
|
|
259
|
+
return this.endTimeInternal;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
get compactMode(): boolean {
|
|
263
|
+
return this.#compactMode;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
set compactMode(v: boolean) {
|
|
267
|
+
if (this.#compactMode === v) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.#compactMode = v;
|
|
271
|
+
if (this.dataGrid) {
|
|
272
|
+
this.#applyCompactMode();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get maxLinkLength(): number|undefined {
|
|
277
|
+
return this.#maxLinkLength;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
set maxLinkLength(maxLinkLength: number|undefined) {
|
|
281
|
+
this.#maxLinkLength = maxLinkLength;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#applyCompactMode(): void {
|
|
285
|
+
if (this.#compactMode && this.dataGrid) {
|
|
286
|
+
this.splitWidget?.detach();
|
|
287
|
+
this.dataGrid.asWidget().detach();
|
|
288
|
+
this.dataGrid.asWidget().show(this.element);
|
|
289
|
+
this.dataGrid.renderInline();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
216
293
|
#eventNameForSorting(event: Trace.Types.Events.Event): string {
|
|
217
294
|
const name = TimelineUIUtils.eventTitle(event) || event.name;
|
|
218
|
-
if (!this
|
|
295
|
+
if (!this.parsedTrace) {
|
|
219
296
|
return name;
|
|
220
297
|
}
|
|
221
|
-
return name + ':@' + Trace.Handlers.Helpers.getNonResolvedURL(event, this
|
|
298
|
+
return name + ':@' + Trace.Handlers.Helpers.getNonResolvedURL(event, this.parsedTrace.data);
|
|
222
299
|
}
|
|
223
300
|
|
|
224
301
|
setSearchableView(searchableView: UI.SearchableView.SearchableView): void {
|
|
@@ -239,9 +316,6 @@ export class TimelineTreeView extends
|
|
|
239
316
|
entityMapper(): Trace.EntityMapper.EntityMapper|null {
|
|
240
317
|
return this.#entityMapper;
|
|
241
318
|
}
|
|
242
|
-
parsedTrace(): Trace.TraceModel.ParsedTrace|null {
|
|
243
|
-
return this.#parsedTrace;
|
|
244
|
-
}
|
|
245
319
|
|
|
246
320
|
isThirdPartyTreeView(): boolean {
|
|
247
321
|
return false;
|
|
@@ -269,13 +343,6 @@ export class TimelineTreeView extends
|
|
|
269
343
|
const columns: DataGrid.DataGrid.ColumnDescriptor[] = [];
|
|
270
344
|
this.populateColumns(columns);
|
|
271
345
|
|
|
272
|
-
this.splitWidget = new UI.SplitWidget.SplitWidget(true, true, 'timeline-tree-view-details-split-widget');
|
|
273
|
-
const mainView = new UI.Widget.VBox();
|
|
274
|
-
const toolbar = mainView.element.createChild('devtools-toolbar');
|
|
275
|
-
toolbar.setAttribute('jslog', `${VisualLogging.toolbar()}`);
|
|
276
|
-
toolbar.wrappable = true;
|
|
277
|
-
this.populateToolbar(toolbar);
|
|
278
|
-
|
|
279
346
|
this.dataGrid = new DataGrid.SortableDataGrid.SortableDataGrid({
|
|
280
347
|
displayName: i18nString(UIStrings.performance),
|
|
281
348
|
columns,
|
|
@@ -287,9 +354,22 @@ export class TimelineTreeView extends
|
|
|
287
354
|
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.OPENED_NODE, this.onGridNodeOpened, this);
|
|
288
355
|
this.dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.LAST);
|
|
289
356
|
this.dataGrid.setRowContextMenuCallback(this.onContextMenu.bind(this));
|
|
290
|
-
this.dataGrid.asWidget().show(mainView.element);
|
|
291
357
|
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, this.updateDetailsForSelection, this);
|
|
292
358
|
|
|
359
|
+
if (this.#compactMode) {
|
|
360
|
+
this.#applyCompactMode();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
this.splitWidget = new UI.SplitWidget.SplitWidget(true, true, 'timeline-tree-view-details-split-widget');
|
|
365
|
+
const mainView = new UI.Widget.VBox();
|
|
366
|
+
const toolbar = mainView.element.createChild('devtools-toolbar');
|
|
367
|
+
toolbar.setAttribute('jslog', `${VisualLogging.toolbar()}`);
|
|
368
|
+
toolbar.wrappable = true;
|
|
369
|
+
this.populateToolbar(toolbar);
|
|
370
|
+
|
|
371
|
+
this.dataGrid.asWidget().show(mainView.element);
|
|
372
|
+
|
|
293
373
|
this.detailsView = new UI.Widget.VBox();
|
|
294
374
|
this.detailsView.element.classList.add('timeline-details-view', 'timeline-details-view-body');
|
|
295
375
|
this.splitWidget.setMainWidget(mainView);
|
|
@@ -299,6 +379,13 @@ export class TimelineTreeView extends
|
|
|
299
379
|
this.splitWidget.addEventListener(UI.SplitWidget.Events.SHOW_MODE_CHANGED, this.onShowModeChanged, this);
|
|
300
380
|
}
|
|
301
381
|
|
|
382
|
+
override wasShown(): void {
|
|
383
|
+
super.wasShown();
|
|
384
|
+
this.refreshTree();
|
|
385
|
+
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, this.#onDataGridSelectionChange, this);
|
|
386
|
+
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.DESELECTED_NODE, this.#onDataGridDeselection, this);
|
|
387
|
+
}
|
|
388
|
+
|
|
302
389
|
lastSelectedNode(): Trace.Extras.TraceTree.Node|null|undefined {
|
|
303
390
|
return this.lastSelectedNodeInternal;
|
|
304
391
|
}
|
|
@@ -375,11 +462,6 @@ export class TimelineTreeView extends
|
|
|
375
462
|
toolbar.appendToolbarItem(textFilterUI);
|
|
376
463
|
}
|
|
377
464
|
|
|
378
|
-
selectedEvents(): Trace.Types.Events.Event[] {
|
|
379
|
-
// TODO: can we make this type readonly?
|
|
380
|
-
return this.#selectedEvents || [];
|
|
381
|
-
}
|
|
382
|
-
|
|
383
465
|
appendContextMenuItems(_contextMenu: UI.ContextMenu.ContextMenu, _node: Trace.Extras.TraceTree.Node): void {
|
|
384
466
|
}
|
|
385
467
|
|
|
@@ -459,7 +541,7 @@ export class TimelineTreeView extends
|
|
|
459
541
|
|
|
460
542
|
buildTopDownTree(doNotAggregate: boolean, eventGroupIdCallback: ((arg0: Trace.Types.Events.Event) => string)|null):
|
|
461
543
|
Trace.Extras.TraceTree.Node {
|
|
462
|
-
return new Trace.Extras.TraceTree.TopDownRootNode(this.selectedEvents
|
|
544
|
+
return new Trace.Extras.TraceTree.TopDownRootNode(this.selectedEvents, {
|
|
463
545
|
filters: this.filters(),
|
|
464
546
|
startTime: this.startTime,
|
|
465
547
|
endTime: this.endTime,
|
|
@@ -469,10 +551,24 @@ export class TimelineTreeView extends
|
|
|
469
551
|
}
|
|
470
552
|
|
|
471
553
|
populateColumns(columns: DataGrid.DataGrid.ColumnDescriptor[]): void {
|
|
472
|
-
|
|
554
|
+
if (this.compactMode) {
|
|
555
|
+
columns.push(
|
|
556
|
+
({id: 'self', title: i18nString(UIStrings.selfTime), width: '15%', sortable: true} as
|
|
557
|
+
DataGrid.DataGrid.ColumnDescriptor));
|
|
558
|
+
columns.push(
|
|
559
|
+
({id: 'total', title: i18nString(UIStrings.totalTime), width: '15%', sortable: true} as
|
|
560
|
+
DataGrid.DataGrid.ColumnDescriptor));
|
|
561
|
+
} else {
|
|
562
|
+
columns.push(
|
|
563
|
+
({id: 'self', title: i18nString(UIStrings.selfTime), width: '120px', fixedWidth: true, sortable: true} as
|
|
564
|
+
DataGrid.DataGrid.ColumnDescriptor));
|
|
565
|
+
columns.push(
|
|
566
|
+
({id: 'total', title: i18nString(UIStrings.totalTime), width: '120px', fixedWidth: true, sortable: true} as
|
|
567
|
+
DataGrid.DataGrid.ColumnDescriptor));
|
|
568
|
+
}
|
|
473
569
|
columns.push(
|
|
474
|
-
{id: '
|
|
475
|
-
|
|
570
|
+
({id: 'activity', title: i18nString(UIStrings.activity), disclosure: true, sortable: true} as
|
|
571
|
+
DataGrid.DataGrid.ColumnDescriptor));
|
|
476
572
|
}
|
|
477
573
|
|
|
478
574
|
sortingChanged(): void {
|
|
@@ -564,6 +660,9 @@ export class TimelineTreeView extends
|
|
|
564
660
|
}
|
|
565
661
|
|
|
566
662
|
private onShowModeChanged(): void {
|
|
663
|
+
if (this.#compactMode || !this.splitWidget) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
567
666
|
if (this.splitWidget.showMode() === UI.SplitWidget.ShowMode.ONLY_MAIN) {
|
|
568
667
|
return;
|
|
569
668
|
}
|
|
@@ -572,6 +671,9 @@ export class TimelineTreeView extends
|
|
|
572
671
|
}
|
|
573
672
|
|
|
574
673
|
protected updateDetailsForSelection(): void {
|
|
674
|
+
if (this.#compactMode || !this.splitWidget || !this.detailsView) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
575
677
|
const selectedNode = this.dataGrid.selectedNode ? (this.dataGrid.selectedNode as TreeGridNode).profileNode : null;
|
|
576
678
|
if (selectedNode === this.lastSelectedNodeInternal) {
|
|
577
679
|
return;
|
|
@@ -612,12 +714,6 @@ export class TimelineTreeView extends
|
|
|
612
714
|
this.dispatchEventToListeners(TimelineTreeView.Events.TREE_ROW_CLICKED, {node});
|
|
613
715
|
}
|
|
614
716
|
|
|
615
|
-
override wasShown(): void {
|
|
616
|
-
super.wasShown();
|
|
617
|
-
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, this.#onDataGridSelectionChange, this);
|
|
618
|
-
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.DESELECTED_NODE, this.#onDataGridDeselection, this);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
717
|
override childWasDetached(_widget: UI.Widget.Widget): void {
|
|
622
718
|
this.dataGrid.removeEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, this.#onDataGridSelectionChange);
|
|
623
719
|
this.dataGrid.removeEventListener(DataGrid.DataGrid.Events.DESELECTED_NODE, this.#onDataGridDeselection);
|
|
@@ -808,12 +904,13 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
|
|
|
808
904
|
}
|
|
809
905
|
} else if (event) {
|
|
810
906
|
name.textContent = TimelineUIUtils.eventTitle(event);
|
|
811
|
-
const parsedTrace = this.treeView.parsedTrace
|
|
907
|
+
const parsedTrace = this.treeView.parsedTrace;
|
|
812
908
|
const target = parsedTrace ? targetForEvent(parsedTrace, event) : null;
|
|
813
909
|
const linkifier = this.treeView.linkifier;
|
|
814
910
|
const isFreshOrEnhanced =
|
|
815
911
|
Boolean(parsedTrace && Tracing.FreshRecording.Tracker.instance().recordingIsFreshOrEnhanced(parsedTrace));
|
|
816
|
-
|
|
912
|
+
const maxLength = this.treeView.maxLinkLength;
|
|
913
|
+
this.linkElement = TimelineUIUtils.linkifyTopCallFrame(event, target, linkifier, isFreshOrEnhanced, maxLength);
|
|
817
914
|
if (this.linkElement) {
|
|
818
915
|
container.createChild('div', 'activity-link').appendChild(this.linkElement);
|
|
819
916
|
}
|
|
@@ -841,7 +938,7 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
|
|
|
841
938
|
switch (columnId) {
|
|
842
939
|
case 'start-time': {
|
|
843
940
|
event = this.profileNode.event;
|
|
844
|
-
const parsedTrace = this.treeView.parsedTrace
|
|
941
|
+
const parsedTrace = this.treeView.parsedTrace;
|
|
845
942
|
if (!parsedTrace) {
|
|
846
943
|
throw new Error('Unable to load trace data for tree view');
|
|
847
944
|
}
|
|
@@ -957,8 +1054,8 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
|
|
|
957
1054
|
protected readonly groupBySetting: Common.Settings.Setting<AggregatedTimelineTreeView.GroupBy>;
|
|
958
1055
|
readonly stackView: TimelineStackView;
|
|
959
1056
|
|
|
960
|
-
constructor() {
|
|
961
|
-
super();
|
|
1057
|
+
constructor(element?: HTMLElement) {
|
|
1058
|
+
super(element);
|
|
962
1059
|
this.groupBySetting = Common.Settings.Settings.instance().createSetting(
|
|
963
1060
|
'timeline-tree-group-by', AggregatedTimelineTreeView.GroupBy.None);
|
|
964
1061
|
this.groupBySetting.addChangeListener(() => this.refreshTree());
|
|
@@ -1038,7 +1135,7 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
|
|
|
1038
1135
|
break;
|
|
1039
1136
|
|
|
1040
1137
|
case AggregatedTimelineTreeView.GroupBy.Frame: {
|
|
1041
|
-
const frame = id ? this.parsedTrace
|
|
1138
|
+
const frame = id ? this.parsedTrace?.data.PageFrames.frames.get(id) : undefined;
|
|
1042
1139
|
const frameName = frame ? TimelineUIUtils.displayNameForFrame(frame) : i18nString(UIStrings.page);
|
|
1043
1140
|
return {name: frameName, color};
|
|
1044
1141
|
}
|
|
@@ -1067,10 +1164,12 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
|
|
|
1067
1164
|
];
|
|
1068
1165
|
toolbar.appendToolbarItem(
|
|
1069
1166
|
new UI.Toolbar.ToolbarSettingComboBox(options, this.groupBySetting, i18nString(UIStrings.groupBy)));
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1167
|
+
if (!this.compactMode && this.splitWidget) {
|
|
1168
|
+
toolbar.appendSpacer();
|
|
1169
|
+
toolbar.appendToolbarItem(this.splitWidget.createShowHideSidebarButton(
|
|
1170
|
+
i18nString(UIStrings.showHeaviestStack), i18nString(UIStrings.hideHeaviestStack),
|
|
1171
|
+
i18nString(UIStrings.heaviestStackShown), i18nString(UIStrings.heaviestStackHidden)));
|
|
1172
|
+
}
|
|
1074
1173
|
}
|
|
1075
1174
|
|
|
1076
1175
|
private buildHeaviestStack(treeNode: Trace.Extras.TraceTree.Node): Trace.Extras.TraceTree.Node[] {
|
|
@@ -1123,13 +1222,13 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
|
|
|
1123
1222
|
return this.domainByEvent.bind(this, groupBy);
|
|
1124
1223
|
case GroupBy.URL:
|
|
1125
1224
|
return (event: Trace.Types.Events.Event) => {
|
|
1126
|
-
const parsedTrace = this.parsedTrace
|
|
1225
|
+
const parsedTrace = this.parsedTrace;
|
|
1127
1226
|
return parsedTrace ? Trace.Handlers.Helpers.getNonResolvedURL(event, parsedTrace.data) ?? '' : '';
|
|
1128
1227
|
};
|
|
1129
1228
|
case GroupBy.Frame:
|
|
1130
1229
|
return (event: Trace.Types.Events.Event) => {
|
|
1131
1230
|
const frameId = Trace.Helpers.Trace.frameIDForEvent(event);
|
|
1132
|
-
return frameId || this.parsedTrace
|
|
1231
|
+
return frameId || this.parsedTrace?.data.Meta.mainFrameId || '';
|
|
1133
1232
|
};
|
|
1134
1233
|
default:
|
|
1135
1234
|
console.assert(false, `Unexpected aggregation setting: ${groupBy}`);
|
|
@@ -1141,7 +1240,7 @@ export class AggregatedTimelineTreeView extends TimelineTreeView {
|
|
|
1141
1240
|
// The eventid == the identity of a node that we expect in a bottomUp tree (either without grouping or with the groupBy grouping)
|
|
1142
1241
|
// A "top node" (in `ungroupedTopNodes`) is aggregated by this. (But so are all the other nodes, except the `GroupNode`s)
|
|
1143
1242
|
private domainByEvent(groupBy: AggregatedTimelineTreeView.GroupBy, event: Trace.Types.Events.Event): string {
|
|
1144
|
-
const parsedTrace = this.parsedTrace
|
|
1243
|
+
const parsedTrace = this.parsedTrace;
|
|
1145
1244
|
if (!parsedTrace) {
|
|
1146
1245
|
return '';
|
|
1147
1246
|
}
|
|
@@ -1254,8 +1353,8 @@ export namespace AggregatedTimelineTreeView {
|
|
|
1254
1353
|
}
|
|
1255
1354
|
|
|
1256
1355
|
export class CallTreeTimelineTreeView extends AggregatedTimelineTreeView {
|
|
1257
|
-
constructor() {
|
|
1258
|
-
super();
|
|
1356
|
+
constructor(element?: HTMLElement) {
|
|
1357
|
+
super(element);
|
|
1259
1358
|
this.element.setAttribute('jslog', `${VisualLogging.pane('call-tree').track({resize: true})}`);
|
|
1260
1359
|
this.dataGrid.markColumnAsSortedBy('total', DataGrid.DataGrid.Order.Descending);
|
|
1261
1360
|
}
|
|
@@ -1267,14 +1366,14 @@ export class CallTreeTimelineTreeView extends AggregatedTimelineTreeView {
|
|
|
1267
1366
|
}
|
|
1268
1367
|
|
|
1269
1368
|
export class BottomUpTimelineTreeView extends AggregatedTimelineTreeView {
|
|
1270
|
-
constructor() {
|
|
1271
|
-
super();
|
|
1369
|
+
constructor(element?: HTMLElement) {
|
|
1370
|
+
super(element);
|
|
1272
1371
|
this.element.setAttribute('jslog', `${VisualLogging.pane('bottom-up').track({resize: true})}`);
|
|
1273
1372
|
this.dataGrid.markColumnAsSortedBy('self', DataGrid.DataGrid.Order.Descending);
|
|
1274
1373
|
}
|
|
1275
1374
|
|
|
1276
1375
|
override buildTree(): Trace.Extras.TraceTree.Node {
|
|
1277
|
-
return new Trace.Extras.TraceTree.BottomUpRootNode(this.selectedEvents
|
|
1376
|
+
return new Trace.Extras.TraceTree.BottomUpRootNode(this.selectedEvents, {
|
|
1278
1377
|
textFilter: this.textFilter(),
|
|
1279
1378
|
filters: this.filtersWithoutTextFilter(),
|
|
1280
1379
|
startTime: this.startTime,
|
|
@@ -785,7 +785,7 @@ export class TimelineUIUtils {
|
|
|
785
785
|
|
|
786
786
|
static linkifyTopCallFrame(
|
|
787
787
|
event: Trace.Types.Events.Event, target: SDK.Target.Target|null, linkifier: LegacyComponents.Linkifier.Linkifier,
|
|
788
|
-
isFreshOrEnhanced = false): Element|null {
|
|
788
|
+
isFreshOrEnhanced = false, maxLength?: number): Element|null {
|
|
789
789
|
let frame = Trace.Helpers.Trace.getZeroIndexedStackTraceInEventPayload(event)?.[0];
|
|
790
790
|
if (Trace.Types.Events.isProfileCall(event)) {
|
|
791
791
|
frame = event.callFrame;
|
|
@@ -800,6 +800,7 @@ export class TimelineUIUtils {
|
|
|
800
800
|
showColumnNumber: true,
|
|
801
801
|
columnNumber: frame.columnNumber,
|
|
802
802
|
lineNumber: frame.lineNumber,
|
|
803
|
+
maxLength,
|
|
803
804
|
};
|
|
804
805
|
if (isFreshOrEnhanced) {
|
|
805
806
|
return linkifier.maybeLinkifyConsoleCallFrame(target, frame, {showColumnNumber: true, inlineFrameIndex: 0});
|
|
@@ -121,6 +121,7 @@ interface MetricsViewInput {
|
|
|
121
121
|
didDismissFieldMismatchNotice: boolean;
|
|
122
122
|
onDismisFieldMismatchNotice: () => void;
|
|
123
123
|
onClickMetric: (traceEvent: Trace.Types.Events.Event) => void;
|
|
124
|
+
skipBottomBorder: boolean;
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
type MetricsView = (input: MetricsViewInput, output: undefined, target: HTMLElement) => void;
|
|
@@ -210,7 +211,7 @@ const CWV_METRICS_VIEW: MetricsView = (input, _output, target) => {
|
|
|
210
211
|
<span>${clsEl}</span>
|
|
211
212
|
<span class="row-label">Local</span>
|
|
212
213
|
</div>
|
|
213
|
-
|
|
214
|
+
${!field && input.skipBottomBorder ? Lit.nothing : html`<span class="row-border"></span>`}
|
|
214
215
|
`;
|
|
215
216
|
|
|
216
217
|
let fieldMetricsTemplateResult;
|
|
@@ -234,7 +235,7 @@ const CWV_METRICS_VIEW: MetricsView = (input, _output, target) => {
|
|
|
234
235
|
<span>${clsEl}</span>
|
|
235
236
|
<span class="row-label">${i18nString(UIStrings.fieldScoreLabel, {PH1: scope})}</span>
|
|
236
237
|
</div>
|
|
237
|
-
|
|
238
|
+
${input.skipBottomBorder ? Lit.nothing : html`<span class="row-border"></span>`}
|
|
238
239
|
`;
|
|
239
240
|
// clang-format on
|
|
240
241
|
}
|
|
@@ -293,6 +294,8 @@ export class CWVMetrics extends UI.Widget.Widget {
|
|
|
293
294
|
|
|
294
295
|
#didDismissFieldMismatchNotice = false;
|
|
295
296
|
|
|
297
|
+
#skipBottomBorder = false;
|
|
298
|
+
|
|
296
299
|
constructor(element?: HTMLElement, view: MetricsView = CWV_METRICS_VIEW) {
|
|
297
300
|
super(element, {useShadowDom: true});
|
|
298
301
|
this.#view = view;
|
|
@@ -303,6 +306,18 @@ export class CWVMetrics extends UI.Widget.Widget {
|
|
|
303
306
|
this.requestUpdate();
|
|
304
307
|
}
|
|
305
308
|
|
|
309
|
+
get skipBottomBorder(): boolean {
|
|
310
|
+
return this.#skipBottomBorder;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
set skipBottomBorder(x: boolean) {
|
|
314
|
+
if (x === this.#skipBottomBorder) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
this.#skipBottomBorder = x;
|
|
318
|
+
this.requestUpdate();
|
|
319
|
+
}
|
|
320
|
+
|
|
306
321
|
#onClickMetric(traceEvent: Trace.Types.Events.Event): void {
|
|
307
322
|
this.element.dispatchEvent(new Insights.EventRef.EventReferenceClick(traceEvent));
|
|
308
323
|
}
|
|
@@ -333,6 +348,7 @@ export class CWVMetrics extends UI.Widget.Widget {
|
|
|
333
348
|
didDismissFieldMismatchNotice: this.#didDismissFieldMismatchNotice,
|
|
334
349
|
onDismisFieldMismatchNotice: this.#onDismisFieldMismatchNotice.bind(this),
|
|
335
350
|
onClickMetric: this.#onClickMetric.bind(this),
|
|
351
|
+
skipBottomBorder: this.#skipBottomBorder,
|
|
336
352
|
};
|
|
337
353
|
this.#view(input, undefined, this.contentElement);
|
|
338
354
|
}
|
|
@@ -401,3 +401,14 @@ Common.Revealer.registerRevealer({
|
|
|
401
401
|
return new Timeline.TimelinePanel.TimeRangeRevealer();
|
|
402
402
|
},
|
|
403
403
|
});
|
|
404
|
+
|
|
405
|
+
Common.Revealer.registerRevealer({
|
|
406
|
+
contextTypes() {
|
|
407
|
+
return maybeRetrieveContextTypes(Timeline => [Timeline.Utils.Helpers.RevealableBottomUpProfile]);
|
|
408
|
+
},
|
|
409
|
+
destination: Common.Revealer.RevealerDestination.TIMELINE_PANEL,
|
|
410
|
+
async loadRevealer() {
|
|
411
|
+
const Timeline = await loadTimelineModule();
|
|
412
|
+
return new Timeline.TimelinePanel.BottomUpProfileRevealer();
|
|
413
|
+
},
|
|
414
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: Internal
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: ed66cb5e93e6205f5231c1dcfac9b91b2aa4ffd6
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -34,6 +34,11 @@ const UIStrings = {
|
|
|
34
34
|
* @description Disclaimer shown in the code blocks.
|
|
35
35
|
*/
|
|
36
36
|
disclaimer: 'Use code snippets with caution',
|
|
37
|
+
/**
|
|
38
|
+
* @description The title of the button to show all lines of a code block.
|
|
39
|
+
* @example {5} PH1
|
|
40
|
+
*/
|
|
41
|
+
showAllLines: 'Show all lines ({PH1} more)',
|
|
37
42
|
} as const;
|
|
38
43
|
const str_ = i18n.i18n.registerUIStrings('ui/components/markdown_view/CodeBlock.ts', UIStrings);
|
|
39
44
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -130,6 +135,7 @@ export class CodeBlock extends HTMLElement {
|
|
|
130
135
|
#copied = false;
|
|
131
136
|
#editorState?: CodeMirror.EditorState;
|
|
132
137
|
#languageConf = new CodeMirror.Compartment();
|
|
138
|
+
#truncationConf = new CodeMirror.Compartment();
|
|
133
139
|
/**
|
|
134
140
|
* Whether to display a notice "Use code snippets with caution" in code
|
|
135
141
|
* blocks.
|
|
@@ -138,6 +144,7 @@ export class CodeBlock extends HTMLElement {
|
|
|
138
144
|
#header?: string;
|
|
139
145
|
#showCopyButton = true;
|
|
140
146
|
#citations: Citation[] = [];
|
|
147
|
+
#displayLimit = Number.MAX_VALUE;
|
|
141
148
|
|
|
142
149
|
connectedCallback(): void {
|
|
143
150
|
void this.#render();
|
|
@@ -152,6 +159,7 @@ export class CodeBlock extends HTMLElement {
|
|
|
152
159
|
CodeMirror.EditorState.readOnly.of(true),
|
|
153
160
|
CodeMirror.EditorView.lineWrapping,
|
|
154
161
|
this.#languageConf.of(CodeMirror.javascript.javascript()),
|
|
162
|
+
this.#truncationConf.of([]),
|
|
155
163
|
],
|
|
156
164
|
});
|
|
157
165
|
void this.#render();
|
|
@@ -190,6 +198,15 @@ export class CodeBlock extends HTMLElement {
|
|
|
190
198
|
this.#citations = citations;
|
|
191
199
|
}
|
|
192
200
|
|
|
201
|
+
set displayLimit(value: number) {
|
|
202
|
+
this.#displayLimit = value;
|
|
203
|
+
void this.#render();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
get displayLimit(): number {
|
|
207
|
+
return this.#displayLimit;
|
|
208
|
+
}
|
|
209
|
+
|
|
193
210
|
#onCopy(): void {
|
|
194
211
|
UI.UIUtils.copyTextToClipboard(this.#code, i18nString(UIStrings.copied));
|
|
195
212
|
this.#copied = true;
|
|
@@ -256,6 +273,9 @@ export class CodeBlock extends HTMLElement {
|
|
|
256
273
|
throw new Error('Unexpected: trying to render the text editor without editorState');
|
|
257
274
|
}
|
|
258
275
|
|
|
276
|
+
const linesCount = this.#editorState.doc.lines;
|
|
277
|
+
const isTruncated = linesCount > this.#displayLimit;
|
|
278
|
+
|
|
259
279
|
// clang-format off
|
|
260
280
|
Lit.render(
|
|
261
281
|
html`<div class='codeblock' jslog=${VisualLogging.section('code')}>
|
|
@@ -271,6 +291,19 @@ export class CodeBlock extends HTMLElement {
|
|
|
271
291
|
<div class="code">
|
|
272
292
|
<devtools-text-editor .state=${this.#editorState}></devtools-text-editor>
|
|
273
293
|
</div>
|
|
294
|
+
${isTruncated ? html`
|
|
295
|
+
<div class="show-all-container">
|
|
296
|
+
<devtools-button
|
|
297
|
+
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
298
|
+
.size=${Buttons.Button.Size.SMALL}
|
|
299
|
+
.jslogContext=${'show-all'}
|
|
300
|
+
.title=${i18nString(UIStrings.showAllLines, { PH1: linesCount - this.#displayLimit })}
|
|
301
|
+
@click=${() => {
|
|
302
|
+
this.displayLimit = Number.MAX_VALUE;
|
|
303
|
+
}}
|
|
304
|
+
>${i18nString(UIStrings.showAllLines, { PH1: linesCount - this.#displayLimit })}</devtools-button>
|
|
305
|
+
</div>
|
|
306
|
+
` : Lit.nothing}
|
|
274
307
|
</div>
|
|
275
308
|
${this.#displayNotice ? this.#renderNotice() : Lit.nothing}
|
|
276
309
|
</div>`,
|
|
@@ -288,8 +321,21 @@ export class CodeBlock extends HTMLElement {
|
|
|
288
321
|
}
|
|
289
322
|
|
|
290
323
|
const language = await languageFromToken(this.#codeLang);
|
|
324
|
+
let truncationExtension: CodeMirror.Extension = [];
|
|
325
|
+
if (isTruncated) {
|
|
326
|
+
truncationExtension = CodeMirror.EditorView.decorations.of(CodeMirror.Decoration.set(
|
|
327
|
+
CodeMirror.Decoration.replace({}).range(
|
|
328
|
+
this.#editorState.doc.line(this.#displayLimit).to,
|
|
329
|
+
this.#editorState.doc.length,
|
|
330
|
+
),
|
|
331
|
+
));
|
|
332
|
+
}
|
|
333
|
+
|
|
291
334
|
editor.dispatch({
|
|
292
|
-
effects:
|
|
335
|
+
effects: [
|
|
336
|
+
this.#languageConf.reconfigure(language),
|
|
337
|
+
this.#truncationConf.reconfigure(truncationExtension),
|
|
338
|
+
],
|
|
293
339
|
});
|
|
294
340
|
}
|
|
295
341
|
}
|
|
@@ -108,3 +108,11 @@
|
|
|
108
108
|
text-decoration-line: underline;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
.show-all-container {
|
|
113
|
+
display: flex;
|
|
114
|
+
justify-content: center;
|
|
115
|
+
align-items: center;
|
|
116
|
+
padding: var(--sys-size-4) 0;
|
|
117
|
+
background-color: var(--code-block-background-color); /* stylelint-disable-line plugin/use_theme_colors */
|
|
118
|
+
}
|
|
@@ -21,6 +21,8 @@ import {Tooltip} from './Tooltip.js';
|
|
|
21
21
|
import {bindCheckbox, CheckboxLabel, createTextChild} from './UIUtils.js';
|
|
22
22
|
import {HBox} from './Widget.js';
|
|
23
23
|
|
|
24
|
+
export {filterStyles};
|
|
25
|
+
|
|
24
26
|
const UIStrings = {
|
|
25
27
|
/**
|
|
26
28
|
* @description Text to filter result items
|