mirror of
https://github.com/arfct/itty-bitty.git
synced 2026-03-11 08:54:33 +00:00
Dynamically create theme color, add sharing
This commit is contained in:
parent
42576e1417
commit
5aeafa9784
1 changed files with 115 additions and 61 deletions
176
docs/index.js
176
docs/index.js
|
|
@ -32,7 +32,14 @@
|
|||
}
|
||||
|
||||
function setThemeColor(color) {
|
||||
document.getElementById("themeColor").content = color;
|
||||
let el = document.getElementById("themeColor");
|
||||
if (!el) {
|
||||
el = document.createElement("meta");
|
||||
el.name = "theme-color";
|
||||
el.id = "themeColor";
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
el.content = color;
|
||||
}
|
||||
|
||||
function setFavicon(favicon) {
|
||||
|
|
@ -50,11 +57,42 @@
|
|||
"application/ld+json": {script:"recipe"},
|
||||
"text/rawhtml": {script:"parse"},
|
||||
"javascript": {script:"bookmarklet"},
|
||||
"ipfs": {script:"ipfs"},
|
||||
"web3": {script:"web3", mode:"frame"},
|
||||
"ipfs": {script:"ipfs", sandbox:"ipfs"},
|
||||
"web3": {script:"web3"},
|
||||
"text/directory": {script:"download", args: {extension:"vcf", filename:"contact"}}
|
||||
}
|
||||
|
||||
|
||||
function share(info) { // {title, text, url}
|
||||
if (!info.url) info = {title:document.title, text:document.title, url:location.href};
|
||||
console.log("Share", info);
|
||||
|
||||
if (navigator.share) {
|
||||
navigator.share(info)
|
||||
.then(() => { console.log('Thanks for sharing!');})
|
||||
.catch(console.error);
|
||||
} else {
|
||||
copyLink(info)
|
||||
}
|
||||
}
|
||||
|
||||
function copyLink(info) {
|
||||
var text = info.url;
|
||||
var dummy = document.createElement("input");
|
||||
document.body.appendChild(dummy);
|
||||
dummy.value = text;
|
||||
dummy.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(dummy);
|
||||
|
||||
document.body.classList.add("copied");
|
||||
setTimeout(function() {
|
||||
document.body.classList.remove("copied");
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.addEventListener("message", function(e) {
|
||||
console.debug("Message:", e.origin, e.data)
|
||||
if (e.data.title) document.title = e.data.title;
|
||||
|
|
@ -65,9 +103,12 @@
|
|||
if (e.data.description) path.push("d/" + encodeURIComponent(e.data.description));
|
||||
if (e.data.favicon) path.push("f/" + encodeURIComponent(e.data.favicon));
|
||||
if (e.data.image) path.push("i/" + encodeURIComponent(btoa(e.data.image)));
|
||||
window.location.pathname = path.join('/');
|
||||
window.location.pathname = path.join('/') + "/";
|
||||
}
|
||||
|
||||
if (e.data.share) {
|
||||
share(e.data.share);
|
||||
}
|
||||
if (e.data.replaceURL) {
|
||||
if (e.data.compressURL) {
|
||||
let durl = new bitty.DataURL(e.data.replaceURL);
|
||||
|
|
@ -141,7 +182,7 @@
|
|||
|
||||
if (fragment.startsWith("data:")) {
|
||||
let info = bitty.infoForDataURL(fragment);
|
||||
renderer = info.params?.render ? {script:info.params.render} : renderers[info.mediatype];
|
||||
renderer = info.params?.render ? {script:info.params.render, sandbox:"hash"} : renderers[info.mediatype];
|
||||
|
||||
type = "data:" + info.mediaType;
|
||||
|
||||
|
|
@ -174,7 +215,7 @@
|
|||
|
||||
let renderer = renderers[scheme];
|
||||
if (renderer) {
|
||||
return renderContentWithScript(false, renderer, title, info, fragment, fragment);
|
||||
return renderContentWithScript({renderer, title, info, body:fragment, url:fragment});
|
||||
}
|
||||
return window.location.replace(fragment);
|
||||
}
|
||||
|
|
@ -199,48 +240,47 @@
|
|||
durl.dataPrefix = dataPrefix;
|
||||
let dataURL = durl.href;
|
||||
let dataContent = durl.rawData;
|
||||
// bitty.decompressDataURL(fragment, dataPrefix, function(dataURL, dataContent)
|
||||
{
|
||||
if (!dataURL) return;
|
||||
iframe.sandbox = "allow-downloads allow-scripts allow-forms allow-top-navigation allow-popups allow-modals allow-popups-to-escape-sandbox";
|
||||
|
||||
if (isIE && renderMode == "data") renderMode = "frame";
|
||||
let contentTarget// = iframe.contentWindow.document;
|
||||
if (isWatch) {
|
||||
console.log("Rendering for watch")
|
||||
contentTarget = document;
|
||||
}
|
||||
console.log("Rendering mode: " + "\x1B[1m" + renderMode, durl)
|
||||
// dataURL = dataURL.replace("application/ld+json", "text/plain");
|
||||
if (renderMode == "download") {
|
||||
try {
|
||||
//let dl = document.querySelector("#download");
|
||||
let extension = title.split(".")
|
||||
let dl = el("a", {id: "download", href:dataURL, download: title},
|
||||
el("div", {id: "dl-image", innerText:extension.pop() ?? ""}),
|
||||
el("div", {id: "dl-name", innerText:"title"}),
|
||||
el("div", {id: "dl-button"}),
|
||||
)
|
||||
document.body.append(dl)
|
||||
document.body.classList.add("download");
|
||||
dl.click();
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log("DL error", e)
|
||||
iframe.src = dataURL;
|
||||
}
|
||||
} else if (renderMode == "data") {
|
||||
iframe.src = dataURL;
|
||||
} else {
|
||||
bitty.dataToString(dataURL, function(content) {
|
||||
if (renderMode == "frame") {
|
||||
writeDocContent(contentTarget, content)
|
||||
} else if (renderMode == "script") {
|
||||
renderContentWithScript(contentTarget == document, renderer, title, info, content, dataURL);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!dataURL) return;
|
||||
iframe.sandbox = "allow-same-origin allow-downloads allow-scripts allow-forms allow-top-navigation allow-popups allow-modals allow-popups-to-escape-sandbox";
|
||||
|
||||
if (isIE && renderMode == "data") renderMode = "frame";
|
||||
let contentTarget// = iframe.contentWindow.document;
|
||||
if (isWatch) {
|
||||
console.log("Rendering for watch")
|
||||
contentTarget = document;
|
||||
}
|
||||
console.log("Rendering mode: " + "\x1B[1m" + renderMode, durl)
|
||||
// dataURL = dataURL.replace("application/ld+json", "text/plain");
|
||||
if (renderMode == "download") {
|
||||
try {
|
||||
//let dl = document.querySelector("#download");
|
||||
let extension = title.split(".")
|
||||
let dl = el("a", {id: "download", href:dataURL, download: title},
|
||||
el("div", {id: "dl-image", innerText:extension.pop() ?? ""}),
|
||||
el("div", {id: "dl-name", innerText:"title"}),
|
||||
el("div", {id: "dl-button"}),
|
||||
)
|
||||
document.body.append(dl)
|
||||
document.body.classList.add("download");
|
||||
dl.click();
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log("DL error", e)
|
||||
iframe.src = dataURL;
|
||||
}
|
||||
} else if (renderMode == "data") {
|
||||
iframe.src = dataURL;
|
||||
} else {
|
||||
bitty.dataToString(dataURL, function(content) {
|
||||
if (renderMode == "frame") {
|
||||
writeDocContent(contentTarget, content)
|
||||
} else if (renderMode == "script") {
|
||||
renderContentWithScript({renderer, title, info, body:content, url:dataURL, overwrite:contentTarget == document});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
let recordHistory = false
|
||||
if (recordHistory) recordToHistory(title, type, description, window.location);
|
||||
|
|
@ -252,36 +292,50 @@
|
|||
|
||||
|
||||
const SCRIPT_LOADER = `<!doctype html><meta charset=utf-8><script src="${location.origin}/render.js"></script>`
|
||||
function renderContentWithScript(overwrite, renderer, title, info, body, url) {
|
||||
let script = renderer.script;
|
||||
if (script.indexOf("/") == -1) script = location.origin + '/render/' + script + '.js'
|
||||
async function renderContentWithScript(params) {
|
||||
|
||||
params.script = params.renderer.script;
|
||||
params.originalURL = location.href;
|
||||
if (params.script.indexOf("/") == -1) params.script = location.origin + '/render/' + params.script + '.js'
|
||||
|
||||
if (overwrite) {
|
||||
if (params.overwrite) {
|
||||
// Overwrite the current page with the script. Dangerous, but required for browsers on apple watch to scroll.
|
||||
let scriptEl = document.createElement("script")
|
||||
scriptEl.src = "/render.js"
|
||||
scriptEl.addEventListener('load', function(e) {
|
||||
console.log("Loaded script", scriptEl.src);
|
||||
renderScriptContent({script, url, title, info, body}, "*");
|
||||
renderScriptContent(params, "*");
|
||||
});
|
||||
document.head.appendChild(scriptEl);
|
||||
|
||||
} else {
|
||||
} else {
|
||||
// Render in an iframe, either via sandboxed subdomain or a data url (disables storage APIs)
|
||||
iframe.onload = (() => {
|
||||
iframe.contentWindow.postMessage({script, url, title, info, body, args:renderer.args}, "*");
|
||||
iframe.contentWindow.postMessage(params, "*");
|
||||
delete iframe.onload
|
||||
});
|
||||
// writeDocContent(iframe.contentWindow.document, SCRIPT_LOADER)
|
||||
// iframe.srcdoc = SCRIPT_LOADER;
|
||||
iframe.src = "data:text/html," + SCRIPT_LOADER;
|
||||
|
||||
let src = location.origin + "/render";
|
||||
let sandbox = params.renderer?.sandbox;
|
||||
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
|
||||
src = src.replace("https://", "https://" + sandbox + ".");
|
||||
} else { // Render using data url (storage disabled)
|
||||
src = "data:text/html," + SCRIPT_LOADER;
|
||||
}
|
||||
console.log("src", src)
|
||||
iframe.src = src;
|
||||
}
|
||||
}
|
||||
|
||||
function writeDocContent(doc, content) {
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
}
|
||||
|
||||
function writeDocContent(doc, content) {
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
}
|
||||
|
||||
function recordToHistory() {
|
||||
if (navigator.storage && navigator.storage.persist)
|
||||
|
|
|
|||
Loading…
Reference in a new issue