Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report: treemap opener, ?dev for localhost viewer and treemap #11667

Merged
merged 11 commits into from
Nov 17, 2020
67 changes: 53 additions & 14 deletions lighthouse-core/report/html/renderer/report-ui-features.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ function getTableRows(tableEl) {
return Array.from(tableEl.tBodies[0].rows);
}

function getAppsOrigin() {
const isVercel = window.location.host.endsWith('.vercel.app');
const isDev = new URLSearchParams(window.location.search).has('dev');

if (isVercel) return `https://${window.location.host}/gh-pages`;
if (isDev) return 'http://localhost:8000';
return 'https://googlechrome.github.io/lighthouse';
}

class ReportUIFeatures {
/**
* @param {DOM} dom
Expand Down Expand Up @@ -457,8 +466,7 @@ class ReportUIFeatures {
break;
}
case 'open-viewer': {
const viewerPath = '/lighthouse/viewer/';
ReportUIFeatures.openTabAndSendJsonReport(this.json, viewerPath);
ReportUIFeatures.openTabAndSendJsonReportToViewer(this.json);
break;
}
case 'save-gist': {
Expand Down Expand Up @@ -492,33 +500,64 @@ class ReportUIFeatures {
/**
* Opens a new tab to the online viewer and sends the local page's JSON results
* to the online viewer using postMessage.
* @param {LH.Result} reportJson
* @param {string} viewerPath
* @param {LH.Result} json
* @protected
*/
static openTabAndSendJsonReport(reportJson, viewerPath) {
const VIEWER_ORIGIN = 'https://googlechrome.github.io';
static openTabAndSendJsonReportToViewer(json) {
// The popup's window.name is keyed by version+url+fetchTime, so we reuse/select tabs correctly
// @ts-ignore - If this is a v2 LHR, use old `generatedTime`.
const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
const fetchTime = json.fetchTime || fallbackFetchTime;
const windowName = `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
const url = getAppsOrigin() + '/viewer/';
ReportUIFeatures.openTabAndSendData({lhr: json}, url, windowName);
}

/**
* Opens a new tab to the treemap app and sends the JSON results using postMessage.
* @param {LH.Result} json
*/
static openTreemap(json) {
const treemapDebugData = /** @type {LH.Audit.Details.DebugData} */ (
json.audits['script-treemap-data'].details);
connorjclark marked this conversation as resolved.
Show resolved Hide resolved
if (!treemapDebugData) {
throw new Error('no script treemap data found');
}

const windowName = `treemap-${json.requestedUrl}`;
/** @type {LH.Treemap.Options} */
const treemapOptions = {
lhr: json,
};
const url = getAppsOrigin() + '/treemap/';
ReportUIFeatures.openTabAndSendData(treemapOptions, url, windowName);
}

/**
* Opens a new tab to an external page and sends data using postMessage.
* @param {{lhr: LH.Result} | LH.Treemap.Options} data
* @param {string} url
* @param {string} windowName
* @protected
*/
static openTabAndSendData(data, url, windowName) {
const origin = new URL(url).origin;
// Chrome doesn't allow us to immediately postMessage to a popup right
// after it's created. Normally, we could also listen for the popup window's
// load event, however it is cross-domain and won't fire. Instead, listen
// for a message from the target app saying "I'm open".
const json = reportJson;
window.addEventListener('message', function msgHandler(messageEvent) {
if (messageEvent.origin !== VIEWER_ORIGIN) {
if (messageEvent.origin !== origin) {
return;
}
if (popup && messageEvent.data.opened) {
popup.postMessage({lhresults: json}, VIEWER_ORIGIN);
popup.postMessage(data, origin);
window.removeEventListener('message', msgHandler);
}
});

// The popup's window.name is keyed by version+url+fetchTime, so we reuse/select tabs correctly
// @ts-expect-error - If this is a v2 LHR, use old `generatedTime`.
const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
const fetchTime = json.fetchTime || fallbackFetchTime;
const windowName = `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
const popup = window.open(`${VIEWER_ORIGIN}${viewerPath}`, windowName);
const popup = window.open(url, windowName);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions lighthouse-core/report/html/report-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
// is in the document.
const features = new ReportUIFeatures(dom);
features.initFeatures(window.__LIGHTHOUSE_JSON__);

// No UI for treemap yet. For now, must run this command in console.
globalThis._tmpFeatures = features;
const command = 'ReportUIFeatures.openTreemap(_tmpFeatures.json);';
console.log(`For treemap viewer, run: ${command}`);
}
window.addEventListener('DOMContentLoaded', __initLighthouseReport__);

Expand Down
4 changes: 2 additions & 2 deletions lighthouse-viewer/app/src/lighthouse-report-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ class LighthouseReportViewer {
*/
_listenForMessages() {
window.addEventListener('message', e => {
if (e.source === self.opener && e.data.lhresults) {
this._replaceReportHtml(e.data.lhresults);
if (e.source === self.opener && (e.data.lhr || e.data.lhresults)) {
this._replaceReportHtml(e.data.lhr || e.data.lhresults);

if (self.opener && !self.opener.closed) {
self.opener.postMessage({rendered: true}, '*');
Expand Down