Test of resource embedding. Fixes for color and recipe

This commit is contained in:
Nicholas Jitkoff 2022-10-19 21:47:36 -07:00
parent 0c3bdf1ae3
commit a109a22d5a
9 changed files with 224 additions and 34 deletions

27
build-v2.js Executable file
View file

@ -0,0 +1,27 @@
#! node
const { execSync } = require("child_process");
const fs = require('fs');
function embedInlines(src, dest) {
try {
let data = fs.readFileSync(src, 'utf8');
data = data.replace(/src="\/?(.*)" inline>/g, (g, h) => {
return `>` + execSync(`terser ${h}`)
})
data = data.replace(/<link rel="stylesheet" href="\/?(.*)" inline>/g, (g, h) => {
console.log(h);
return `<style>${execSync(`uglifycss ${h}`)}</style>`
})
console.log(data);
fs.writeFileSync(dest,data)
} catch (err) {
console.error(err);
}
}
process.chdir("docs");
embedInlines('index.html', 'index.min.html')
process.chdir("render");
embedInlines('recipe.html', 'recipe.min.html')

View file

@ -161,7 +161,7 @@ async function testCompression(rawData) {
async function compressData(data, encoding = GZIP_MARKER, callback) {
console.debug("Compressing with", encoding)
if (encoding == GZIP_MARKER) {
return import("/js/gzip/pako.js").then((module) => {
return import("/js/gzip/pako.min.js").then((module) => {
return pako.deflate(data, {level:"9"});
});
} else if (encoding == BROT_MARKER) {
@ -188,9 +188,36 @@ function byteArrayToString(bytes) {
return String.fromCharCode.apply(null, new Uint8Array(bytes));
}
function browserDecompressData(data) {
const cs = new DecompressionStream("gzip");
const writer = cs.writable.getWriter();
writer.write(data);
writer.close();
return new Response(cs.readable).arrayBuffer().then(function (arrayBuffer) {
return new TextDecoder().decode(arrayBuffer);
});
// const stream = new Response(data).body.pipeThrough(new DecompressionStream('gzip'));
// return (new Response(stream).arrayBuffer());
// var blob = new Blob([data], {type: "octet/stream"});
// const ds = new DecompressionStream("gzip");
// const decompressedStream = blob.stream().pipeThrough(ds);
// data = await new Response(decompressedStream).arrayBuffer();
// console.log(blob, data);
// console.log(blob, data);
// return data
}
async function decompressData(data, encoding, callback) {
if (encoding == GZIP_MARKER) {
return import("/js/gzip/pako.js").then((module) => {
// return await browserDecompressData(data);
return import("/js/gzip/pako.min.js").then((module) => {
let byteArray = pako.inflate(data);
return byteArray;
});

View file

@ -4,15 +4,15 @@
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, viewport-fit=cover">
<meta name="description" content="itty bitty things can be conveyed in a link.">
<link id="favicon" rel="icon" href='/favicon.svg'>
<link rel="stylesheet" href="/index.css">
<link id="favicon" rel="icon" href="/favicon.svg">
<link rel="stylesheet" href="/index.css" inline>
<meta id="themeColor" name="theme-color" content="white" media="(prefers-color-scheme: light)">
<meta id="themeColorDark" name="theme-color" content="#121212" media="(prefers-color-scheme: dark)">
<!-- <link rel="manifest" href="/manifest.json"> -->
<script src="/js/lzma/lzma-d-min.js"></script>
<script src="/bitty.js" type="module"></script>
<script src="/index.js" type="module"></script>
<script src="/js/gzip/pako.js" type="module"></script>
<script type="module" src="/bitty.js" inline></script>
<script type="module" src="/index.js" inline></script>
<script type="module" src="/js/gzip/pako.min.js" ></script>
<script nomodule> location.href = "/v1/" + location.hash </script>
<noscript>itty.bitty requires JavaScript.</noscript>
</head>

View file

@ -1,4 +1,4 @@
import * as bitty from './bitty.js';
import * as bitty from '/bitty.js';
window.bitty = bitty;
@ -64,7 +64,7 @@
}
const renderers = {
"application/ld+json": {script:"recipe"},
"application/ld+json": {script:"/render/recipe.min.html"},
"text/canvas+javascript": {script:"canvas"},
"text/javascript": {script:"script"},
"application/bitsy": {script:"/render/bitsy.html", sandbox:"bitsy"},
@ -404,13 +404,15 @@
let src = window.scriptDomain ?? location.origin;
src += "/render";
let sandbox = params.renderer?.sandbox;
if (params.script.endsWith(".html")) {
src = params.script;
if (!sandbox) sandbox = "none";
}
let sandbox = params.renderer?.sandbox;
// if (sandbox == "none") { // passthrough
// } else
if (sandbox == "hash") { // Generate sandbox based off of body hash
if (sandbox == "none") { // passthrough
} else if (sandbox == "hash") { // Generate sandbox based off of body hash
let hash = await bitty.hashString(params.body);
src = src.replace("https://", "https://script-" + hash + ".");
} else if (sandbox) { // Use named sandbox

24
docs/index.min.html Normal file

File diff suppressed because one or more lines are too long

View file

@ -44,7 +44,7 @@ function edit() {
document.body.classList.toggle("edit");
}
function render() {
let colors = params.body.substring(2).split(";");
let colors = decodeURIComponent(params.body.substring(2)).split(";");
document.body.style.backgroundColor = colors[0];
document.body.style.color = colors[1];
currentColor = colors[0];

43
docs/render/recipe.html Normal file
View file

@ -0,0 +1,43 @@
<link rel="stylesheet" href="recipe.css" inline>
<script src="recipe.js" inline></script>
<script>
function loadScript(src, callback, type = "module") {
let promise = new Promise((resolve, reject) => {
let script = document.createElement("script")
script.type = type;
script.onload = resolve;
script.src = src
document.head.appendChild(script);
console.log("script", script)
})
return callback ? promise.then(callback) : promise;
}
window.addEventListener("message", function(e) {
let data = e.data;
// var base = el('base', {href: data.script});
// console.log("MESSAGE", data, base, data.script);
// document.head.appendChild(base);
window.script = data.script
console.log("data.script", data)
window.params = data;
window.params.origin = e.origin;
console.log("🖊Rendering with", {script:data.script, params:data})
render()
loadScript("../js/qrious.min.js", null, "").then(() => {
console.log("qrious loaded", window.params, window.params.originalURL);
var qr = new QRious({
element: document.getElementById("qr"),
background: 'transparent',
foreground: 'currentColor',
size: 512,
value: params.originalURL.substring(0),
});
})
}, false);
</script>

View file

@ -179,6 +179,26 @@ const replacements = {
}
let lastNoun = undefined;
window.addEventListener("click", (e) => {
let target = e.target;
if (target.classList.contains("noun")) {
let els = document.querySelectorAll("#" + e.target.id);
let isIngredient = target.closest(".ingredients");
for (const noun of els) {
noun.classList.add("hovered");
if (noun.closest(".ingredients") != isIngredient) {
noun.scrollIntoView({behavior:"smooth", block: "center"})
console.log("focusing", noun)
if (noun == lastNoun) break;
}
}
lastNoun = target;
}
})
window.addEventListener("mouseover", (e) => {
let target = e.target;
@ -190,11 +210,11 @@ window.addEventListener("mouseover", (e) => {
noun.classList.add("hovered");
noun.closest(".substep")?.classList.add("hovered")
noun.closest(".ingredient")?.classList.add("hovered")
if (noun.closest(".ingredients") != isIngredient) {
noun.scrollIntoView({behavior:"smooth", block: "center"})
console.log("focusing", noun)
if (noun == lastNoun) break;
}
// if (noun.closest(".ingredients") != isIngredient) {
// noun.scrollIntoView({behavior:"smooth", block: "center"})
// console.log("focusing", noun)
// if (noun == lastNoun) break;
// }
}
lastNoun = target;
}
@ -400,6 +420,7 @@ function faviconForTitle(title) {
}
return undefined;
}
function render() {
try {
let data = JSON.parse(window.params.body);
@ -414,7 +435,8 @@ function render() {
console.error("Data", e, {e, body: window.params.body});
return;
}
document.head.appendChild(el("base", {target: "_blank"}));
// console.log("head", document.head, .el, el("base", {target: "_blank"}))
document.head.appendChild(m("base", {target: "_blank"}));
delete document.documentElement.style.display;
document.body.childNodes.forEach((c) => document.body.removeChild(c))
@ -597,7 +619,7 @@ function render() {
let originalURL = json.mainEntityOfPage?.["@id"] ?? ((json.mainEntityOfPage == true) ? false : json.mainEntityOfPage) ?? json.url;
let hostname = originalURL ? new URL(originalURL).hostname.replace("www.","") : ""
let qrImage = QRCodeURL(params.originalURL, {margin:0});
let qrImage = undefined // QRCodeURL(params.originalURL, {margin:0});
let publisherImage = json.publisher?.image ?.[0]?.url ?? json.publisher ?.logo ?.url;
document.body.appendChild(
@ -696,16 +718,16 @@ function keepAwake() {
}
var path = window.script.substring(0, window.script.lastIndexOf("."));
var cssURL = path + ".css";
loadScript(path + '/../../js/qrious.min.js', null, "").then(() => {
console.log("qrious loaded", params.originalURL.length);
var qr = new QRious({
element: document.getElementById("qr"),
background: 'transparent',
foreground: 'currentColor',
size: 512,
value: params.originalUrl.substring(0),
});
})
loadSyle(cssURL).then(render);
// var path = window.script.substring(0, window.script.lastIndexOf("."));
// var cssURL = path + ".css";
// loadScript(path + '/../../js/qrious.min.js', null, "").then(() => {
// console.log("qrious loaded", params.originalURL.length);
// var qr = new QRious({
// element: document.getElementById("qr"),
// background: 'transparent',
// foreground: 'currentColor',
// size: 512,
// value: params.originalUrl.substring(0),
// });
// })
// loadSyle(cssURL).then(render);

File diff suppressed because one or more lines are too long