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
+ share
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))
- // }
}