blob: 0460011f16ee20c070e3061a39cd36037f3fb60f [file] [log] [blame]
Patrick Hulcea087f622018-05-18 00:37:53 +00001// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @override
7 */
8Audits2.ReportRenderer = class extends ReportRenderer {
9 /**
10 * Provides empty element for left nav
11 * @override
12 * @returns {!DocumentFragment}
13 */
14 _renderReportNav() {
15 return createDocumentFragment();
16 }
17
18 /**
19 * @param {!ReportRenderer.ReportJSON} report
20 * @override
21 * @return {!DocumentFragment}
22 */
23 _renderReportHeader(report) {
24 return createDocumentFragment();
25 }
26};
27
28class ReportUIFeatures {
29 /**
30 * @param {!ReportRenderer.ReportJSON} report
31 */
32 initFeatures(report) {
33 }
34}
35
36Audits2.CategoryRenderer = class extends CategoryRenderer {
37 /**
38 * @override
39 * @param {!DOM} dom
40 * @param {!DetailsRenderer} detailsRenderer
41 */
42 constructor(dom, detailsRenderer) {
43 super(dom, detailsRenderer);
44 this._defaultPassTrace = null;
45 }
46
47 /**
48 * @param {!ReportRenderer.ReportJSON} lhr
49 */
50 setTraceArtifact(lhr) {
51 if (!lhr.artifacts || !lhr.artifacts.traces || !lhr.artifacts.traces.defaultPass)
52 return;
53 this._defaultPassTrace = lhr.artifacts.traces.defaultPass;
54 }
55
56 /**
57 * @override
58 * @param {!ReportRenderer.CategoryJSON} category
59 * @param {!Object<string, !ReportRenderer.GroupJSON>} groups
60 * @return {!Element}
61 */
62 renderPerformanceCategory(category, groups) {
63 const defaultPassTrace = this._defaultPassTrace;
64 const element = super.renderPerformanceCategory(category, groups);
65 if (!defaultPassTrace)
66 return element;
67
68 const timelineButton = UI.createTextButton(Common.UIString('View Trace'), onViewTraceClick, 'view-trace');
69 element.querySelector('.lh-audit-group').prepend(timelineButton);
70 return element;
71
72 async function onViewTraceClick() {
73 await UI.inspectorView.showPanel('timeline');
74 Timeline.TimelinePanel.instance().loadFromEvents(defaultPassTrace.traceEvents);
75 }
76 }
77};
78
79Audits2.DetailsRenderer = class extends DetailsRenderer {
80 /**
81 * @param {!DOM} dom
82 */
83 constructor(dom) {
84 super(dom);
85 this._onLoadPromise = null;
86 }
87
88 /**
89 * @override
90 * @param {!DetailsRenderer.NodeDetailsJSON} item
91 * @return {!Element}
92 */
93 renderNode(item) {
94 const element = super.renderNode(item);
95 this._replaceWithDeferredNodeBlock(element, item);
96 return element;
97 }
98
99 /**
100 * @param {!Element} origElement
101 * @param {!DetailsRenderer.NodeDetailsJSON} detailsItem
102 */
103 async _replaceWithDeferredNodeBlock(origElement, detailsItem) {
104 const mainTarget = SDK.targetManager.mainTarget();
105 if (!this._onLoadPromise) {
106 const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel);
107 this._onLoadPromise = resourceTreeModel.once(SDK.ResourceTreeModel.Events.Load);
108 }
109
110 await this._onLoadPromise;
111
112 const domModel = mainTarget.model(SDK.DOMModel);
113 if (!detailsItem.path)
114 return;
115
116 const nodeId = await domModel.pushNodeByPathToFrontend(detailsItem.path);
117
118 if (!nodeId)
119 return;
120 const node = domModel.nodeForId(nodeId);
121 if (!node)
122 return;
123
124 const element =
125 await Common.Linkifier.linkify(node, /** @type {!Common.Linkifier.Options} */ ({title: detailsItem.snippet}));
126 origElement.title = '';
127 origElement.textContent = '';
128 origElement.appendChild(element);
129 }
130};