From 9a49a607acc4cc082a4ccc94ea9ae3ba898b6c09 Mon Sep 17 00:00:00 2001 From: Adam Raine Date: Wed, 13 Oct 2021 14:24:26 -0400 Subject: [PATCH 01/19] start --- build/build-viewer.js | 10 +++++ .../assets/standalone-flow-template.html | 1 - flow-report/render-flow.js | 17 ++++++++ flow-report/src/app.tsx | 2 + flow-report/src/wrappers/report-renderer.tsx | 4 +- flow-report/src/wrappers/styles.tsx | 26 +++++++++++++ lighthouse-viewer/app/index.html | 2 +- .../app/src/lighthouse-report-viewer.js | 37 ++++++++++++++++-- lighthouse-viewer/tsconfig.json | 3 +- lighthouse-viewer/types/viewer.d.ts | 2 + package.json | 1 + report/generator/report-generator.js | 1 - report/renderer/report-renderer.js | 11 +++++- yarn.lock | 39 ++++++++++++++++--- 14 files changed, 139 insertions(+), 17 deletions(-) create mode 100644 flow-report/render-flow.js create mode 100644 flow-report/src/wrappers/styles.tsx diff --git a/build/build-viewer.js b/build/build-viewer.js index 28ecaa1bb15b..5a94b264f57c 100644 --- a/build/build-viewer.js +++ b/build/build-viewer.js @@ -45,11 +45,21 @@ async function run() { html: {path: 'index.html'}, stylesheets: [ {path: 'styles/*'}, + {path: '../../flow-report/assets/styles.css'}, ], javascripts: [ await generatorJsPromise, {path: require.resolve('pako/dist/pako_inflate.js')}, {path: 'src/main.js', rollup: true, rollupPlugins: [ + rollupPlugins.typescript({ + tsconfig: 'flow-report/tsconfig.json', + // Plugin struggles with custom outDir, so revert it from tsconfig value + // as well as any options that require an outDir is set. + outDir: null, + composite: false, + emitDeclarationOnly: false, + declarationMap: false, + }), rollupPlugins.replace({ // Default delimiters are word boundraries. Setting them to nothing (empty strings) // makes this plugin replace any subtring found. diff --git a/flow-report/assets/standalone-flow-template.html b/flow-report/assets/standalone-flow-template.html index 7b72f95fc9b1..b8d7d6df0365 100644 --- a/flow-report/assets/standalone-flow-template.html +++ b/flow-report/assets/standalone-flow-template.html @@ -21,7 +21,6 @@ Lighthouse Flow Report - diff --git a/flow-report/render-flow.js b/flow-report/render-flow.js new file mode 100644 index 000000000000..b5ad5b622ba6 --- /dev/null +++ b/flow-report/render-flow.js @@ -0,0 +1,17 @@ +/** + * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved. + * 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 + * 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. + */ + +import {render, h} from 'preact'; + +import {App} from './src/app'; + +/** + * @param {LH.FlowResult} flowResult + * @param {HTMLElement} container + */ +export default function renderFlow(flowResult, container) { + render(h(App, {flowResult}), container); +} diff --git a/flow-report/src/app.tsx b/flow-report/src/app.tsx index 280caadc540f..66c690be7008 100644 --- a/flow-report/src/app.tsx +++ b/flow-report/src/app.tsx @@ -15,6 +15,7 @@ import {Report} from './wrappers/report'; import {Topbar} from './topbar'; import {Header} from './header'; import {I18nProvider} from './i18n/i18n'; +import {Styles} from './wrappers/styles'; const Content: FunctionComponent = () => { const currentLhr = useCurrentLhr(); @@ -54,6 +55,7 @@ export const App: FunctionComponent<{flowResult: LH.FlowResult}> = ({flowResult} +
setCollapsed(c => !c)} /> diff --git a/flow-report/src/wrappers/report-renderer.tsx b/flow-report/src/wrappers/report-renderer.tsx index 63a60e961d37..08fb939fcdcd 100644 --- a/flow-report/src/wrappers/report-renderer.tsx +++ b/flow-report/src/wrappers/report-renderer.tsx @@ -32,7 +32,9 @@ export const ReportRendererProvider: FunctionComponent = ({children}) => { const dom = new DOM(document); const detailsRenderer = new DetailsRenderer(dom); const categoryRenderer = new CategoryRenderer(dom, detailsRenderer); - const reportRenderer = new ReportRenderer(dom); + const reportRenderer = new ReportRenderer(dom, { + disableGlobalStyles: true, + }); return { dom, detailsRenderer, diff --git a/flow-report/src/wrappers/styles.tsx b/flow-report/src/wrappers/styles.tsx new file mode 100644 index 000000000000..f3bf565a1028 --- /dev/null +++ b/flow-report/src/wrappers/styles.tsx @@ -0,0 +1,26 @@ +/** + * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved. + * 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 + * 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. + */ + +import {FunctionComponent} from 'preact'; +import {useLayoutEffect, useRef} from 'preact/hooks'; + +import {useReportRenderer} from './report-renderer'; + +export const Styles: FunctionComponent = () => { + const ref = useRef(null); + const {dom} = useReportRenderer(); + + useLayoutEffect(() => { + if (!ref.current) return; + const styles = dom.createComponent('styles'); + ref.current.appendChild(styles); + return () => { + if (ref.current) ref.current.innerHTML = ''; + }; + }, []); + + return
; +}; diff --git a/lighthouse-viewer/app/index.html b/lighthouse-viewer/app/index.html index 3cf83009ad3f..2bdfaa8f2beb 100644 --- a/lighthouse-viewer/app/index.html +++ b/lighthouse-viewer/app/index.html @@ -16,7 +16,7 @@ - +
diff --git a/lighthouse-viewer/app/src/lighthouse-report-viewer.js b/lighthouse-viewer/app/src/lighthouse-report-viewer.js index 1c94f3eea1e6..27228a1d79ed 100644 --- a/lighthouse-viewer/app/src/lighthouse-report-viewer.js +++ b/lighthouse-viewer/app/src/lighthouse-report-viewer.js @@ -14,6 +14,7 @@ import {ViewerUIFeatures} from './viewer-ui-features.js'; import {DOM} from '../../../report/renderer/dom.js'; import {ReportRenderer} from '../../../report/renderer/report-renderer.js'; import {TextEncoding} from '../../../report/renderer/text-encoding.js'; +import renderFlow from '../../../flow-report/render-flow.js'; /* global logger */ @@ -189,13 +190,18 @@ export class LighthouseReportViewer { } } + /** + * @param {LH.Result | LH.FlowResult} json + * @return {json is LH.FlowResult} + */ + _isFlowReport(json) { + return 'steps' in json && Array.isArray(json.steps); + } + /** * @param {LH.Result} json - * @private */ - // TODO: Really, `json` should really have type `unknown` and - // we can have _validateReportJson verify that it's an LH.Result - _replaceReportHtml(json) { + _renderLhr(json) { // Allow users to view the runnerResult if ('lhr' in json) { const runnerResult = /** @type {{lhr: LH.Result}} */ (/** @type {unknown} */ (json)); @@ -254,6 +260,29 @@ export class LighthouseReportViewer { } finally { this._reportIsFromGist = this._reportIsFromPSI = this._reportIsFromJSON = false; } + } + + /** + * @param {LH.FlowResult} json + */ + _renderFlowResult(json) { + const container = find('main', document); + renderFlow(json, container); + } + + /** + * @param {LH.Result | LH.FlowResult} json + * @private + */ + // TODO: Really, `json` should really have type `unknown` and + // we can have _validateReportJson verify that it's an LH.Result + _replaceReportHtml(json) { + if (this._isFlowReport(json)) { + this._renderFlowResult(json); + } else { + console.log('######'); + this._renderLhr(json); + } // Remove the placeholder UI once the user has loaded a report. const placeholder = document.querySelector('.viewer-placeholder'); diff --git a/lighthouse-viewer/tsconfig.json b/lighthouse-viewer/tsconfig.json index 926844a0d556..ad5fb6bca75b 100644 --- a/lighthouse-viewer/tsconfig.json +++ b/lighthouse-viewer/tsconfig.json @@ -10,7 +10,8 @@ }, "references": [ {"path": "../types/lhr/"}, - {"path": "../report/"} + {"path": "../report/"}, + {"path": "../flow-report/"} ], "include": [ "app/src/**/*.js", diff --git a/lighthouse-viewer/types/viewer.d.ts b/lighthouse-viewer/types/viewer.d.ts index 45255d5e8137..8618b3adfcf1 100644 --- a/lighthouse-viewer/types/viewer.d.ts +++ b/lighthouse-viewer/types/viewer.d.ts @@ -15,6 +15,8 @@ import '../../report/types/augment-dom'; // Import for LH globals needed for report files. import '../../report/types/html-renderer'; +import '../../flow-report/types/flow-report'; + declare global { var ReportGenerator: typeof _ReportGenerator; var logger: _Logger; diff --git a/package.json b/package.json index 2ac8a4ae8ba0..394b9647b065 100644 --- a/package.json +++ b/package.json @@ -174,6 +174,7 @@ "tabulator-tables": "^4.9.3", "terser": "^5.3.8", "ts-jest": "^27.0.4", + "tsify": "^5.0.4", "typed-query-selector": "^2.4.0", "typescript": "4.4.3", "wait-for-expect": "^3.0.2", diff --git a/report/generator/report-generator.js b/report/generator/report-generator.js index ee5bff09709a..ae6737648095 100644 --- a/report/generator/report-generator.js +++ b/report/generator/report-generator.js @@ -70,7 +70,6 @@ class ReportGenerator { {search: '%%LIGHTHOUSE_FLOW_JSON%%', replacement: sanitizedJson}, {search: '%%LIGHTHOUSE_FLOW_JAVASCRIPT%%', replacement: htmlReportAssets.FLOW_REPORT_JAVASCRIPT}, {search: '/*%%LIGHTHOUSE_FLOW_CSS%%*/', replacement: htmlReportAssets.FLOW_REPORT_CSS}, - {search: '/*%%LIGHTHOUSE_CSS%%*/', replacement: htmlReportAssets.REPORT_CSS}, /* eslint-enable max-len */ ]); } diff --git a/report/renderer/report-renderer.js b/report/renderer/report-renderer.js index 1282d11af2a2..579f389f2c55 100644 --- a/report/renderer/report-renderer.js +++ b/report/renderer/report-renderer.js @@ -20,6 +20,7 @@ 'use strict'; /** @typedef {import('./dom.js').DOM} DOM */ +/** @typedef {{disableGlobalStyles?: boolean}} Options */ import {CategoryRenderer} from './category-renderer.js'; import {DetailsRenderer} from './details-renderer.js'; @@ -29,11 +30,15 @@ import {PerformanceCategoryRenderer} from './performance-category-renderer.js'; import {PwaCategoryRenderer} from './pwa-category-renderer.js'; import {Util} from './util.js'; + export class ReportRenderer { /** * @param {DOM} dom + * @param {Options=} options */ - constructor(dom) { + constructor(dom, options) { + /** @type {Options|undefined} */ + this.options = options; /** @type {DOM} */ this._dom = dom; } @@ -276,7 +281,9 @@ export class ReportRenderer { } const reportFragment = this._dom.createFragment(); - reportFragment.append(this._dom.createComponent('styles')); + if (!this.options || !this.options.disableGlobalStyles) { + reportFragment.append(this._dom.createComponent('styles')); + } const topbarDocumentFragment = this._renderReportTopbar(report); reportFragment.appendChild(topbarDocumentFragment); diff --git a/yarn.lock b/yarn.lock index 5edfc820dca8..598bb24c6ad1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1974,6 +1974,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +any-promise@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + anymatch@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -8188,7 +8193,7 @@ semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -8673,16 +8678,16 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" +strip-json-comments@^2.0.0, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - strip-outer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" @@ -9035,6 +9040,28 @@ tsconfig-paths@^3.11.0: minimist "^1.2.0" strip-bom "^3.0.0" +tsconfig@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-5.0.3.tgz#5f4278e701800967a8fc383fd19648878f2a6e3a" + integrity sha1-X0J45wGACWeo/Dg/0ZZIh48qbjo= + dependencies: + any-promise "^1.3.0" + parse-json "^2.2.0" + strip-bom "^2.0.0" + strip-json-comments "^2.0.0" + +tsify@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/tsify/-/tsify-5.0.4.tgz#22163648d04c0c90bdb15704fb14947df2328547" + integrity sha512-XAZtQ5OMPsJFclkZ9xMZWkSNyMhMxEPsz3D2zu79yoKorH9j/DT4xCloJeXk5+cDhosEibu4bseMVjyPOAyLJA== + dependencies: + convert-source-map "^1.1.0" + fs.realpath "^1.0.0" + object-assign "^4.1.0" + semver "^6.1.0" + through2 "^2.0.0" + tsconfig "^5.0.3" + tslib@^1.8.1: version "1.9.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" From 6f168fb3490889c020d4bf7de472e84a2195883c Mon Sep 17 00:00:00 2001 From: Adam Raine Date: Thu, 18 Nov 2021 15:21:56 -0500 Subject: [PATCH 02/19] rm consloe --- viewer/app/src/lighthouse-report-viewer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/viewer/app/src/lighthouse-report-viewer.js b/viewer/app/src/lighthouse-report-viewer.js index f43348cc3fc3..4d5d02114c77 100644 --- a/viewer/app/src/lighthouse-report-viewer.js +++ b/viewer/app/src/lighthouse-report-viewer.js @@ -281,7 +281,6 @@ export class LighthouseReportViewer { if (this._isFlowReport(json)) { this._renderFlowResult(json); } else { - console.log('######'); this._renderLhr(json); } From 80d1431b804ab7a24fb5bfe0c0c7d77e7631e611 Mon Sep 17 00:00:00 2001 From: Adam Raine Date: Thu, 18 Nov 2021 15:31:53 -0500 Subject: [PATCH 03/19] api --- flow-report/{render-flow.js => api.js} | 2 +- viewer/app/src/lighthouse-report-viewer.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename flow-report/{render-flow.js => api.js} (92%) diff --git a/flow-report/render-flow.js b/flow-report/api.js similarity index 92% rename from flow-report/render-flow.js rename to flow-report/api.js index b5ad5b622ba6..ec54aa4c79be 100644 --- a/flow-report/render-flow.js +++ b/flow-report/api.js @@ -12,6 +12,6 @@ import {App} from './src/app'; * @param {LH.FlowResult} flowResult * @param {HTMLElement} container */ -export default function renderFlow(flowResult, container) { +export function renderFlowReport(flowResult, container) { render(h(App, {flowResult}), container); } diff --git a/viewer/app/src/lighthouse-report-viewer.js b/viewer/app/src/lighthouse-report-viewer.js index 4d5d02114c77..5381a29f4650 100644 --- a/viewer/app/src/lighthouse-report-viewer.js +++ b/viewer/app/src/lighthouse-report-viewer.js @@ -14,7 +14,7 @@ import {ViewerUIFeatures} from './viewer-ui-features.js'; import {DOM} from '../../../report/renderer/dom.js'; import {ReportRenderer} from '../../../report/renderer/report-renderer.js'; import {TextEncoding} from '../../../report/renderer/text-encoding.js'; -import renderFlow from '../../../flow-report/render-flow.js'; +import {renderFlowReport} from '../../../flow-report/api.js'; /* global logger */ @@ -268,7 +268,7 @@ export class LighthouseReportViewer { */ _renderFlowResult(json) { const container = find('main', document); - renderFlow(json, container); + renderFlowReport(json, container); } /** From 031a7b245e9d47bbb2fe61325bed0e1361328258 Mon Sep 17 00:00:00 2001 From: Adam Raine Date: Thu, 18 Nov 2021 20:53:38 -0500 Subject: [PATCH 04/19] yeet --- build/gh-pages-app.js | 1 + viewer/app/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build/gh-pages-app.js b/build/gh-pages-app.js index fd0de19b7305..9bbc459f7806 100644 --- a/build/gh-pages-app.js +++ b/build/gh-pages-app.js @@ -153,6 +153,7 @@ class GhPagesApp { ]; if (!process.env.DEBUG) plugins.push(rollupPlugins.terser()); const bundle = await rollup.rollup({ + preserveEntrySignatures: 'strict', input, plugins, }); diff --git a/viewer/app/index.html b/viewer/app/index.html index b8a058f625c7..29015bb1ed33 100644 --- a/viewer/app/index.html +++ b/viewer/app/index.html @@ -43,7 +43,7 @@

Lighthouse Report Viewer

- +