lighthouse 8.3.0-dev.20210904 → 8.3.0

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.
Files changed (196) hide show
  1. package/changelog.md +1 -1
  2. package/dist/report/standalone.js +196 -0
  3. package/jest.config.js +0 -4
  4. package/lighthouse-cli/cli-flags.js +6 -14
  5. package/lighthouse-cli/run.js +1 -1
  6. package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +3 -9
  7. package/lighthouse-cli/test/smokehouse/report-assert.js +16 -36
  8. package/lighthouse-core/audits/large-javascript-libraries.js +166 -0
  9. package/lighthouse-core/audits/seo/http-status-code.js +6 -2
  10. package/lighthouse-core/audits/viewport.js +1 -2
  11. package/lighthouse-core/config/config-helpers.js +75 -9
  12. package/lighthouse-core/config/config.js +50 -6
  13. package/lighthouse-core/config/constants.js +0 -1
  14. package/lighthouse-core/config/default-config.js +0 -3
  15. package/lighthouse-core/config/experimental-config.js +8 -0
  16. package/lighthouse-core/config/metrics-to-audits.js +0 -1
  17. package/lighthouse-core/fraggle-rock/config/config.js +4 -3
  18. package/lighthouse-core/fraggle-rock/config/default-config.js +1 -3
  19. package/lighthouse-core/fraggle-rock/config/validation.js +0 -201
  20. package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +0 -4
  21. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +8 -16
  22. package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +0 -4
  23. package/lighthouse-core/fraggle-rock/gather/session.js +5 -30
  24. package/lighthouse-core/gather/driver/navigation.js +6 -7
  25. package/lighthouse-core/gather/driver/wait-for-condition.js +0 -27
  26. package/lighthouse-core/gather/fetcher.js +7 -17
  27. package/lighthouse-core/gather/gather-runner.js +0 -1
  28. package/lighthouse-core/gather/gatherers/seo/robots-txt.js +6 -2
  29. package/lighthouse-core/gather/gatherers/seo/tap-targets.js +2 -2
  30. package/lighthouse-core/gather/gatherers/stacks.js +1 -1
  31. package/lighthouse-core/lib/asset-saver.js +2 -2
  32. package/lighthouse-core/lib/cdt/SDK.js +0 -1
  33. package/lighthouse-core/lib/csp-evaluator.js +4 -17
  34. package/{report/generator → lighthouse-core/lib}/file-namer.js +0 -0
  35. package/lighthouse-core/lib/i18n/README.md +1 -1
  36. package/lighthouse-core/lib/i18n/i18n.js +7 -7
  37. package/lighthouse-core/lib/i18n/locales/ar-XB.json +18 -0
  38. package/lighthouse-core/lib/i18n/locales/ar.json +18 -0
  39. package/lighthouse-core/lib/i18n/locales/bg.json +18 -0
  40. package/lighthouse-core/lib/i18n/locales/ca.json +18 -0
  41. package/lighthouse-core/lib/i18n/locales/cs.json +18 -0
  42. package/lighthouse-core/lib/i18n/locales/da.json +18 -0
  43. package/lighthouse-core/lib/i18n/locales/de.json +18 -0
  44. package/lighthouse-core/lib/i18n/locales/el.json +18 -0
  45. package/lighthouse-core/lib/i18n/locales/en-GB.json +18 -0
  46. package/lighthouse-core/lib/i18n/locales/en-US.json +18 -18
  47. package/lighthouse-core/lib/i18n/locales/en-XA.json +18 -0
  48. package/lighthouse-core/lib/i18n/locales/en-XL.json +18 -18
  49. package/lighthouse-core/lib/i18n/locales/es-419.json +18 -0
  50. package/lighthouse-core/lib/i18n/locales/es.json +18 -0
  51. package/lighthouse-core/lib/i18n/locales/fi.json +18 -0
  52. package/lighthouse-core/lib/i18n/locales/fil.json +18 -0
  53. package/lighthouse-core/lib/i18n/locales/fr.json +18 -0
  54. package/lighthouse-core/lib/i18n/locales/he.json +18 -0
  55. package/lighthouse-core/lib/i18n/locales/hi.json +18 -0
  56. package/lighthouse-core/lib/i18n/locales/hr.json +18 -0
  57. package/lighthouse-core/lib/i18n/locales/hu.json +18 -0
  58. package/lighthouse-core/lib/i18n/locales/id.json +18 -0
  59. package/lighthouse-core/lib/i18n/locales/it.json +18 -0
  60. package/lighthouse-core/lib/i18n/locales/ja.json +18 -0
  61. package/lighthouse-core/lib/i18n/locales/ko.json +18 -0
  62. package/lighthouse-core/lib/i18n/locales/lt.json +18 -0
  63. package/lighthouse-core/lib/i18n/locales/lv.json +18 -0
  64. package/lighthouse-core/lib/i18n/locales/nl.json +18 -0
  65. package/lighthouse-core/lib/i18n/locales/no.json +18 -0
  66. package/lighthouse-core/lib/i18n/locales/pl.json +18 -0
  67. package/lighthouse-core/lib/i18n/locales/pt-PT.json +18 -0
  68. package/lighthouse-core/lib/i18n/locales/pt.json +18 -0
  69. package/lighthouse-core/lib/i18n/locales/ro.json +18 -0
  70. package/lighthouse-core/lib/i18n/locales/ru.json +18 -0
  71. package/lighthouse-core/lib/i18n/locales/sk.json +18 -0
  72. package/lighthouse-core/lib/i18n/locales/sl.json +18 -0
  73. package/lighthouse-core/lib/i18n/locales/sr-Latn.json +18 -0
  74. package/lighthouse-core/lib/i18n/locales/sr.json +18 -0
  75. package/lighthouse-core/lib/i18n/locales/sv.json +18 -0
  76. package/lighthouse-core/lib/i18n/locales/ta.json +18 -0
  77. package/lighthouse-core/lib/i18n/locales/te.json +18 -0
  78. package/lighthouse-core/lib/i18n/locales/th.json +18 -0
  79. package/lighthouse-core/lib/i18n/locales/tr.json +18 -0
  80. package/lighthouse-core/lib/i18n/locales/uk.json +18 -0
  81. package/lighthouse-core/lib/i18n/locales/vi.json +18 -0
  82. package/lighthouse-core/lib/i18n/locales/zh-HK.json +18 -0
  83. package/lighthouse-core/lib/i18n/locales/zh-TW.json +18 -0
  84. package/lighthouse-core/lib/i18n/locales/zh.json +18 -0
  85. package/lighthouse-core/lib/large-javascript-libraries/bundlephobia-database.json +62 -0
  86. package/lighthouse-core/lib/large-javascript-libraries/library-suggestions.js +20 -0
  87. package/lighthouse-core/lib/network-request.js +1 -3
  88. package/lighthouse-core/lib/traces/pwmetrics-events.js +2 -2
  89. package/lighthouse-core/lib/url-shim.js +1 -7
  90. package/lighthouse-core/runner.js +1 -4
  91. package/lighthouse-core/util-commonjs.js +2 -2
  92. package/now.json +1 -1
  93. package/package.json +13 -20
  94. package/report/README.md +2 -2
  95. package/report/assets/standalone-template.html +1 -0
  96. package/report/assets/styles.css +27 -23
  97. package/report/assets/templates.html +40 -37
  98. package/report/clients/bundle.js +0 -1
  99. package/report/{package.json → clients/package.json} +0 -0
  100. package/report/clients/psi.js +3 -13
  101. package/report/clients/standalone.js +1 -1
  102. package/report/{types/buffer.d.ts → clients/treemap.js} +13 -11
  103. package/report/renderer/category-renderer.js +2 -2
  104. package/report/renderer/components.js +48 -46
  105. package/report/renderer/crc-details-renderer.js +16 -16
  106. package/report/renderer/details-renderer.js +1 -1
  107. package/report/renderer/dom.js +0 -17
  108. package/report/renderer/element-screenshot-renderer.js +9 -9
  109. package/{flow-report/test/setup/global-setup.ts → report/renderer/file-namer.js} +2 -5
  110. package/report/renderer/logger.js +4 -4
  111. package/report/renderer/package.json +4 -0
  112. package/report/renderer/report-renderer.js +11 -4
  113. package/report/renderer/report-ui-features.js +656 -43
  114. package/report/renderer/text-encoding.js +1 -1
  115. package/report/renderer/util.js +2 -2
  116. package/report/{generator/report-assets.js → report-assets.js} +3 -9
  117. package/report/{generator/report-generator.js → report-generator.js} +9 -37
  118. package/report/test/clients/package.json +4 -0
  119. package/report/test/clients/psi-test.js +1 -3
  120. package/report/test/renderer/category-renderer-test.js +1 -2
  121. package/report/test/renderer/components-test.js +0 -35
  122. package/report/test/renderer/crc-details-renderer-test.js +4 -5
  123. package/report/test/renderer/details-renderer-test.js +1 -3
  124. package/report/test/renderer/dom-test.js +6 -8
  125. package/report/test/renderer/i18n-test.js +0 -1
  126. package/report/test/renderer/package.json +4 -0
  127. package/report/test/renderer/performance-category-renderer-test.js +2 -3
  128. package/report/test/renderer/pwa-category-renderer-test.js +1 -2
  129. package/report/test/renderer/report-renderer-test.js +0 -1
  130. package/report/test/renderer/report-ui-features-test.js +18 -20
  131. package/report/test/renderer/snippet-renderer-test.js +0 -1
  132. package/report/test/renderer/text-encoding-test.js +0 -2
  133. package/report/test/renderer/util-test.js +0 -1
  134. package/report/test/{generator/report-generator-test.js → report-generator-test.js} +2 -4
  135. package/third-party/chromium-synchronization/installability-errors-test.js +27 -28
  136. package/third-party/snyk/snapshot.json +0 -2
  137. package/tsconfig.json +5 -24
  138. package/types/artifacts.d.ts +18 -5
  139. package/types/{lhr/audit-details.d.ts → audit-details.d.ts} +3 -18
  140. package/types/audit.d.ts +58 -7
  141. package/types/{lhr/budget.d.ts → budget.d.ts} +0 -0
  142. package/types/bundle-phobia-cli/index.d.ts +40 -0
  143. package/types/config.d.ts +8 -3
  144. package/types/externs.d.ts +119 -5
  145. package/types/gatherer.d.ts +2 -3
  146. package/types/global-lh.d.ts +14 -16
  147. package/{report/types/report-result.d.ts → types/html-renderer.d.ts} +17 -8
  148. package/types/{lhr/i18n.d.ts → i18n.d.ts} +25 -2
  149. package/types/{lhr/lhr.d.ts → lhr.d.ts} +9 -41
  150. package/types/smokehouse.d.ts +3 -3
  151. package/types/{lhr/treemap.d.ts → treemap.d.ts} +3 -3
  152. package/flow-report/assets/standalone-flow-template.html +0 -38
  153. package/flow-report/assets/styles.css +0 -310
  154. package/flow-report/jest.config.js +0 -24
  155. package/flow-report/src/app.tsx +0 -40
  156. package/flow-report/src/common.tsx +0 -72
  157. package/flow-report/src/icons.tsx +0 -96
  158. package/flow-report/src/sidebar/flow.tsx +0 -72
  159. package/flow-report/src/sidebar/sidebar.tsx +0 -89
  160. package/flow-report/src/summary/summary.tsx +0 -178
  161. package/flow-report/src/util.ts +0 -160
  162. package/flow-report/src/wrappers/gauge.tsx +0 -40
  163. package/flow-report/src/wrappers/report-renderer.tsx +0 -46
  164. package/flow-report/src/wrappers/report.tsx +0 -71
  165. package/flow-report/standalone-flow.tsx +0 -23
  166. package/flow-report/test/app-test.tsx +0 -48
  167. package/flow-report/test/common-test.tsx +0 -131
  168. package/flow-report/test/setup/env-setup.ts +0 -25
  169. package/flow-report/test/sidebar/flow-test.tsx +0 -71
  170. package/flow-report/test/sidebar/sidebar-test.tsx +0 -53
  171. package/flow-report/test/summary/summary-test.tsx +0 -132
  172. package/flow-report/test/util-test.tsx +0 -109
  173. package/flow-report/tsconfig.json +0 -39
  174. package/flow-report/types/flow-report.d.ts +0 -27
  175. package/lighthouse-core/audits/lcp-lazy-loaded.js +0 -83
  176. package/report/.eslintrc.cjs +0 -33
  177. package/report/generator/README.md +0 -9
  178. package/report/generator/flow-report-assets.js +0 -20
  179. package/report/generator/package.json +0 -4
  180. package/report/generator/tsconfig.json +0 -28
  181. package/report/renderer/drop-down-menu.js +0 -215
  182. package/report/renderer/features-util.js +0 -26
  183. package/report/renderer/open-tab.js +0 -137
  184. package/report/renderer/topbar-features.js +0 -309
  185. package/report/test/generator/file-namer-test.js +0 -28
  186. package/report/test/generator/package.json +0 -4
  187. package/report/test-assets/faux-psi-template.html +0 -126
  188. package/report/test-assets/faux-psi.js +0 -92
  189. package/report/tsconfig.json +0 -39
  190. package/report/types/augment-dom.d.ts +0 -24
  191. package/report/types/html-renderer.d.ts +0 -28
  192. package/types/lhr/audit-result.d.ts +0 -59
  193. package/types/lhr/flow.d.ts +0 -16
  194. package/types/lhr/settings.d.ts +0 -105
  195. package/types/lhr/tsconfig.json +0 -24
  196. package/types/query-selector.d.ts +0 -36
@@ -1,309 +0,0 @@
1
- /**
2
- * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- */
6
- 'use strict';
7
-
8
- /* eslint-env browser */
9
-
10
- /** @typedef {import('./dom.js').DOM} DOM */
11
- /** @typedef {import('./report-ui-features').ReportUIFeatures} ReportUIFeatures */
12
-
13
- import {DropDownMenu} from './drop-down-menu.js';
14
- import {toggleDarkTheme} from './features-util.js';
15
- import {openViewer, openViewerAndSendData} from './open-tab.js';
16
-
17
- export class TopbarFeatures {
18
- /**
19
- * @param {ReportUIFeatures} reportUIFeatures
20
- * @param {DOM} dom
21
- */
22
- constructor(reportUIFeatures, dom) {
23
- /** @type {LH.Result} */
24
- this.lhr; // eslint-disable-line no-unused-expressions
25
- this._reportUIFeatures = reportUIFeatures;
26
- this._dom = dom;
27
- /** @type {Document} */
28
- this._document = this._dom.document();
29
- this._dropDownMenu = new DropDownMenu(this._dom);
30
- this._copyAttempt = false;
31
- /** @type {HTMLElement} */
32
- this.topbarEl; // eslint-disable-line no-unused-expressions
33
- /** @type {HTMLElement} */
34
- this.scoreScaleEl; // eslint-disable-line no-unused-expressions
35
- /** @type {HTMLElement} */
36
- this.stickyHeaderEl; // eslint-disable-line no-unused-expressions
37
- /** @type {HTMLElement} */
38
- this.highlightEl; // eslint-disable-line no-unused-expressions
39
- this.onDropDownMenuClick = this.onDropDownMenuClick.bind(this);
40
- this.onKeyUp = this.onKeyUp.bind(this);
41
- this.onCopy = this.onCopy.bind(this);
42
- this.collapseAllDetails = this.collapseAllDetails.bind(this);
43
- this._updateStickyHeaderOnScroll = this._updateStickyHeaderOnScroll.bind(this);
44
- }
45
-
46
- /**
47
- * @param {LH.Result} lhr
48
- */
49
- enable(lhr) {
50
- this.lhr = lhr;
51
- this._document.addEventListener('keyup', this.onKeyUp);
52
- this._document.addEventListener('copy', this.onCopy);
53
- this._dropDownMenu.setup(this.onDropDownMenuClick);
54
- this._setUpCollapseDetailsAfterPrinting();
55
-
56
- const topbarLogo = this._dom.find('.lh-topbar__logo', this._document);
57
- topbarLogo.addEventListener('click', () => toggleDarkTheme(this._dom));
58
-
59
- // There is only a sticky header when at least 2 categories are present.
60
- if (Object.keys(this.lhr.categories).length >= 2) {
61
- this._setupStickyHeaderElements();
62
- const containerEl = this._dom.find('.lh-container', this._document);
63
- const elToAddScrollListener = this._getScrollParent(containerEl);
64
- elToAddScrollListener.addEventListener('scroll', this._updateStickyHeaderOnScroll);
65
-
66
- // Use ResizeObserver where available.
67
- // TODO: there is an issue with incorrect position numbers and, as a result, performance
68
- // issues due to layout thrashing.
69
- // See https://github.com/GoogleChrome/lighthouse/pull/9023/files#r288822287 for details.
70
- // For now, limit to DevTools.
71
- if (this._dom.isDevTools()) {
72
- const resizeObserver = new window.ResizeObserver(this._updateStickyHeaderOnScroll);
73
- resizeObserver.observe(containerEl);
74
- } else {
75
- window.addEventListener('resize', this._updateStickyHeaderOnScroll);
76
- }
77
- }
78
- }
79
-
80
- /**
81
- * Handler for tool button.
82
- * @param {Event} e
83
- */
84
- onDropDownMenuClick(e) {
85
- e.preventDefault();
86
-
87
- const el = /** @type {?Element} */ (e.target);
88
-
89
- if (!el || !el.hasAttribute('data-action')) {
90
- return;
91
- }
92
-
93
- switch (el.getAttribute('data-action')) {
94
- case 'copy':
95
- this.onCopyButtonClick();
96
- break;
97
- case 'print-summary':
98
- this.collapseAllDetails();
99
- this._print();
100
- break;
101
- case 'print-expanded':
102
- this.expandAllDetails();
103
- this._print();
104
- break;
105
- case 'save-json': {
106
- const jsonStr = JSON.stringify(this.lhr, null, 2);
107
- this._reportUIFeatures._saveFile(new Blob([jsonStr], {type: 'application/json'}));
108
- break;
109
- }
110
- case 'save-html': {
111
- const htmlStr = this._reportUIFeatures.getReportHtml();
112
- try {
113
- this._reportUIFeatures._saveFile(new Blob([htmlStr], {type: 'text/html'}));
114
- } catch (e) {
115
- this._dom.fireEventOn('lh-log', this._document, {
116
- cmd: 'error', msg: 'Could not export as HTML. ' + e.message,
117
- });
118
- }
119
- break;
120
- }
121
- case 'open-viewer': {
122
- // DevTools cannot send data with postMessage, and we only want to use the URL fragment
123
- // approach for viewer when needed, so check the environment and choose accordingly.
124
- if (this._dom.isDevTools()) {
125
- openViewer(this.lhr);
126
- } else {
127
- openViewerAndSendData(this.lhr);
128
- }
129
- break;
130
- }
131
- case 'save-gist': {
132
- this._reportUIFeatures.saveAsGist();
133
- break;
134
- }
135
- case 'toggle-dark': {
136
- toggleDarkTheme(this._dom);
137
- break;
138
- }
139
- }
140
-
141
- this._dropDownMenu.close();
142
- }
143
-
144
- /**
145
- * Handle copy events.
146
- * @param {ClipboardEvent} e
147
- */
148
- onCopy(e) {
149
- // Only handle copy button presses (e.g. ignore the user copying page text).
150
- if (this._copyAttempt && e.clipboardData) {
151
- // We want to write our own data to the clipboard, not the user's text selection.
152
- e.preventDefault();
153
- e.clipboardData.setData('text/plain', JSON.stringify(this.lhr, null, 2));
154
-
155
- this._dom.fireEventOn('lh-log', this._document, {
156
- cmd: 'log', msg: 'Report JSON copied to clipboard',
157
- });
158
- }
159
-
160
- this._copyAttempt = false;
161
- }
162
-
163
- /**
164
- * Copies the report JSON to the clipboard (if supported by the browser).
165
- */
166
- onCopyButtonClick() {
167
- this._dom.fireEventOn('lh-analytics', this._document, {
168
- cmd: 'send',
169
- fields: {hitType: 'event', eventCategory: 'report', eventAction: 'copy'},
170
- });
171
-
172
- try {
173
- if (this._document.queryCommandSupported('copy')) {
174
- this._copyAttempt = true;
175
-
176
- // Note: In Safari 10.0.1, execCommand('copy') returns true if there's
177
- // a valid text selection on the page. See http://caniuse.com/#feat=clipboard.
178
- if (!this._document.execCommand('copy')) {
179
- this._copyAttempt = false; // Prevent event handler from seeing this as a copy attempt.
180
-
181
- this._dom.fireEventOn('lh-log', this._document, {
182
- cmd: 'warn', msg: 'Your browser does not support copy to clipboard.',
183
- });
184
- }
185
- }
186
- } catch (e) {
187
- this._copyAttempt = false;
188
- this._dom.fireEventOn('lh-log', this._document, {cmd: 'log', msg: e.message});
189
- }
190
- }
191
-
192
- /**
193
- * Keyup handler for the document.
194
- * @param {KeyboardEvent} e
195
- */
196
- onKeyUp(e) {
197
- // Ctrl+P - Expands audit details when user prints via keyboard shortcut.
198
- if ((e.ctrlKey || e.metaKey) && e.keyCode === 80) {
199
- this._dropDownMenu.close();
200
- }
201
- }
202
-
203
- /**
204
- * Expands all audit `<details>`.
205
- * Ideally, a print stylesheet could take care of this, but CSS has no way to
206
- * open a `<details>` element.
207
- */
208
- expandAllDetails() {
209
- const details = this._dom.findAll('.lh-categories details', this._document);
210
- details.map(detail => detail.open = true);
211
- }
212
-
213
- /**
214
- * Collapses all audit `<details>`.
215
- * open a `<details>` element.
216
- */
217
- collapseAllDetails() {
218
- const details = this._dom.findAll('.lh-categories details', this._document);
219
- details.map(detail => detail.open = false);
220
- }
221
-
222
- _print() {
223
- self.print();
224
- }
225
-
226
- /**
227
- * Resets the state of page before capturing the page for export.
228
- * When the user opens the exported HTML page, certain UI elements should
229
- * be in their closed state (not opened) and the templates should be unstamped.
230
- */
231
- resetUIState() {
232
- this._dropDownMenu.close();
233
- }
234
-
235
- /**
236
- * Finds the first scrollable ancestor of `element`. Falls back to the document.
237
- * @param {Element} element
238
- * @return {Node}
239
- */
240
- _getScrollParent(element) {
241
- const {overflowY} = window.getComputedStyle(element);
242
- const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden';
243
-
244
- if (isScrollable) {
245
- return element;
246
- }
247
-
248
- if (element.parentElement) {
249
- return this._getScrollParent(element.parentElement);
250
- }
251
-
252
- return document;
253
- }
254
-
255
- /**
256
- * Sets up listeners to collapse audit `<details>` when the user closes the
257
- * print dialog, all `<details>` are collapsed.
258
- */
259
- _setUpCollapseDetailsAfterPrinting() {
260
- // FF and IE implement these old events.
261
- if ('onbeforeprint' in self) {
262
- self.addEventListener('afterprint', this.collapseAllDetails);
263
- } else {
264
- // Note: FF implements both window.onbeforeprint and media listeners. However,
265
- // it doesn't matchMedia doesn't fire when matching 'print'.
266
- self.matchMedia('print').addListener(mql => {
267
- if (mql.matches) {
268
- this.expandAllDetails();
269
- } else {
270
- this.collapseAllDetails();
271
- }
272
- });
273
- }
274
- }
275
-
276
- _setupStickyHeaderElements() {
277
- this.topbarEl = this._dom.find('div.lh-topbar', this._document);
278
- this.scoreScaleEl = this._dom.find('div.lh-scorescale', this._document);
279
- this.stickyHeaderEl = this._dom.find('div.lh-sticky-header', this._document);
280
-
281
- // Highlighter will be absolutely positioned at first gauge, then transformed on scroll.
282
- this.highlightEl = this._dom.createChildOf(this.stickyHeaderEl, 'div', 'lh-highlighter');
283
- }
284
-
285
- _updateStickyHeaderOnScroll() {
286
- // Show sticky header when the score scale begins to go underneath the topbar.
287
- const topbarBottom = this.topbarEl.getBoundingClientRect().bottom;
288
- const scoreScaleTop = this.scoreScaleEl.getBoundingClientRect().top;
289
- const showStickyHeader = topbarBottom >= scoreScaleTop;
290
-
291
- // Highlight mini gauge when section is in view.
292
- // In view = the last category that starts above the middle of the window.
293
- const categoryEls = Array.from(this._document.querySelectorAll('.lh-category'));
294
- const categoriesAboveTheMiddle =
295
- categoryEls.filter(el => el.getBoundingClientRect().top - window.innerHeight / 2 < 0);
296
- const highlightIndex =
297
- categoriesAboveTheMiddle.length > 0 ? categoriesAboveTheMiddle.length - 1 : 0;
298
-
299
- // Category order matches gauge order in sticky header.
300
- const gaugeWrapperEls = this.stickyHeaderEl.querySelectorAll('.lh-gauge__wrapper');
301
- const gaugeToHighlight = gaugeWrapperEls[highlightIndex];
302
- const origin = gaugeWrapperEls[0].getBoundingClientRect().left;
303
- const offset = gaugeToHighlight.getBoundingClientRect().left - origin;
304
-
305
- // Mutate at end to avoid layout thrashing.
306
- this.highlightEl.style.transform = `translate(${offset}px)`;
307
- this.stickyHeaderEl.classList.toggle('lh-sticky-header--visible', showStickyHeader);
308
- }
309
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * @license Copyright 2017 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- */
6
- 'use strict';
7
-
8
- const assert = require('assert').strict;
9
-
10
- const getFilenamePrefix = require('../../generator/file-namer.js').getFilenamePrefix;
11
-
12
- /* eslint-env jest */
13
- describe('file-namer helper', () => {
14
- it('generates filename prefixes', () => {
15
- const results = {
16
- finalUrl: 'https://testexample.com',
17
- fetchTime: '2017-01-06T02:34:56.217Z',
18
- };
19
- const str = getFilenamePrefix(results);
20
- // we want the filename to match user timezone, however these tests will run on multiple TZs
21
- assert.ok(str.startsWith('testexample.com'), 'hostname is missing');
22
- assert.ok(str.includes('2017-'), 'full year is missing');
23
- assert.ok(str.endsWith('-56'), 'seconds value is not at the end');
24
- // regex of hostname_YYYY-MM-DD_HH-MM-SS
25
- const regex = /testexample\.com_\d{4}-[0-1][[0-9]-[0-1][[0-9]_[0-2][0-9]-[0-5][0-9]-[0-5][0-9]/;
26
- assert.ok(regex.test(str), `${str} doesn't match pattern: hostname_YYYY-MM-DD_HH-MM-SS`);
27
- });
28
- });
@@ -1,4 +0,0 @@
1
- {
2
- "type": "commonjs",
3
- "//": "Preserve commonjs in this directory. Temporary file until converted to type: module"
4
- }
@@ -1,126 +0,0 @@
1
- <!--
2
- * Copyright 2021 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- -->
6
-
7
- <!--
8
- This fake psi page is intended to reproduce the experience of rendering two LHRs within the same DOM,
9
- like in PageSpeed Insights. This helps surface the peculiar behavior around tabs,
10
- expectations of unique IDs, and scoped report containment.
11
- -->
12
-
13
- <!doctype html>
14
- <html lang="en">
15
- <head>
16
- <meta charset="utf-8">
17
- <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
18
- <title>Faux PageSpeed Report</title>
19
- <style>/*%%LIGHTHOUSE_CSS%%*/</style>
20
-
21
- <style>
22
- /* Inspired by https://codepen.io/markcaron/pen/MvGRYV?editors=1100 but improved. s*/
23
- /*
24
- The tab visibility basics
25
- */
26
- .tabset > input[type="radio"] {
27
- position: absolute;
28
- left: -200vw;
29
- }
30
-
31
- .tabset .tab-panel {
32
- display: none;
33
- }
34
-
35
- .tabset > input:nth-of-type(1):checked ~ .tab-panels > .tab-panel:nth-of-type(1),
36
- .tabset > input:nth-of-type(2):checked ~ .tab-panels > .tab-panel:nth-of-type(2) {
37
- display: block;
38
- }
39
-
40
- /*
41
- Purdy tabs
42
- */
43
- .tabset > label {
44
- position: relative;
45
- display: inline-block;
46
- padding: 15px 55px 15px;
47
- border: 1px solid transparent;
48
- border-bottom: 0;
49
- cursor: pointer;
50
- font-weight: 600;
51
- }
52
-
53
- .tabset > label:hover {
54
- background-color: hsl(0deg 0% 100% / 24%);
55
- }
56
-
57
- .tabset > label:hover,
58
- .tabset > input:focus + label {
59
- color: #06c;
60
- }
61
-
62
- .tabset > input:checked + label {
63
- border-color: #ccc;
64
- border-bottom: 1px solid #fff;
65
- margin-bottom: -1px;
66
- background: white;
67
- }
68
-
69
- .tab-panel {
70
- padding: 30px 0;
71
- border-top: 1px solid #ccc;
72
- }
73
-
74
- body {
75
- padding: 30px;
76
- }
77
-
78
- .tabset {
79
- max-width: 65em;
80
- background: #eee;
81
- }
82
-
83
- .tab-panels {
84
- background: white;
85
- }
86
-
87
- /* extra styles */
88
- body {
89
- background: hsl(217deg 89% 61%);
90
- }
91
- </style>
92
- </head>
93
- <body >
94
- <noscript>PSI requires JavaScript. Please enable.</noscript>
95
-
96
- <div class="element-screenshots-container"></div>
97
-
98
-
99
- <div class="tabset lh-vars lh-root">
100
-
101
- <input type="radio" name="tabset" id="tab1" aria-controls="mobile" checked>
102
- <label for="tab1">Mobile</label>
103
-
104
- <input type="radio" name="tabset" id="tab2" aria-controls="desktop">
105
- <label for="tab2">Desktop</label>
106
-
107
- <div class="tab-panels">
108
- <section id="mobile" class="tab-panel">
109
- <main></main>
110
- </section>
111
-
112
- <section id="desktop" class="tab-panel">
113
- <main></main>
114
- </section>
115
-
116
- </div>
117
- </div>
118
-
119
- <script>window.__LIGHTHOUSE_JSON__ = %%LIGHTHOUSE_JSON%%;</script>
120
- <script type="module">
121
- %%LIGHTHOUSE_JAVASCRIPT%%
122
- //# sourceURL=psi-reportrenderer.js
123
- </script>
124
- <script>console.log('window.__LIGHTHOUSE_JSON__', __LIGHTHOUSE_JSON__);</script>
125
- </body>
126
- </html>
@@ -1,92 +0,0 @@
1
- /**
2
- * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- */
6
- 'use strict';
7
-
8
- /** @fileoverview This file is a glorified call of prepareLabData. */
9
-
10
- /** @typedef {import('../clients/psi.js').PrepareLabDataResult} PrepareLabDataResult */
11
-
12
- (async function __initPsiReports__() {
13
- // @ts-expect-error
14
- const mobileLHR = window.__LIGHTHOUSE_JSON__;
15
- const desktopLHR = JSON.parse(JSON.stringify(mobileLHR));
16
-
17
- const lhrs = {
18
- 'mobile': mobileLHR,
19
- 'desktop': desktopLHR,
20
- };
21
-
22
- for (const [tabId, lhr] of Object.entries(lhrs)) {
23
- await distinguishLHR(lhr, tabId);
24
-
25
- // @ts-expect-error
26
- const pldd = /** @type {PrepareLabDataResult} */ (window.prepareLabData(lhr, document));
27
- const {scoreGaugeEl, perfCategoryEl,
28
- finalScreenshotDataUri, scoreScaleEl, installFeatures} = pldd;
29
-
30
- const container = document.querySelector(`#${tabId} main`);
31
- if (!container) throw new Error('Unexpected DOM. Bailing.');
32
- container.append(scoreGaugeEl);
33
- container.append(scoreScaleEl);
34
- if (finalScreenshotDataUri) {
35
- const imgEl = document.createElement('img');
36
- imgEl.src = finalScreenshotDataUri;
37
- container.append(imgEl);
38
- }
39
- container.append(perfCategoryEl);
40
- installFeatures(container);
41
- }
42
- })();
43
-
44
-
45
- /**
46
- * Tweak the LHR to make the desktop and mobile reports easier to identify.
47
- * Adjusted: Perf category name and score, and emoji placed on top of key screenshots.
48
- * @param {LH.Result} lhr
49
- * @param {string} tabId
50
- */
51
- async function distinguishLHR(lhr, tabId) {
52
- lhr.categories.performance.title += ` ${tabId}`; // for easier identification
53
- if (tabId === 'desktop') {
54
- lhr.categories.performance.score = 0.81;
55
- }
56
-
57
- const finalSSDetails = lhr.audits['final-screenshot'] && lhr.audits['final-screenshot'].details;
58
- if (!finalSSDetails || finalSSDetails.type !== 'screenshot') throw new Error();
59
- finalSSDetails.data = await decorateScreenshot(finalSSDetails.data, tabId);
60
-
61
- const fpSSDetails = lhr.audits['full-page-screenshot'] &&
62
- lhr.audits['full-page-screenshot'].details;
63
- if (!fpSSDetails || fpSSDetails.type !== 'full-page-screenshot') throw new Error();
64
- fpSSDetails.screenshot.data = await decorateScreenshot(fpSSDetails.screenshot.data, tabId);
65
- }
66
-
67
- /**
68
- * Add 📱 and 💻 emoji on top of screenshot
69
- * @param {string} datauri
70
- * @param {string} tabId
71
- */
72
- async function decorateScreenshot(datauri, tabId) {
73
- const img = document.createElement('img');
74
-
75
- await new Promise((resolve, reject) => {
76
- img.addEventListener('load', () => resolve(img));
77
- img.addEventListener('error', (err) => reject(err));
78
- img.src = datauri;
79
- });
80
- const c = document.createElement('canvas');
81
- c.width = img.width;
82
- c.height = img.height;
83
-
84
- const ctx = c.getContext('2d');
85
- if (!ctx) throw new Error();
86
- ctx.drawImage(img, 0, 0);
87
- ctx.font = `${img.width / 2}px serif`;
88
- ctx.textAlign = 'center';
89
- ctx.globalAlpha = 0.7;
90
- ctx.fillText(tabId === 'mobile' ? '📱' : '💻', img.width / 2, Math.min(img.height / 2, 700));
91
- return c.toDataURL();
92
- }
@@ -1,39 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "composite": true,
4
- "outDir": "../.tmp/tsbuildinfo/report",
5
- "emitDeclarationOnly": true,
6
- "declarationMap": true,
7
-
8
- // Limit to base JS and DOM defs.
9
- "lib": ["es2020", "dom", "dom.iterable"],
10
- // Don't include any types from node_modules.
11
- "types": [],
12
- "target": "es2020",
13
- "module": "es2020",
14
- "moduleResolution": "node",
15
-
16
- "allowJs": true,
17
- "checkJs": true,
18
- "strict": true,
19
- // TODO: remove the next line to be fully `strict`.
20
- "useUnknownInCatchVariables": false,
21
-
22
- // "listFiles": true,
23
- // "noErrorTruncation": true,
24
- "extendedDiagnostics": true,
25
- },
26
- "include": [
27
- "**/*.js",
28
- "types/**/*.d.ts",
29
- ],
30
- "references": [
31
- {"path": "../types/lhr/"},
32
- {"path": "./generator/"}
33
- ],
34
- "exclude": [
35
- "generator/**/*.js",
36
- // These test files require further changes before they can be type checked.
37
- "test/**/*.js",
38
- ],
39
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- */
6
-
7
- /**
8
- * @fileoverview Augment global scope with needed DOM APIs that are newer or not
9
- * widely supported enough to be in tsc's lib `dom`.
10
- */
11
-
12
- // Import to augment querySelector/querySelectorAll with stricter type checking.
13
- import '../../types/query-selector';
14
-
15
- declare global {
16
- var CompressionStream: {
17
- prototype: CompressionStream,
18
- new (format: string): CompressionStream,
19
- };
20
-
21
- interface CompressionStream extends GenericTransformStream {
22
- readonly format: string;
23
- }
24
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
3
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
- */
6
-
7
- import AuditDetails from '../../types/lhr/audit-details';
8
- import {FormattedIcu as FormattedIcu_} from '../../types/lhr/i18n';
9
- import LHResult from '../../types/lhr/lhr';
10
- import ReportResult_ from './report-result';
11
- import * as Settings from '../../types/lhr/settings';
12
- import Treemap_ from '../../types/lhr/treemap';
13
-
14
- declare global {
15
- // Expose global types in LH namespace.
16
- module LH {
17
- export import Result = LHResult;
18
- export import ReportResult = ReportResult_;
19
- export import Locale = Settings.Locale;
20
- export type FormattedIcu<T> = FormattedIcu_<T>;
21
-
22
- module Audit {
23
- export import Details = AuditDetails;
24
- }
25
-
26
- export import Treemap = Treemap_;
27
- }
28
- }