-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
misc(treemap): initialize app structure #11635
Changes from all commits
f8518de
535422b
6390fd1
a48402a
d2ca505
59be9d0
61efa44
3a14210
eadd41e
29f9fa0
bef0523
a44f9c9
b5a8141
d3432a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* @license Copyright 2020 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. | ||
*/ | ||
'use strict'; | ||
|
||
const fs = require('fs'); | ||
const GhPagesApp = require('./gh-pages-app.js'); | ||
|
||
/** | ||
* Build treemap app, optionally deploying to gh-pages if `--deploy` flag was set. | ||
*/ | ||
async function run() { | ||
const app = new GhPagesApp({ | ||
name: 'treemap', | ||
appDir: `${__dirname}/../lighthouse-treemap/app`, | ||
html: {path: 'index.html'}, | ||
stylesheets: [ | ||
{path: 'styles/*'}, | ||
], | ||
javascripts: [ | ||
fs.readFileSync(require.resolve('webtreemap-cdt'), 'utf8'), | ||
{path: 'src/*'}, | ||
], | ||
assets: [ | ||
{path: 'debug.json'}, | ||
], | ||
}); | ||
|
||
await app.build(); | ||
|
||
const argv = process.argv.slice(2); | ||
if (argv.includes('--deploy')) { | ||
await app.deploy(); | ||
} | ||
} | ||
|
||
run(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Lighthouse Treemap Viewer | ||
|
||
## Development | ||
|
||
```sh | ||
yarn serve-treemap | ||
|
||
# in separate terminal, start build watch | ||
# dependency: `brew install entr` | ||
find lighthouse-treemap | entr -s 'DEBUG=1 yarn build-treemap' | ||
open http://localhost:8000/treemap/?debug | ||
``` |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!-- | ||
Copyright 2020 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. | ||
--> | ||
|
||
<!doctype html> | ||
<html> | ||
|
||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"> | ||
<title>Lighthouse Treemap</title> | ||
<link rel="icon" | ||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEhklEQVR4AWJxL/BhIAesev1U5tcflpncgNrKIsqNIwzC9feMpDUzs70kOczMzMzJJcxwCTMzncPMnOwtzBwzMzPb0vRfeZPp0VhPS5I39V5fdiXV1/VD+9QC7OVn9BsyH1XIoEI1PfmJvLFowVV564+34DFUHudbmfDh4kVXh//7XwE+WjS/YfXZe3yr4j2rqj1AIhSB7hZ8ZtPZu/zw8cK523U4wE1/rvPfWrz4zs0m9ZdC9yUJAlASdBAgocRegfF/f3/h/PuaFsxMdwjAR0vm1+06eMMfIrhLqTWqdH4EumU2SPfMhigJAlRQbZrgrRsl9U+Y2DYDFCz3ILC9kiAiqSrMwbWT0nceEnR+9Kggc2zjOJCASDENkg0a5HfZZgDP81CM3CrQs2Z1+o7DJ6ePr8sK0AOCHv5Jjdt3evyYSaZ351VIStIxPRAUtrBYbxC6w+BZ0ivVSBKkIhJhemSyZpfB00EiPO2VjzYkxhcqXQqCWCShGplvi3y0QxqbuBurMjyJeWnkHZuAEgIQGsUBqwrfjZ+IlBgKyRJzVVYF8O6qFWdh86YzQzMrZigYmxAyfvHgLZQ/LC1CbeniW2Hkqr/PH16SgvGuf2/uzNMBwJA/njxizGPtSyAf7EziJCMGRDRdhoAC4PL1A/SrKQMAAQkEfpJAcRQdrBJ7gNwjSpJsdwK+CANBkqa1LgQB4IicV9nYUct7gaxuDJUErQIiEAiMxLVOFlKzIktPpT0ggpdpC/8YAHnxbgkUY4tAAFSR7AAXNyAAWHJrA/kHGjzg5nleuwFO7Nd/IoDw4Pm58+4jNLmYG0wRA5bErc2Mr3Y+dXTDW1VvwqbJkzMCHQ4S1GTCBOIgUHJrGdEwqzR+jAp/o2qAZelUDoQnruEEdDclJI6576AlNVfc+22XN/+Y1vnJD0Yind6UpEEvn/Hqq15EYjCW7jZCJEpnNvDgkyelDjs106kuux2AAXCSobULOWP8mLhYlpoDMK4qAFXJGk+grtH8YXVz5KJblqaG1+VUdTc0I290bmUQAriGITRbdQnom0aoFj8kx1+wMD2ifncAXUQE4SkDqN1hE0jEophs1SUwZAOhUAiMCLwRtamtTZtbbmZErSAUHbSysaoEmnrsakiMiUAURi283gN6wans9oX8rOCrj7/JP35DFD+iQ7Au/K2KE1jzx6ujjUnXFH9KjEq6ZlhsTBICrNLJf47Pv/pkHzvup1w4dmUbEei0+bcXRqJuh5kVARQ8byyYxOwNGr7A87xh1tp8sGT+uMInrwi++Xj7TQz2d27NvwEkrOflAFQGIDA5khASBCGdO2/Z/MnLPwYfv5TFhjW7QhVKAB6afwe2LpFlFsCnlQEosgQgDsdOG1/LKeNqJS4JCSPJ/i+TakwEARor7gER1Iva5JmPOJK0RUqmoPnnlzFCtmIAhAAQEIQRgDaiYPIauNXcnDlRIrWNFY3hm7PG9YRqr7IV7HrCgAC17befjEvRq2nGhAHtBqDpOuI/I1diUUAMYIxEdyejBJqLnNoszGZtfiX/CztGv2mq+sdaAAAAAElFTkSuQmCC"> | ||
<meta name="theme-color" content="#304ffe"> | ||
<link rel="stylesheet" href="styles/bundled.css"> | ||
</head> | ||
|
||
<body> | ||
<main> | ||
<!-- Inject LHR here. --> | ||
</main> | ||
|
||
<script src="src/bundled.js"></script> | ||
|
||
<!-- Google Analytics --> | ||
<script> | ||
(function (i, s, o, g, r, a, m) { | ||
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () { | ||
(i[r].q = i[r].q || []).push(arguments) | ||
}, i[r].l = 1 * new Date(); a = s.createElement(o), | ||
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m) | ||
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga'); | ||
|
||
ga('create', 'UA-85519014-2', 'auto'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this the same analytics account as the viewer? I guess that's what we want when served over same domain anyway There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ya |
||
ga('send', 'pageview'); | ||
</script> | ||
</body> | ||
|
||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* @license Copyright 2020 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. | ||
*/ | ||
'use strict'; | ||
|
||
/* eslint-env browser */ | ||
|
||
/* globals webtreemap TreemapUtil */ | ||
|
||
/** | ||
* Allows for saving the document and loading with data intact. | ||
* @param {LH.Treemap.Options} options | ||
*/ | ||
function injectOptions(options) { | ||
if (window.__treemapOptions) return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. definitely fits now, so not worth discussing much, but can I reserve the right to object to |
||
|
||
const scriptEl = document.createElement('script'); | ||
scriptEl.textContent = ` | ||
window.__treemapOptions = ${JSON.stringify(options)}; | ||
`; | ||
document.head.append(scriptEl); | ||
} | ||
|
||
/** | ||
* @param {LH.Treemap.Options} options | ||
*/ | ||
function init(options) { | ||
// ==== temporary | ||
TreemapUtil.find('main').textContent = JSON.stringify(options.lhr); | ||
// eslint-disable-next-line no-console | ||
console.log({webtreemap}); | ||
// ==== temporary | ||
|
||
injectOptions(options); | ||
|
||
// eslint-disable-next-line no-console | ||
console.log('window.__treemapOptions', window.__treemapOptions); | ||
} | ||
|
||
/** | ||
* @param {string} message | ||
*/ | ||
function showError(message) { | ||
document.body.textContent = message; | ||
} | ||
|
||
async function main() { | ||
if (window.__treemapOptions) { | ||
// Prefer the hardcoded options from a saved HTML file above all. | ||
init(window.__treemapOptions); | ||
} else if (new URLSearchParams(window.location.search).has('debug')) { | ||
const response = await fetch('debug.json'); | ||
init(await response.json()); | ||
} else { | ||
window.addEventListener('message', e => { | ||
if (e.source !== self.opener) return; | ||
|
||
/** @type {LH.Treemap.Options} */ | ||
const options = e.data; | ||
const {lhr} = options; | ||
if (!lhr) return showError('Error: Invalid options'); | ||
|
||
const documentUrl = lhr.requestedUrl; | ||
if (!documentUrl) return showError('Error: Invalid options'); | ||
|
||
init(options); | ||
}); | ||
} | ||
|
||
// If the page was opened as a popup, tell the opening window we're ready. | ||
if (self.opener && !self.opener.closed) { | ||
self.opener.postMessage({opened: true}, '*'); | ||
} | ||
} | ||
|
||
document.addEventListener('DOMContentLoaded', main); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* @license Copyright 2020 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. | ||
*/ | ||
'use strict'; | ||
|
||
/* eslint-env browser */ | ||
|
||
/** @typedef {HTMLElementTagNameMap & {[id: string]: HTMLElement}} HTMLElementByTagName */ | ||
|
||
class TreemapUtil { | ||
/** | ||
* @template {string} T | ||
* @param {T} name | ||
* @param {string=} className | ||
* @param {Object<string, (string|undefined)>=} attrs Attribute key/val pairs. | ||
* Note: if an attribute key has an undefined value, this method does not | ||
* set the attribute on the node. | ||
* @return {HTMLElementByTagName[T]} | ||
*/ | ||
static createElement(name, className, attrs = {}) { | ||
patrickhulce marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const element = document.createElement(name); | ||
if (className) { | ||
element.className = className; | ||
} | ||
Object.keys(attrs).forEach(key => { | ||
const value = attrs[key]; | ||
if (typeof value !== 'undefined') { | ||
element.setAttribute(key, value); | ||
} | ||
}); | ||
return element; | ||
} | ||
|
||
/** | ||
* @template {string} T | ||
* @param {Element} parentElem | ||
* @param {T} elementName | ||
* @param {string=} className | ||
* @param {Object<string, (string|undefined)>=} attrs Attribute key/val pairs. | ||
* Note: if an attribute key has an undefined value, this method does not | ||
* set the attribute on the node. | ||
* @return {HTMLElementByTagName[T]} | ||
*/ | ||
static createChildOf(parentElem, elementName, className, attrs) { | ||
const element = this.createElement(elementName, className, attrs); | ||
parentElem.appendChild(element); | ||
return element; | ||
} | ||
|
||
/** | ||
* Guaranteed context.querySelector. Always returns an element or throws if | ||
* nothing matches query. | ||
* @param {string} query | ||
* @param {ParentNode=} context | ||
* @return {HTMLElement} | ||
*/ | ||
static find(query, context = document) { | ||
/** @type {?HTMLElement} */ | ||
const result = context.querySelector(query); | ||
if (result === null) { | ||
throw new Error(`query ${query} not found`); | ||
} | ||
return result; | ||
} | ||
} | ||
|
||
// node export for testing. | ||
if (typeof module !== 'undefined' && module.exports) { | ||
module.exports = TreemapUtil; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* @license Copyright 2020 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. | ||
*/ | ||
|
||
body { | ||
margin: 0; | ||
overflow-y: hidden; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment here that summarizes what's happening could be helpful if it's not too much trouble. Personally, at first glance this bit threw me for a loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is meant-to-be-unreadable code for google analytics :) it's what they give to you for copy/paste.