From ba7b10dc4bf5592a4eeffc1783221db561f0dc82 Mon Sep 17 00:00:00 2001 From: Nicholas Jitkoff Date: Tue, 17 May 2022 08:37:07 -0700 Subject: [PATCH] Updated opengraph functions, dark mode --- docs/base.css | 5 +- docs/bitty.js | 2 +- docs/bookmarklet.url | 1 - docs/bookmarklet.url.js | 54 ++++++++++++ docs/edit.css | 73 ++++++++++++---- docs/edit.html | 23 +++-- docs/edit.js | 14 ++- docs/favicon.svg | 11 +++ docs/history.html | 148 ++++++++++++++++++++++++++++++++ docs/index.css | 3 + docs/index.html | 6 +- docs/render/parse.js | 21 ++++- docs/render/recipe.css | 27 ++++-- docs/render/recipe.js | 20 +++-- netlify/edge-functions/index.js | 54 ++++++------ 15 files changed, 379 insertions(+), 83 deletions(-) delete mode 100644 docs/bookmarklet.url create mode 100644 docs/bookmarklet.url.js create mode 100644 docs/favicon.svg create mode 100644 docs/history.html diff --git a/docs/base.css b/docs/base.css index 6fe47f3..dd8e17c 100644 --- a/docs/base.css +++ b/docs/base.css @@ -1 +1,4 @@ -body{margin:0 auto;padding:12vmin 10vmin;max-width:35em;line-height:1.5em;font-family: -apple-system,BlinkMacSystemFont,sans-serif;word-wrap: break-word;} \ No newline at end of file +body{margin:0 auto;padding:12vmin 10vmin;max-width:35em;line-height:1.5em;font-family:-apple-system,BlinkMacSystemFont,sans-serif;word-wrap:break-word;} + + +@media (prefers-color-scheme: dark){body{color:white;background-color:#111;}} \ No newline at end of file diff --git a/docs/bitty.js b/docs/bitty.js index 09d495d..0bb834b 100644 --- a/docs/bitty.js +++ b/docs/bitty.js @@ -55,7 +55,7 @@ function decompressDataURL(dataURL, preamble, callback) { let encoding = info.encoding; let encodingIndex = dataURL.indexOf(encoding); - if (encoding) { + if (encoding != "base64") { var base64 = dataURL.substring(encodingIndex + LZMA64_MARKER.length + 1); base64 = base64.replace("-",""); // TODO: apply this elsewhere; diff --git a/docs/bookmarklet.url b/docs/bookmarklet.url deleted file mode 100644 index 60a692d..0000000 --- a/docs/bookmarklet.url +++ /dev/null @@ -1 +0,0 @@ -javascript:((itty_bitty_recipes) => {let ldjson = document.querySelector('script[type=%22application/ld+json%22]').innerText.trim();var blob = new Blob([ldjson],{type : 'application/ld+json;charset=utf-8'}); var a = new FileReader();a.onload = function(e) { open(itty_bitty_recipes + '/#/'%20+%20e.target.result);};a.readAsDataURL(blob);})('https://gitty.bitty.site') \ No newline at end of file diff --git a/docs/bookmarklet.url.js b/docs/bookmarklet.url.js new file mode 100644 index 0000000..bb3a4ee --- /dev/null +++ b/docs/bookmarklet.url.js @@ -0,0 +1,54 @@ +https://itty.bitty.app/Recipe_Bookmarklet/Simplify_recipes_with_a_click./%F0%9F%8D%B4#itty.bitty.recipe/ + + +// JSON extraction + +//javascript: +((itty_bitty_recipes) => { + let ldjson = document.querySelector('script[type="application/ld+json"]').innerText.trim(); + let f = new FileReader(); + f.onload = function(e) { location.href = (itty_bitty_recipes + '/#/' + e.target.result);}; + f.readAsDataURL(new Blob([ldjson],{type : 'application/ld+json;charset=utf-8'})); +})('https://recipe.bitty.app') + + + +// DOM extraction + +javascript:f=new FileReader();f.onload=function(e){top.location.href=('https://itty.bitty.app/#/'+e.target.result)};f.readAsDataURL(new Blob([document.documentElement.outerHTML],{type:'text/raw+html;render=parse;encode=none;charset=utf-8'})); + +javascript:f=new FileReader();f.onload=function(e){top.location.href=('http://localhost:8888/#/'+e.target.result)};f.readAsDataURL(new Blob([document.documentElement.outerHTML],{type:'text/raw+html;render=parse;encode=none;charset=utf-8'})); + + + +// JS Injection + +javascript: +(function(ittybitty){ + let id="ittybitty"; + if (document.getElementById(id)) return; + var l = document.createElement('script'); + l.setAttribute('type','text/javascript'); + l.setAttribute('src',ittybitty + '/extractrecipe.js'); + l.id=id; + document.head.appendChild(l); +})("https://itty.bitty.app"); + + +// JS Injection with fallback + +javascript: +(function(host){ + document.getElementById(host)?.remove(); + var l = document.createElement('script'); + l.setAttribute('type','text/javascript'); + l.setAttribute('src', host + '/extract.js'); + l.onerror = () => { + let html = document.documentElement.innerHTML; + let f = new FileReader(); + f.onload = function(e) { location.href = (host + '/#/' + e.target.result);}; + f.readAsDataURL(new Blob([html],{type : 'text/rawhtml;charset=utf-8'})); + }; + l.id = id; + document.head.appendChild(l); +})("https://itty.bitty.app"); diff --git a/docs/edit.css b/docs/edit.css index fcf3537..5346538 100644 --- a/docs/edit.css +++ b/docs/edit.css @@ -1,10 +1,33 @@ + + +html { + --text-color:rgba(0, 0, 0, 0.87); + --text-placeholder-color:rgba(0,0,0,0.54); + --text-link-color:#0070e0; + --background-color:white; + --shadow-color:black; + + color: var(--text-color); + background-color: var(--background-color); +} +@media (prefers-color-scheme: dark) { + html { + --text-color:white; + --text-placeholder-color:rgba(255,255,255,0.54); + --text-link-color:#40a0ff; + --background-color:#111; + --shadow-color:black; + + } +} + body { margin: 0 auto; padding: 12vh 10vmin; max-width: 35em; - font-family: -apple-system, BlinkMacSystemFont, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + line-height: 1.5em; - color: rgba(0, 0, 0, 0.87); } h1 { @@ -15,7 +38,7 @@ h2 { } a { - color: #0070e0; + color: var(--text-link-color); } *[contenteditable="true"] { @@ -29,7 +52,7 @@ body.loaded:not(.edited) #placeholder { #placeholder { display: none; font-style: italic; - color: rgba(0, 0, 0, 0.3); + color: var(--text-placeholder-color); pointer-events: none; position: absolute; } @@ -62,14 +85,14 @@ body.drag #content { top: 0; position: absolute; padding: 0.5em 0; - font-family: monospace; font-weight: bold; + font-size:small; } body.edited #doc-title:empty:before, #doc-title:focus:empty:before { content: "untitled"; - color: rgba(0, 0, 0, 0.333); + color: var(--text-placeholder-color); } #doc-title:focus { @@ -79,19 +102,25 @@ body.edited #doc-title:empty:before, #doc-title:empty:before { background: transparent; } - + #content:empty:before { content: attr(placeholder); color: rgba(0, 0, 0, 0.2); background: transparent; } + #doc-file { border-radius: 1em; - background: #ebeff9; + background-color: #fafafa; padding: 0.25em 1em; - font-size: smaller; + /* font-size: smaller; */ margin-bottom: 2em; -} + background-position: top center; + background-repeat: no-repeat; + + background-image: url("data:image/svg+xml,%0A%3Csvg width='128' height='128' viewBox='0 0 128 128' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cmask id='path-1-outside-1_116_2' maskUnits='userSpaceOnUse' x='27' y='15' width='74' height='98' fill='black'%3E%3Crect fill='white' x='27' y='15' width='74' height='98'/%3E%3Cpath d='M80 16H28V112H100V36L80 16Z'/%3E%3C/mask%3E%3Cpath d='M80 16H28V112H100V36L80 16Z' fill='white'/%3E%3Cpath d='M28 16V15H27V16H28ZM80 16L80.7071 15.2929L80.4142 15H80V16ZM28 112H27V113H28V112ZM100 112V113H101V112H100ZM100 36H101V35.5858L100.707 35.2929L100 36ZM28 17H80V15H28V17ZM29 112V16H27V112H29ZM100 111H28V113H100V111ZM99 36V112H101V36H99ZM100.707 35.2929L80.7071 15.2929L79.2929 16.7071L99.2929 36.7071L100.707 35.2929Z' fill='black' fill-opacity='0.15' mask='url(%23path-1-outside-1_116_2)'/%3E%3C/svg%3E%0A"); + +min-height: 160px;/* background-size: 128px; */text-align: center;padding-top: 128px;} #doc-file:empty { display: none; } @@ -122,7 +151,6 @@ body.edited #doc-title:empty:before, bottom: 0; left: 0; right: 0; - font-family: monospace; font-weight: bold; text-align: center; } @@ -141,8 +169,6 @@ body.edited #doc-title:empty:before, #toolbar button { vertical-align: baseline; - - font-family: monospace; } #toolbar a.invalid { @@ -164,11 +190,11 @@ body.edited #doc-title:empty:before, right: 0; padding: 0.5em 1em; text-align: right; - font-family: monospace; + + font-size:small; font-weight: bold; /*transform: translateY(-2em);*/ transition: transform 100ms ease-out; - background-color: white; border-bottom-left-radius: 1em; cursor: pointer; } @@ -181,7 +207,6 @@ body.edited #doc-title:empty:before, position: absolute; padding: 0.5em 1em; z-index: 100; - font-family: monospace; font-weight: bold; } @@ -199,17 +224,25 @@ body:not(.copied) #copy-message { margin-left: 0.5em; cursor: pointer; text-decoration: none; - color: #333; + color: var(--text-color); + vertical-align: middle; } #toolbar a:hover { text-decoration: underline; - color: #111; } .menu { width: auto; display: none; -} + color:var(--text-color); + border: 2px solid currentColor; + padding: 0.5em; + box-shadow: 2px 2px var(--shadow-color); + margin-right: -0.5em;border-radius: 2px; +margin-top: 0.7em;} + +div#menu-contents {} + #toolbar.menu-visible .menu { display: block; } @@ -220,4 +253,6 @@ body:not(.copied) #copy-message { .menu hr { border: none; + background-color: currentColor; + height: 2px; } diff --git a/docs/edit.html b/docs/edit.html index 11a0f61..4d02cbc 100644 --- a/docs/edit.html +++ b/docs/edit.html @@ -2,35 +2,40 @@ - + itty.bitty + + + +
-itty bitty things
-can be conveyed in a link.
-type here – and then share!

about itty bitty
+ itty bitty things
+ can be conveyed in a link.
+ type here – and then share!

 about itty bitty

Link copied to clipboard.
-  qr code menu +  share menu diff --git a/docs/edit.js b/docs/edit.js index 6a504a1..f002d37 100644 --- a/docs/edit.js +++ b/docs/edit.js @@ -42,6 +42,9 @@ window.onload = function() { content.focus(); document.execCommand("selectAll", false, null); QS("#qrcode").onclick = makeQRCode; + + QS("#share").onclick = share; + if (!navigator.share) QS("#share").style.display = "none" QS("#twitter").onclick = tweetLink; QS("#copy").onclick = copyLink; QS("#menu").onclick = toggleMenu; @@ -110,7 +113,7 @@ function handleDrop(e) { importedFileData = url2; updateLink(url2, file.name, true); - setFileName("📄" + file.name); + setFileName(file.name); }); }, false @@ -263,6 +266,15 @@ function updateLink(url, title, push) { } } +function share() { + navigator.share({ + title: 'itty.bitty', + url: location.href + }).then(() => { + console.log('Thanks for sharing!'); + }) + .catch(console.error); +} function makeQRCode() { var url = "https://chart.googleapis.com/chart?cht=qr&chs=512x512&chld=L|1&choe=UTF-8&chl=" + diff --git a/docs/favicon.svg b/docs/favicon.svg new file mode 100644 index 0000000..946a656 --- /dev/null +++ b/docs/favicon.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/docs/history.html b/docs/history.html new file mode 100644 index 0000000..a73df82 --- /dev/null +++ b/docs/history.html @@ -0,0 +1,148 @@ + +itty.bitty.history + + + + + + + + diff --git a/docs/index.css b/docs/index.css index 6ff7702..aea3f0e 100644 --- a/docs/index.css +++ b/docs/index.css @@ -1,6 +1,9 @@ body { font-family: sans-serif; } + +@media(prefers-color-scheme: dark){body{color:white;background-color:#111;}} + #iframe { border: none; position: absolute; diff --git a/docs/index.html b/docs/index.html index 9bb0c2b..a821f23 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,8 +1,10 @@ - + + - + + diff --git a/docs/render/parse.js b/docs/render/parse.js index 9311450..340f6e0 100644 --- a/docs/render/parse.js +++ b/docs/render/parse.js @@ -1,9 +1,22 @@ // let title = params.title + +parent.postMessage({title:"Parsing Content..."}, "*"); +document.write("PARSING CONTENT…") + + const parser = new DOMParser(); const doc = parser.parseFromString(params.body, "text/html"); -let ldjson = doc.querySelector('script[type="application/ld+json"]').innerText.trim(); -let f = new FileReader(); -f.onload = function(e) { top.location.href = ( '/#/' + e.target.result);}; -f.readAsDataURL(new Blob([ldjson],{type : 'application/ld+json;charset=utf-8'})); \ No newline at end of file +let ldjson = doc.querySelector('script[type="application/ld+json"]') +if (ldjson) { + ldjson = ldjson.innerText.trim(); + let f = new FileReader(); + f.onload = function(e) { + //top.location.href = ( '/#/' + e.target.result); + parent.postMessage({replaceURL:'/temp#/' + e.target.result}, "*"); + }; + f.readAsDataURL(new Blob([ldjson],{type : 'application/ld+json;charset=utf-8'})); +} else { + alert("No recipe found") +} \ No newline at end of file diff --git a/docs/render/recipe.css b/docs/render/recipe.css index dbc9083..4896b3c 100644 --- a/docs/render/recipe.css +++ b/docs/render/recipe.css @@ -86,14 +86,15 @@ background-color:#f1f1f1; ul.step { padding-inline-start: 0; list-style-type:none; - -padding: 0;margin: 0em;} + padding: 0;margin: 0em; +} .instructions:not(.numbered) .number { display: none; } + span.number { - margin-left: -24px; + margin-left: -27px; float:left; border: 2px solid currentColor; font-weight: 800; @@ -104,8 +105,8 @@ span.number { font-size: 10px; line-height: 16px; opacity:0.7; - display:none; -} +/* background: black; */} + .number.big { font-size:8px; } @@ -164,6 +165,8 @@ border-radius: 2px;} .ingredients { font-weight: 700; font-size: 90%; + /* position:sticky; */ + /* top: 0px; */ /* padding-top: 1em; */ flex: 0 1 35%; /* color: rgba(0,0,0,0.8); */} @@ -176,7 +179,11 @@ border-radius: 2px;} /* line-height: 125%; */ /* font-size: 100%; */ flex: 0 1 65%; - margin-top: -0.4em; + margin-top: -0.7em; +} + +.instructions.numbered li { + padding-left: 2em; } .substep { @@ -206,7 +213,7 @@ border-radius: 2px;} } .ingredient.complete, -.substep.complete { +li.complete { text-decoration: line-through; opacity: 0.33; } @@ -309,4 +316,8 @@ color:var(--text-color); .noprint { display: none; } -} \ No newline at end of file +} + +.instructions.numbered hr {margin: 0.7em 0;height: 2px;opacity: 10;} + +.instructions.numbered {margin-top: -1.6em;} \ No newline at end of file diff --git a/docs/render/recipe.js b/docs/render/recipe.js index fd4ea27..186a93d 100644 --- a/docs/render/recipe.js +++ b/docs/render/recipe.js @@ -138,7 +138,7 @@ function highlightStep(e) { // e.target.parent.children.forEach((i,el) => { // el.classList.toggle("complete", ) // } - e.target.closest(".substep").classList.toggle("complete") + e.target.closest("li").classList.toggle("complete") } @@ -186,7 +186,7 @@ function render() { image = image?.url || image; instructions = json.recipeInstructions; let title = clean(json.name); - parent.postMessage({title:title, favicon:"🍳", image:image, updateURL:true}, "*"); + parent.postMessage({title:title, favicon:"🍴", image:image, updateURL:true}, "*"); // let text = instructions.join(" "); @@ -227,9 +227,10 @@ function render() { return [m("hr"), m("ul.step", instruction.map(i => renderInstructions(i, terms)))]; } - let text = (instruction.text || instruction); - if (text.startsWith("= ")) return m("h3", text.substring(2)); + let text = (instruction?.text || instruction); + if (text?.startsWith("= ")) return m("h3", text.substring(2)); + if (!text) return; return m("li", { onclick: highlightStep }, m("span.number" + (step>9 ? ".big" : ""), `${step++}`), m("span.substep",{innerHTML:highlightTerms(FRACTION_MAP.replace(text.trim()), terms)})) @@ -321,13 +322,14 @@ function render() { ) ) - var path = script.src.substring(0, script.src.lastIndexOf(".")); - var cssURL = path + ".css"; - - document.head.appendChild(m("link", { rel: "stylesheet", type: "text/css", href: cssURL })); - document.head.appendChild(m("link", { rel: "stylesheet", href: "https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" })); } +var path = script.src.substring(0, script.src.lastIndexOf(".")); +var cssURL = path + ".css"; + +document.head.appendChild(m("link", { rel: "stylesheet", type: "text/css", href: cssURL })); +document.head.appendChild(m("link", { rel: "stylesheet", href: "https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" })); + render(); \ No newline at end of file diff --git a/netlify/edge-functions/index.js b/netlify/edge-functions/index.js index f5e408b..b35c357 100644 --- a/netlify/edge-functions/index.js +++ b/netlify/edge-functions/index.js @@ -5,40 +5,38 @@ export default async (request, context) => { let metadataBots = [ "Twitterbot", "curl", "facebookexternalhit", "Slackbot-LinkExpanding", "Discordbot"] let isMetadataBot = metadataBots.some(bot => useragent.indexOf(bot) != -1); if (isMetadataBot) { - let components = path.split("/"); - components.shift(); - let title = decodeURIComponent(components.shift()).replace(/_/g, " "); - let desc = decodeURIComponent(components.shift()).replace(/_/g, " "); - let image = decodeURIComponent(components.join("/")); - let content = ""; - if (title) { - content += `${title}`; - // content += `` - } - if (desc && desc.length > 1) { - content += ``; - } - if (image) { - if (image.startsWith("http")) { - content += ``; + let components = path.substring(1).split("/"); + // components.shift(); + let info = {} + info.t = decodeURIComponent(components.shift()).replace(/_/g, " "); + + components.forEach(component => { + let field = component.split(":"); + console.log("field", field) + let key = field.shift(); + let value = decodeURIComponent(field.join(":")); + if (key.length && value.length) info[key] = value; + }) + info.d = info.d?.replace(/_/g, " "); + + let content = []; + if (info.t) { content.push(`${info.t}`,``); } + if (info.s) { content.push(``); } + if (info.d) { content.push(``,``); } + if (info.i) { content.push(``); } + if (info.f) { + if (info.f.length > 9){ + content.push(``); } else { - image = decodeURIComponent(image) - let codepoints = []; - for (const char of image) { - codepoints.push(char.codePointAt(0).toString(16)); - } - content += `` + let codepoints = Array.from(info.f).map(c => c.codePointAt(0).toString(16)); + content.push(``); } } - context.log(title, "|", desc || "-", "|", image || "-"); + context.log(info, content); - return new Response(content, { + return new Response(content.join("\n"), { headers: { "content-type": "text/html" }, }); } - // else { - // console.log("Forward: " + "/?" + path) - // return (context.rewrite("/?" + path)) - // } }