lighthouse 9.5.0-dev.20220513 → 9.5.0-dev.20220516
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/dist/report/bundle.esm.js +85 -89
- package/dist/report/flow.js +9 -9
- package/dist/report/standalone.js +11 -11
- package/flow-report/src/util.ts +1 -1
- package/package.json +1 -1
- package/report/renderer/category-renderer.js +20 -23
- package/report/renderer/crc-details-renderer.js +21 -23
- package/report/renderer/details-renderer.js +6 -6
- package/report/renderer/dom.js +6 -6
- package/report/renderer/element-screenshot-renderer.js +1 -1
- package/report/renderer/performance-category-renderer.js +10 -10
- package/report/renderer/pwa-category-renderer.js +3 -3
- package/report/renderer/report-renderer.js +17 -16
- package/report/renderer/snippet-renderer.js +2 -2
package/flow-report/src/util.ts
CHANGED
|
@@ -137,7 +137,7 @@ function useExternalRenderer<T extends Element>(
|
|
|
137
137
|
if (!ref.current) return;
|
|
138
138
|
|
|
139
139
|
const root = renderCallback();
|
|
140
|
-
ref.current.
|
|
140
|
+
ref.current.append(root);
|
|
141
141
|
|
|
142
142
|
return () => {
|
|
143
143
|
if (ref.current?.contains(root)) ref.current.removeChild(root);
|
package/package.json
CHANGED
|
@@ -72,9 +72,9 @@ export class CategoryRenderer {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const titleEl = this.dom.find('.lh-audit__title', auditEl);
|
|
75
|
-
titleEl.
|
|
75
|
+
titleEl.append(this.dom.convertMarkdownCodeSnippets(audit.result.title));
|
|
76
76
|
const descEl = this.dom.find('.lh-audit__description', auditEl);
|
|
77
|
-
descEl.
|
|
77
|
+
descEl.append(this.dom.convertMarkdownLinkSnippets(audit.result.description));
|
|
78
78
|
|
|
79
79
|
for (const relevantMetric of audit.relevantMetrics || []) {
|
|
80
80
|
const adornEl = this.dom.createChildOf(descEl, 'span', 'lh-audit__adorn');
|
|
@@ -84,19 +84,16 @@ export class CategoryRenderer {
|
|
|
84
84
|
|
|
85
85
|
if (audit.stackPacks) {
|
|
86
86
|
audit.stackPacks.forEach(pack => {
|
|
87
|
-
const
|
|
88
|
-
packElm.classList.add('lh-audit__stackpack');
|
|
89
|
-
|
|
90
|
-
const packElmImg = this.dom.createElement('img');
|
|
91
|
-
packElmImg.classList.add('lh-audit__stackpack__img');
|
|
87
|
+
const packElmImg = this.dom.createElement('img', 'lh-audit__stackpack__img');
|
|
92
88
|
packElmImg.src = pack.iconDataURL;
|
|
93
89
|
packElmImg.alt = pack.title;
|
|
94
|
-
packElm.appendChild(packElmImg);
|
|
95
90
|
|
|
96
|
-
|
|
91
|
+
const snippets = this.dom.convertMarkdownLinkSnippets(pack.description);
|
|
92
|
+
const packElm = this.dom.createElement('div', 'lh-audit__stackpack');
|
|
93
|
+
packElm.append(packElmImg, snippets);
|
|
97
94
|
|
|
98
95
|
this.dom.find('.lh-audit__stackpacks', auditEl)
|
|
99
|
-
.
|
|
96
|
+
.append(packElm);
|
|
100
97
|
});
|
|
101
98
|
}
|
|
102
99
|
|
|
@@ -105,12 +102,12 @@ export class CategoryRenderer {
|
|
|
105
102
|
const elem = this.detailsRenderer.render(audit.result.details);
|
|
106
103
|
if (elem) {
|
|
107
104
|
elem.classList.add('lh-details');
|
|
108
|
-
header.
|
|
105
|
+
header.append(elem);
|
|
109
106
|
}
|
|
110
107
|
}
|
|
111
108
|
|
|
112
109
|
// Add chevron SVG to the end of the summary
|
|
113
|
-
this.dom.find('.lh-chevron-container', auditEl).
|
|
110
|
+
this.dom.find('.lh-chevron-container', auditEl).append(this._createChevron());
|
|
114
111
|
this._setRatingClass(auditEl, audit.result.score, scoreDisplayMode);
|
|
115
112
|
|
|
116
113
|
if (audit.result.scoreDisplayMode === 'error') {
|
|
@@ -132,7 +129,7 @@ export class CategoryRenderer {
|
|
|
132
129
|
const warningsEl = this.dom.createChildOf(summaryEl, 'div', 'lh-warnings');
|
|
133
130
|
this.dom.createChildOf(warningsEl, 'span').textContent = strings.warningHeader;
|
|
134
131
|
if (warnings.length === 1) {
|
|
135
|
-
warningsEl.
|
|
132
|
+
warningsEl.append(this.dom.createTextNode(warnings.join('')));
|
|
136
133
|
} else {
|
|
137
134
|
const warningsUl = this.dom.createChildOf(warningsEl, 'ul');
|
|
138
135
|
for (const warning of warnings) {
|
|
@@ -207,11 +204,11 @@ export class CategoryRenderer {
|
|
|
207
204
|
|
|
208
205
|
const gaugeContainerEl = this.dom.find('.lh-score__gauge', component);
|
|
209
206
|
const gaugeEl = this.renderCategoryScore(category, groupDefinitions, options);
|
|
210
|
-
gaugeContainerEl.
|
|
207
|
+
gaugeContainerEl.append(gaugeEl);
|
|
211
208
|
|
|
212
209
|
if (category.description) {
|
|
213
210
|
const descEl = this.dom.convertMarkdownLinkSnippets(category.description);
|
|
214
|
-
this.dom.find('.lh-category-header__description', component).
|
|
211
|
+
this.dom.find('.lh-category-header__description', component).append(descEl);
|
|
215
212
|
}
|
|
216
213
|
|
|
217
214
|
return component;
|
|
@@ -230,13 +227,13 @@ export class CategoryRenderer {
|
|
|
230
227
|
|
|
231
228
|
this.dom.createChildOf(auditGroupHeader, 'span', 'lh-audit-group__title')
|
|
232
229
|
.textContent = group.title;
|
|
233
|
-
groupEl.
|
|
230
|
+
groupEl.append(auditGroupHeader);
|
|
234
231
|
|
|
235
232
|
let footerEl = null;
|
|
236
233
|
if (group.description) {
|
|
237
234
|
footerEl = this.dom.convertMarkdownLinkSnippets(group.description);
|
|
238
235
|
footerEl.classList.add('lh-audit-group__description', 'lh-audit-group__footer');
|
|
239
|
-
groupEl.
|
|
236
|
+
groupEl.append(footerEl);
|
|
240
237
|
}
|
|
241
238
|
|
|
242
239
|
return [groupEl, footerEl];
|
|
@@ -300,7 +297,7 @@ export class CategoryRenderer {
|
|
|
300
297
|
renderUnexpandableClump(auditRefs, groupDefinitions) {
|
|
301
298
|
const clumpElement = this.dom.createElement('div');
|
|
302
299
|
const elements = this._renderGroupedAudits(auditRefs, groupDefinitions);
|
|
303
|
-
elements.forEach(elem => clumpElement.
|
|
300
|
+
elements.forEach(elem => clumpElement.append(elem));
|
|
304
301
|
return clumpElement;
|
|
305
302
|
}
|
|
306
303
|
|
|
@@ -334,7 +331,7 @@ export class CategoryRenderer {
|
|
|
334
331
|
if (description) {
|
|
335
332
|
const descriptionEl = this.dom.convertMarkdownLinkSnippets(description);
|
|
336
333
|
descriptionEl.classList.add('lh-audit-group__description', 'lh-audit-group__footer');
|
|
337
|
-
el.
|
|
334
|
+
el.append(descriptionEl);
|
|
338
335
|
}
|
|
339
336
|
|
|
340
337
|
this.dom.find('.lh-clump-toggletext--show', el).textContent = Util.i18n.strings.show;
|
|
@@ -426,7 +423,7 @@ export class CategoryRenderer {
|
|
|
426
423
|
const content = this.dom.find('.lh-fraction__content', tmpl);
|
|
427
424
|
const text = this.dom.createElement('span');
|
|
428
425
|
text.textContent = `${numPassed}/${numPassableAudits}`;
|
|
429
|
-
content.
|
|
426
|
+
content.append(text);
|
|
430
427
|
|
|
431
428
|
let rating = Util.calculateRating(fraction);
|
|
432
429
|
|
|
@@ -530,7 +527,7 @@ export class CategoryRenderer {
|
|
|
530
527
|
render(category, groupDefinitions = {}, options) {
|
|
531
528
|
const element = this.dom.createElement('div', 'lh-category');
|
|
532
529
|
element.id = category.id;
|
|
533
|
-
element.
|
|
530
|
+
element.append(this.renderCategoryHeader(category, groupDefinitions, options));
|
|
534
531
|
|
|
535
532
|
// Top level clumps for audits, in order they will appear in the report.
|
|
536
533
|
/** @type {Map<TopLevelClumpId, Array<LH.ReportResult.AuditRef>>} */
|
|
@@ -563,13 +560,13 @@ export class CategoryRenderer {
|
|
|
563
560
|
if (clumpId === 'failed') {
|
|
564
561
|
const clumpElem = this.renderUnexpandableClump(auditRefs, groupDefinitions);
|
|
565
562
|
clumpElem.classList.add(`lh-clump--failed`);
|
|
566
|
-
element.
|
|
563
|
+
element.append(clumpElem);
|
|
567
564
|
continue;
|
|
568
565
|
}
|
|
569
566
|
|
|
570
567
|
const description = clumpId === 'manual' ? category.manualDescription : undefined;
|
|
571
568
|
const clumpElem = this.renderClump(clumpId, {auditRefs, description});
|
|
572
|
-
element.
|
|
569
|
+
element.append(clumpElem);
|
|
573
570
|
}
|
|
574
571
|
|
|
575
572
|
return element;
|
|
@@ -105,34 +105,33 @@ class CriticalRequestChainRenderer {
|
|
|
105
105
|
|
|
106
106
|
// Construct lines and add spacers for sub requests.
|
|
107
107
|
segment.treeMarkers.forEach(separator => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
const classSeparator = separator ?
|
|
109
|
+
'lh-tree-marker lh-vert' :
|
|
110
|
+
'lh-tree-marker';
|
|
111
|
+
treeMarkeEl.append(
|
|
112
|
+
dom.createElement('span', classSeparator),
|
|
113
|
+
dom.createElement('span', 'lh-tree-marker')
|
|
114
|
+
);
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
117
|
+
const classLastChild = segment.isLastChild ?
|
|
118
|
+
'lh-tree-marker lh-up-right' :
|
|
119
|
+
'lh-tree-marker lh-vert-right';
|
|
120
|
+
const classHasChildren = segment.hasChildren ?
|
|
121
|
+
'lh-tree-marker lh-horiz-down' :
|
|
122
|
+
'lh-tree-marker lh-right';
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
treeMarkeEl.append(
|
|
125
|
+
dom.createElement('span', classLastChild),
|
|
126
|
+
dom.createElement('span', 'lh-tree-marker lh-right'),
|
|
127
|
+
dom.createElement('span', classHasChildren)
|
|
128
|
+
);
|
|
130
129
|
|
|
131
130
|
// Fill in url, host, and request size information.
|
|
132
131
|
const url = segment.node.request.url;
|
|
133
132
|
const linkEl = detailsRenderer.renderTextURL(url);
|
|
134
133
|
const treevalEl = dom.find('.lh-crc-node__tree-value', chainEl);
|
|
135
|
-
treevalEl.
|
|
134
|
+
treevalEl.append(linkEl);
|
|
136
135
|
|
|
137
136
|
if (!segment.hasChildren) {
|
|
138
137
|
const {startTime, endTime, transferSize} = segment.node.request;
|
|
@@ -141,8 +140,7 @@ class CriticalRequestChainRenderer {
|
|
|
141
140
|
const span2 = dom.createElement('span', 'lh-crc-node__chain-duration');
|
|
142
141
|
span2.textContent = Util.i18n.formatBytesToKiB(transferSize, 0.01);
|
|
143
142
|
|
|
144
|
-
treevalEl.
|
|
145
|
-
treevalEl.appendChild(span2);
|
|
143
|
+
treevalEl.append(span, span2);
|
|
146
144
|
}
|
|
147
145
|
|
|
148
146
|
return chainEl;
|
|
@@ -158,7 +156,7 @@ class CriticalRequestChainRenderer {
|
|
|
158
156
|
* @param {DetailsRenderer} detailsRenderer
|
|
159
157
|
*/
|
|
160
158
|
static buildTree(dom, tmpl, segment, elem, details, detailsRenderer) {
|
|
161
|
-
elem.
|
|
159
|
+
elem.append(CRCRenderer.createChainNode(dom, segment, detailsRenderer));
|
|
162
160
|
if (segment.node.children) {
|
|
163
161
|
for (const key of Object.keys(segment.node.children)) {
|
|
164
162
|
const childSegment = CRCRenderer.createSegment(segment.node.children, key,
|
|
@@ -119,12 +119,12 @@ export class DetailsRenderer {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
const element = this._dom.createElement('div', 'lh-text__url');
|
|
122
|
-
element.
|
|
122
|
+
element.append(this._renderLink({text: displayedPath, url}));
|
|
123
123
|
|
|
124
124
|
if (displayedHost) {
|
|
125
125
|
const hostElem = this._renderText(displayedHost);
|
|
126
126
|
hostElem.classList.add('lh-text__url-host');
|
|
127
|
-
element.
|
|
127
|
+
element.append(hostElem);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
if (title) {
|
|
@@ -397,7 +397,7 @@ export class DetailsRenderer {
|
|
|
397
397
|
|
|
398
398
|
if (valueElement) {
|
|
399
399
|
const classes = `lh-table-column--${heading.valueType}`;
|
|
400
|
-
this._dom.createChildOf(rowElem, 'td', classes).
|
|
400
|
+
this._dom.createChildOf(rowElem, 'td', classes).append(valueElement);
|
|
401
401
|
} else {
|
|
402
402
|
// Empty cell is rendered for a column if:
|
|
403
403
|
// - the pair is null
|
|
@@ -452,7 +452,7 @@ export class DetailsRenderer {
|
|
|
452
452
|
const classes = `lh-table-column--${valueType}`;
|
|
453
453
|
const labelEl = this._dom.createElement('div', 'lh-text');
|
|
454
454
|
labelEl.textContent = heading.label;
|
|
455
|
-
this._dom.createChildOf(theadTrElem, 'th', classes).
|
|
455
|
+
this._dom.createChildOf(theadTrElem, 'th', classes).append(labelEl);
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
const tbodyElem = this._dom.createChildOf(tableElem, 'tbody');
|
|
@@ -495,13 +495,13 @@ export class DetailsRenderer {
|
|
|
495
495
|
if (item.nodeLabel) {
|
|
496
496
|
const nodeLabelEl = this._dom.createElement('div');
|
|
497
497
|
nodeLabelEl.textContent = item.nodeLabel;
|
|
498
|
-
element.
|
|
498
|
+
element.append(nodeLabelEl);
|
|
499
499
|
}
|
|
500
500
|
if (item.snippet) {
|
|
501
501
|
const snippetEl = this._dom.createElement('div');
|
|
502
502
|
snippetEl.classList.add('lh-node__snippet');
|
|
503
503
|
snippetEl.textContent = item.snippet;
|
|
504
|
-
element.
|
|
504
|
+
element.append(snippetEl);
|
|
505
505
|
}
|
|
506
506
|
if (item.selector) {
|
|
507
507
|
element.title = item.selector;
|
package/report/renderer/dom.js
CHANGED
|
@@ -97,7 +97,7 @@ export class DOM {
|
|
|
97
97
|
*/
|
|
98
98
|
createChildOf(parentElem, elementName, className) {
|
|
99
99
|
const element = this.createElement(elementName, className);
|
|
100
|
-
parentElem.
|
|
100
|
+
parentElem.append(element);
|
|
101
101
|
return element;
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -135,7 +135,7 @@ export class DOM {
|
|
|
135
135
|
for (const segment of Util.splitMarkdownLink(text)) {
|
|
136
136
|
if (!segment.isLink) {
|
|
137
137
|
// Plain text segment.
|
|
138
|
-
element.
|
|
138
|
+
element.append(this._document.createTextNode(segment.text));
|
|
139
139
|
continue;
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -153,7 +153,7 @@ export class DOM {
|
|
|
153
153
|
a.target = '_blank';
|
|
154
154
|
a.textContent = segment.text;
|
|
155
155
|
this.safelySetHref(a, url.href);
|
|
156
|
-
element.
|
|
156
|
+
element.append(a);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
return element;
|
|
@@ -210,9 +210,9 @@ export class DOM {
|
|
|
210
210
|
if (segment.isCode) {
|
|
211
211
|
const pre = this.createElement('code');
|
|
212
212
|
pre.textContent = segment.text;
|
|
213
|
-
element.
|
|
213
|
+
element.append(pre);
|
|
214
214
|
} else {
|
|
215
|
-
element.
|
|
215
|
+
element.append(this._document.createTextNode(segment.text));
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -295,7 +295,7 @@ export class DOM {
|
|
|
295
295
|
const a = this.createElement('a');
|
|
296
296
|
a.download = filename;
|
|
297
297
|
this.safelySetBlobHref(a, blob);
|
|
298
|
-
this._document.body.
|
|
298
|
+
this._document.body.append(a); // Firefox requires anchor to be in the DOM.
|
|
299
299
|
a.click();
|
|
300
300
|
|
|
301
301
|
// cleanup.
|
|
@@ -39,7 +39,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
39
39
|
valueEl.textContent = audit.result.displayValue || '';
|
|
40
40
|
|
|
41
41
|
const descriptionEl = this.dom.find('.lh-metric__description', tmpl);
|
|
42
|
-
descriptionEl.
|
|
42
|
+
descriptionEl.append(this.dom.convertMarkdownLinkSnippets(audit.result.description));
|
|
43
43
|
|
|
44
44
|
if (audit.result.scoreDisplayMode === 'error') {
|
|
45
45
|
descriptionEl.textContent = '';
|
|
@@ -179,7 +179,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
179
179
|
const strings = Util.i18n.strings;
|
|
180
180
|
const element = this.dom.createElement('div', 'lh-category');
|
|
181
181
|
element.id = category.id;
|
|
182
|
-
element.
|
|
182
|
+
element.append(this.renderCategoryHeader(category, groups, options));
|
|
183
183
|
|
|
184
184
|
// Metrics.
|
|
185
185
|
const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
|
|
@@ -204,7 +204,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
204
204
|
const metricsBoxesEl = this.dom.createElement('div', 'lh-metrics-container');
|
|
205
205
|
metricsGroupEl.insertBefore(metricsBoxesEl, metricsFooterEl);
|
|
206
206
|
metricAudits.forEach(item => {
|
|
207
|
-
metricsBoxesEl.
|
|
207
|
+
metricsBoxesEl.append(this._renderMetric(item));
|
|
208
208
|
});
|
|
209
209
|
|
|
210
210
|
// Only add the disclaimer with the score calculator link if the category was rendered with a score gauge.
|
|
@@ -212,7 +212,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
212
212
|
const descriptionEl = this.dom.find('.lh-category-header__description', element);
|
|
213
213
|
const estValuesEl = this.dom.createChildOf(descriptionEl, 'div', 'lh-metrics__disclaimer');
|
|
214
214
|
const disclaimerEl = this.dom.convertMarkdownLinkSnippets(strings.varianceDisclaimer);
|
|
215
|
-
estValuesEl.
|
|
215
|
+
estValuesEl.append(disclaimerEl);
|
|
216
216
|
|
|
217
217
|
// Add link to score calculator.
|
|
218
218
|
const calculatorLink = this.dom.createChildOf(estValuesEl, 'a', 'lh-calclink');
|
|
@@ -222,7 +222,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
metricsGroupEl.classList.add('lh-audit-group--metrics');
|
|
225
|
-
element.
|
|
225
|
+
element.append(metricsGroupEl);
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// Filmstrip
|
|
@@ -232,7 +232,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
232
232
|
if (thumbnailResult?.details) {
|
|
233
233
|
timelineEl.id = thumbnailResult.id;
|
|
234
234
|
const filmstripEl = this.detailsRenderer.render(thumbnailResult.details);
|
|
235
|
-
filmstripEl && timelineEl.
|
|
235
|
+
filmstripEl && timelineEl.append(filmstripEl);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// Opportunities
|
|
@@ -266,7 +266,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
266
266
|
opportunityAudits.forEach(item =>
|
|
267
267
|
groupEl.insertBefore(this._renderOpportunity(item, scale), footerEl));
|
|
268
268
|
groupEl.classList.add('lh-audit-group--load-opportunities');
|
|
269
|
-
element.
|
|
269
|
+
element.append(groupEl);
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
// Diagnostics
|
|
@@ -283,7 +283,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
283
283
|
const [groupEl, footerEl] = this.renderAuditGroup(groups['diagnostics']);
|
|
284
284
|
diagnosticAudits.forEach(item => groupEl.insertBefore(this.renderAudit(item), footerEl));
|
|
285
285
|
groupEl.classList.add('lh-audit-group--diagnostics');
|
|
286
|
-
element.
|
|
286
|
+
element.append(groupEl);
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
// Passed audits
|
|
@@ -297,7 +297,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
297
297
|
groupDefinitions: groups,
|
|
298
298
|
};
|
|
299
299
|
const passedElem = this.renderClump('passed', clumpOpts);
|
|
300
|
-
element.
|
|
300
|
+
element.append(passedElem);
|
|
301
301
|
|
|
302
302
|
// Budgets
|
|
303
303
|
/** @type {Array<Element>} */
|
|
@@ -317,7 +317,7 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
317
317
|
const [groupEl, footerEl] = this.renderAuditGroup(groups.budgets);
|
|
318
318
|
budgetTableEls.forEach(table => groupEl.insertBefore(table, footerEl));
|
|
319
319
|
groupEl.classList.add('lh-audit-group--budgets');
|
|
320
|
-
element.
|
|
320
|
+
element.append(groupEl);
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
return element;
|
|
@@ -27,7 +27,7 @@ export class PwaCategoryRenderer extends CategoryRenderer {
|
|
|
27
27
|
render(category, groupDefinitions = {}) {
|
|
28
28
|
const categoryElem = this.dom.createElement('div', 'lh-category');
|
|
29
29
|
categoryElem.id = category.id;
|
|
30
|
-
categoryElem.
|
|
30
|
+
categoryElem.append(this.renderCategoryHeader(category, groupDefinitions));
|
|
31
31
|
|
|
32
32
|
const auditRefs = category.auditRefs;
|
|
33
33
|
|
|
@@ -35,13 +35,13 @@ export class PwaCategoryRenderer extends CategoryRenderer {
|
|
|
35
35
|
// all put in a top-level clump that isn't expandable/collapsible.
|
|
36
36
|
const regularAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode !== 'manual');
|
|
37
37
|
const auditsElem = this._renderAudits(regularAuditRefs, groupDefinitions);
|
|
38
|
-
categoryElem.
|
|
38
|
+
categoryElem.append(auditsElem);
|
|
39
39
|
|
|
40
40
|
// Manual audits are still in a manual clump.
|
|
41
41
|
const manualAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode === 'manual');
|
|
42
42
|
const manualElem = this.renderClump('manual',
|
|
43
43
|
{auditRefs: manualAuditRefs, description: category.manualDescription});
|
|
44
|
-
categoryElem.
|
|
44
|
+
categoryElem.append(manualElem);
|
|
45
45
|
|
|
46
46
|
return categoryElem;
|
|
47
47
|
}
|
|
@@ -70,7 +70,7 @@ export class ReportRenderer {
|
|
|
70
70
|
const report = Util.prepareReportResult(lhr);
|
|
71
71
|
|
|
72
72
|
this._dom.rootEl.textContent = ''; // Remove previous report.
|
|
73
|
-
this._dom.rootEl.
|
|
73
|
+
this._dom.rootEl.append(this._renderReport(report));
|
|
74
74
|
|
|
75
75
|
return this._dom.rootEl;
|
|
76
76
|
}
|
|
@@ -178,11 +178,13 @@ export class ReportRenderer {
|
|
|
178
178
|
const message = this._dom.find('.lh-warnings__msg', container);
|
|
179
179
|
message.textContent = Util.i18n.strings.toplevelWarningsMessage;
|
|
180
180
|
|
|
181
|
-
const warnings =
|
|
181
|
+
const warnings = [];
|
|
182
182
|
for (const warningString of report.runWarnings) {
|
|
183
|
-
const warning =
|
|
184
|
-
warning.
|
|
183
|
+
const warning = this._dom.createElement('li');
|
|
184
|
+
warning.append(this._dom.convertMarkdownLinkSnippets(warningString));
|
|
185
|
+
warnings.push(warning);
|
|
185
186
|
}
|
|
187
|
+
this._dom.find('ul', container).append(...warnings);
|
|
186
188
|
|
|
187
189
|
return container;
|
|
188
190
|
}
|
|
@@ -275,11 +277,11 @@ export class ReportRenderer {
|
|
|
275
277
|
};
|
|
276
278
|
|
|
277
279
|
const headerContainer = this._dom.createElement('div');
|
|
278
|
-
headerContainer.
|
|
280
|
+
headerContainer.append(this._renderReportHeader());
|
|
279
281
|
|
|
280
282
|
const reportContainer = this._dom.createElement('div', 'lh-container');
|
|
281
283
|
const reportSection = this._dom.createElement('div', 'lh-report');
|
|
282
|
-
reportSection.
|
|
284
|
+
reportSection.append(this._renderReportWarnings(report));
|
|
283
285
|
|
|
284
286
|
let scoreHeader;
|
|
285
287
|
const isSoloCategory = Object.keys(report.categories).length === 1;
|
|
@@ -296,23 +298,23 @@ export class ReportRenderer {
|
|
|
296
298
|
const scoresContainer = this._dom.find('.lh-scores-container', headerContainer);
|
|
297
299
|
scoreHeader.append(
|
|
298
300
|
...this._renderScoreGauges(report, categoryRenderer, specificCategoryRenderers));
|
|
299
|
-
scoresContainer.
|
|
300
|
-
scoresContainer.appendChild(scoreScale);
|
|
301
|
+
scoresContainer.append(scoreHeader, scoreScale);
|
|
301
302
|
|
|
302
303
|
const stickyHeader = this._dom.createElement('div', 'lh-sticky-header');
|
|
303
304
|
stickyHeader.append(
|
|
304
305
|
...this._renderScoreGauges(report, categoryRenderer, specificCategoryRenderers));
|
|
305
|
-
reportContainer.
|
|
306
|
+
reportContainer.append(stickyHeader);
|
|
306
307
|
}
|
|
307
308
|
|
|
308
|
-
const categories =
|
|
309
|
+
const categories = this._dom.createElement('div', 'lh-categories');
|
|
310
|
+
reportSection.append(categories);
|
|
309
311
|
const categoryOptions = {gatherMode: report.gatherMode};
|
|
310
312
|
for (const category of Object.values(report.categories)) {
|
|
311
313
|
const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
|
|
312
314
|
// .lh-category-wrapper is full-width and provides horizontal rules between categories.
|
|
313
315
|
// .lh-category within has the max-width: var(--report-content-max-width);
|
|
314
316
|
const wrapper = renderer.dom.createChildOf(categories, 'div', 'lh-category-wrapper');
|
|
315
|
-
wrapper.
|
|
317
|
+
wrapper.append(renderer.render(
|
|
316
318
|
category,
|
|
317
319
|
report.categoryGroups,
|
|
318
320
|
categoryOptions
|
|
@@ -327,13 +329,12 @@ export class ReportRenderer {
|
|
|
327
329
|
}
|
|
328
330
|
|
|
329
331
|
if (!this._opts.omitTopbar) {
|
|
330
|
-
reportFragment.
|
|
332
|
+
reportFragment.append(this._renderReportTopbar(report));
|
|
331
333
|
}
|
|
332
334
|
|
|
333
|
-
reportFragment.
|
|
334
|
-
|
|
335
|
-
reportContainer.
|
|
336
|
-
reportSection.appendChild(this._renderReportFooter(report));
|
|
335
|
+
reportFragment.append(reportContainer);
|
|
336
|
+
reportSection.append(this._renderReportFooter(report));
|
|
337
|
+
reportContainer.append(headerContainer, reportSection);
|
|
337
338
|
|
|
338
339
|
if (fullPageScreenshot) {
|
|
339
340
|
ElementScreenshotRenderer.installFullPageScreenshot(
|
|
@@ -128,7 +128,7 @@ export class SnippetRenderer {
|
|
|
128
128
|
// access the full element detail. Just being able to see the outer HTML isn't very useful.
|
|
129
129
|
if (details.node && dom.isDevTools()) {
|
|
130
130
|
const nodeContainer = dom.find('.lh-snippet__node', header);
|
|
131
|
-
nodeContainer.
|
|
131
|
+
nodeContainer.append(detailsRenderer.renderNode(details.node));
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
return header;
|
|
@@ -163,7 +163,7 @@ export class SnippetRenderer {
|
|
|
163
163
|
const lineContent = content + (truncated ? '…' : '');
|
|
164
164
|
const lineContentEl = dom.find('.lh-snippet__line code', contentLine);
|
|
165
165
|
if (contentType === LineContentType.MESSAGE) {
|
|
166
|
-
lineContentEl.
|
|
166
|
+
lineContentEl.append(dom.convertMarkdownLinkSnippets(lineContent));
|
|
167
167
|
} else {
|
|
168
168
|
lineContentEl.textContent = lineContent;
|
|
169
169
|
}
|