split off from wabac.js:

- add pageembeds.js for now
- new webpack build, use /sw.js in prod, /dist/sw.js in dev to work with webpack-dev-server single directory
- add wombat dependency and webpack build
This commit is contained in:
Ilya Kreymer
2020-05-02 11:27:48 -07:00
parent 47108dc7d8
commit e023726fd2
15 changed files with 6323 additions and 2 deletions
+9
View File
@@ -0,0 +1,9 @@
*.har
*.warc
*.warc.gz
!examples/*.warc
dist/sw.js
**/node_modules
yarn-error.log
coverage/
.DS_Store
+3
View File
File diff suppressed because one or more lines are too long
+555
View File
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
<!doctype html>
<html class="no-overflow">
<head>
<script src="./dist/frontend.js"></script>
<link href="./dist/frontend.css" rel="stylesheet"/>
</head>
<body>
<app-main></app-main>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
import './src/frontend';
+34
View File
@@ -0,0 +1,34 @@
{
"name": "replaywebpage",
"version": "1.0.0",
"description": "Serverless Web Archive Replay",
"main": "index.js",
"repository": "https://github.com/webrecorder/replayweb.page",
"author": "Ilya Kreymer <ikreymer@gmail.com>",
"license": "AGPL3",
"dependencies": {
"@fortawesome/fontawesome-free": "^5.13.0",
"bulma": "^0.8.2",
"lit-element": "^2.3.1",
"marked": "^1.0.0",
"pretty-bytes": "^5.3.0",
"wabac": "link:../serviceworker/",
"wombat": "github:https://github.com/webrecorder/wombat"
},
"devDependencies": {
"css-loader": "^3.5.3",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.2.1",
"svg-inline-loader": "^0.8.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"scripts": {
"build": "webpack --mode production",
"build-dev": "webpack --mode development",
"start-dev": "webpack-dev-server --mode development"
}
}
+84
View File
@@ -0,0 +1,84 @@
@charset "utf-8";
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap');
$wr-green: #64e986;
$wr-yellow: #f5c71a;
$wr-light-blue: #43daff;
$wr-med-blue: #27a0ff;
$wr-dark-blue: #4876ff;
$wr-accent: #1b0921;
$primary: $wr-green;
$info: $wr-yellow;
$link: $wr-dark-blue;
$light: $wr-light-blue;
$dark: $wr-accent;
/*$navbar-height: 3.75rem;*/
html {
scroll-behavior: smooth;
overflow-y: hidden;
}
/*
@font-face {
font-family: 'SourceSansPro';
src: url('../static/SourceSansPro-Regular.ttf');
}
*/
.font-ssp {
font-family: 'Source Code Pro', monospace;
}
.font-ssp-c {
font-family: 'Source Code Pro', monospace;
letter-spacing: -1.5px;
}
html.no-overflow {
overflow-y: hidden;
}
.page-desc {
font-weight: initial;
font-size: initial;
margin-top: 10px;
}
progress:after {
content: attr(data-percent)'%';
position: absolute;
-webkit-transform: translate(-50%, -100%);
-ms-transform: translate(-50%, -100%);
transform: translateX(-50%, -100%);
font-size: calc(1.5rem / 1.5);
line-height: 1.5rem;
}
.sticky {
position: sticky;
top: 30px;
left: 0px;
}
.main-scroll {
flex: 1;
scroll-behavior: smooth;
overflow-y: auto;
max-height: 100vh;
height: 100%;
display: flex;
flex-direction: column;
overflow-x: hidden;
}
@import "../node_modules/bulma/bulma";
+2 -2
View File
@@ -136,7 +136,7 @@ class WrLoader extends LitElement
this.state = "waiting";
this.loadInfo = null;
this.worker = new Worker("./dist/dbworker.js");
this.worker = new Worker(__SW_PATH__);
}
static get properties() {
@@ -1350,7 +1350,7 @@ class WrFaIcon extends LitElement
// ===========================================================================
async function main() {
const swPromise = initSW("./swonly.js?replayPrefix=wabac&stats=true");
const swPromise = initSW(__SW_PATH__ + "?replayPrefix=wabac&stats=true");
await swPromise;
customElements.define("app-main", AppMain);
customElements.define("wr-index", WrIndex);
+118
View File
@@ -0,0 +1,118 @@
async function digestMessage(message, hashtype) {
const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
const hashBuffer = await crypto.subtle.digest(hashtype, msgUint8); // hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
return hashHex;
}
function waitForReady() {
return new Promise((resolve) => {
window.addEventListener("load", () => {
resolve();
});
if (document.readyState === 'complete') {
resolve();
}
});
}
function initSW(relUrl = 'sw.js?replayPrefix=wabac&stats=true', path) {
const loc = window.location;
console.log(`Register SW: ${relUrl}`);
if (!navigator.serviceWorker) {
let msg = null;
if (loc.protocol === "http:") {
msg = 'Service workers only supported when loading via https://, but this site loaded from: ' + loc.origin;
} else {
msg = 'Sorry, Service workers are not supported in this browser'
}
return Promise.reject(msg);
}
// Register SW in current path scope (if not '/' use curr directory)
if (!path) {
path = loc.origin + loc.pathname;
} else {
path = new URL(path, window.location.href).href;
}
if (!path.endsWith("/")) {
path = path.slice(0, path.lastIndexOf("/") + 1);
}
let url = new URL(relUrl, path);
if (navigator.serviceWorker.controller && navigator.serviceWorker.controller.scriptURL === url) {
return Promise.resolve(false);
}
let done = false;
let resolve, reject;
const pr = new Promise((res, rej) => {
resolve = (e) => { done = true; res(e); };
reject = (e) => { done = true; rej(e); };
});
window.fetch(url, { "mode": "cors" }).then(resp => {
if (!resp.url.startsWith(path)) {
reject("Service Worker in wrong scope!")
}
return resp.url;
}).then((swUrl) => {
navigator.serviceWorker.addEventListener('error', e => reject(null));
setTimeout(() => {
if (!done) {
reject('Service Worker is not available');
}
}, 30000);
return navigator.serviceWorker.register(swUrl, { scope: path });
}).then((registration) => {
console.log('Service worker registration succeeded:', registration);
if (navigator.serviceWorker.controller) {
resolve(true);
}
navigator.serviceWorker.addEventListener('controllerchange', e => resolve(true));
}).catch((error) => {
console.log('Service worker registration failed:', error);
reject(error);
});
return pr;
}
function tsToDate(ts) {
if (!ts) {
return "";
}
if (ts.length < 14) {
ts += "00000000000000".substr(ts.length);
}
const datestr = (ts.substring(0, 4) + "-" +
ts.substring(4, 6) + "-" +
ts.substring(6, 8) + "T" +
ts.substring(8, 10) + ":" +
ts.substring(10, 12) + ":" +
ts.substring(12, 14) + "-00:00");
return new Date(datestr);
};
function getTS(iso) {
return iso.replace(/[-:T]/g, '').slice(0, 14);
}
export { initSW, waitForReady, digestMessage, tsToDate, getTS };
+15
View File
@@ -0,0 +1,15 @@
"use strict";
// Inited as Web Worker
if (self.postMessage) {
const { WorkerLoader } = require('wabac/src/loaders');
const loader = new WorkerLoader(self);
console.log('ww init');
} else {
// Service Worker Init
const { SWReplay } = require('wabac/src/swmain.js');
self.sw = new SWReplay();
console.log('sw init');
}
+144
View File
@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="logoonly.svg"
inkscape:version="1.0rc1 (09960d6, 2020-04-09)"
id="svg403"
version="1.1"
viewBox="0 0 66.712425 66.712425"
height="66.712425mm"
width="66.712425mm">
<defs
id="defs397">
<linearGradient
id="linearGradient5691"
inkscape:collect="always">
<stop
id="stop5687"
offset="0"
style="stop-color:#4876ff;stop-opacity:1" />
<stop
id="stop5689"
offset="1"
style="stop-color:#04cdff;stop-opacity:1" />
</linearGradient>
<linearGradient
y2="48.223869"
x2="97.913383"
y1="48.223869"
x1="2.9740067"
gradientTransform="matrix(1.2909748,0,0,1.2909748,126.71149,146.96477)"
gradientUnits="userSpaceOnUse"
id="linearGradient444"
xlink:href="#linearGradient5691"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
inkscape:window-maximized="0"
inkscape:window-y="23"
inkscape:window-x="0"
inkscape:window-height="786"
inkscape:window-width="1252"
showgrid="false"
inkscape:document-rotation="0"
inkscape:current-layer="layer1"
inkscape:document-units="mm"
inkscape:cy="520.33335"
inkscape:cx="353.00073"
inkscape:zoom="0.35"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base" />
<metadata
id="metadata400">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-12.435223,-10.495135)"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<g
transform="matrix(0.54430533,0,0,0.54430533,-56.88484,-71.599319)"
id="use356">
<g
id="g440">
<circle
transform="rotate(0.86915877)"
inkscape:transform-center-y="2.8413144"
inkscape:transform-center-x="-2.7634129"
r="61.282173"
cy="209.22058"
cx="191.83304"
id="circle430"
style="fill:url(#linearGradient444);fill-opacity:1;stroke:none;stroke-width:42.9582;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
<path
style="fill:#f5c71a;fill-opacity:1;stroke-width:1.29097"
d="m 213.97635,227.49063 h 10.04864 c 7.00225,0 12.69803,-5.69578 12.69803,-12.69802 0,-7.00225 -5.69578,-12.69803 -12.69803,-12.69803 h -28.65835 c -7.00224,0 -12.69802,5.69578 -12.69802,12.69803 0,3.61344 1.52335,6.86798 3.95295,9.1827 -1.52592,1.02374 -3.35394,1.62921 -5.32526,1.62921 h -3.82517 c -1.91579,-3.1603 -3.04024,-6.85378 -3.04024,-10.81191 0,-11.5439 9.39185,-20.93574 20.93574,-20.93574 h 28.65835 c 11.5439,0 20.93445,9.39054 20.93445,20.93574 0,11.54519 -9.39218,21.12976 -20.93445,20.93573 L 214,236 v -4 z"
id="path432"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssscscsssssccc" />
<path
style="fill:#64e986;fill-opacity:1;stroke-width:1.29097"
d="m 163,202 -8.98973,0.0946 c -7.00187,0.0737 -12.69803,5.69578 -12.69803,12.69932 0,7.00095 5.69577,12.69673 12.69803,12.69673 h 28.65835 c 7.00224,0 12.69802,-5.69578 12.69802,-12.69673 0,-3.61344 -1.52335,-6.86928 -3.95296,-9.18399 1.52593,-1.02375 3.35394,-1.62793 5.32527,-1.62793 h 3.82258 c 1.91709,3.15902 3.04153,6.85249 3.04153,10.81192 0,11.5426 -9.39054,20.93444 -20.93444,20.93444 h -28.65835 c -11.54261,0 -20.93575,-9.39054 -20.93575,-20.93444 0,-11.54519 9.39331,-21.1208 20.93575,-20.93703 L 163,194 v 4 z"
id="path434"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssscscsssssccc" />
<path
sodipodi:type="star"
style="fill:#64e986;fill-opacity:1;stroke:none;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
id="path436"
sodipodi:sides="3"
sodipodi:cx="66.525429"
sodipodi:cy="34.639832"
sodipodi:r1="14.518896"
sodipodi:r2="7.2594481"
sodipodi:arg1="1.0516502"
sodipodi:arg2="2.0988478"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 73.728819,47.245763 -10.861072,-6.335289 -10.86107,-6.33529 10.917057,-6.238319 10.917057,-6.238318 -0.05599,12.573609 z"
inkscape:transform-center-x="-1.9610825"
inkscape:transform-center-y="0.018337839"
transform="matrix(-0.70292103,0,0,0.73238527,212.74337,173.39159)" />
<path
sodipodi:type="star"
style="fill:#f5c71a;fill-opacity:1;stroke:none;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
id="path438"
sodipodi:sides="3"
sodipodi:cx="66.525429"
sodipodi:cy="34.639832"
sodipodi:r1="14.518896"
sodipodi:r2="7.2594481"
sodipodi:arg1="1.0516502"
sodipodi:arg2="2.0988478"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 73.728819,47.245763 -10.861072,-6.335289 -10.86107,-6.33529 10.917057,-6.238319 10.917057,-6.238318 -0.05599,12.573609 z"
inkscape:transform-center-x="2.1128909"
inkscape:transform-center-y="-0.01877307"
transform="matrix(0.75733451,0,0,-0.74979977,161.4911,257.29221)" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

+1
View File
File diff suppressed because one or more lines are too long
+24
View File
File diff suppressed because one or more lines are too long
+72
View File
@@ -0,0 +1,72 @@
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = (env, argv) => {
return {
mode: 'production',
entry: {
'frontend': './src/frontend.js',
'sw': './src/sw.js',
'wombat': 'wombat/src/wbWombat.js',
},
output: {
path: path.join(__dirname, 'dist'),
filename: (chunkData) => {
switch (chunkData.chunk.name) {
case 'sw':
return argv.mode === 'production' ? '../[name].js': '[name].js';
case 'wombat':
return '../static/[name].js';
case 'frontend':
default:
return '[name].js';
}
},
libraryTarget: 'self',
globalObject: 'self',
publicPath: '/dist/'
},
devServer: {
compress: true,
port: 9990,
headers: {'Service-Worker-Allowed': '/'},
open: false,
publicPath: '/dist/'
},
plugins: [
new MiniCssExtractPlugin(),
new webpack.DefinePlugin({
__SW_PATH__: JSON.stringify(argv.mode === 'production' ? './sw.js' : './dist/sw.js')
}),
],
module: {
rules: [{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
// Prefer `dart-sass`
implementation: require('node-sass'),
},
},
],
},
{
test: /\.svg$/,
loader: 'svg-inline-loader'
}]
}
}
}
+5249
View File
File diff suppressed because it is too large Load Diff