diff --git a/build-index.sh b/docs/build-v1.sh
similarity index 100%
rename from build-index.sh
rename to docs/build-v1.sh
diff --git a/docs/data.js b/docs/data.js
index d39516c..ee8ba83 100644
--- a/docs/data.js
+++ b/docs/data.js
@@ -45,19 +45,16 @@ function decompressDataURI(dataURI, preamble, callback) {
function zipToString(data, callback) {
var array = base64ToByteArray(data);
- if (array[0] == 31) { // Handle Brotli
- var script= document.createElement('script');
- script.type = "module"
- script.innerHTML = `import {BrotliDecode} from "./js/brotli/decode.js";console.log("yo");window.brotli = BrotliDecode;`;
- document.head.appendChild(script);
- setTimeout(() => {
- return callback((window.brotli(array)));
- },100);
- return;
-
- }
-
-
+ // if (array[0] == 31) { // Handle Brotli
+ // var script= document.createElement('script');
+ // script.type = "module"
+ // script.innerHTML = `import {BrotliDecode} from "./js/brotli/decode.js";console.log("yo");window.brotli = BrotliDecode;`;
+ // document.head.appendChild(script);
+ // setTimeout(() => {
+ // return callback((window.brotli(array)));
+ // },100);
+ // return;
+ // }
LZMA.decompress(array, function(result, error) {
if (!(typeof result === 'string')) result = new Uint8Array(result)
diff --git a/docs/index.html b/docs/index.html
index 6a24fef..77ba874 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -2,9 +2,9 @@
-
+
-
+
To use itty.bitty, please enable JavaScript.
itty.bitty is experimental technology that renders linked content from outside sources.
Learn more .
This content is only as trustworthy as its source, and it should be treated with the caution
diff --git a/docs/legacy.html b/docs/legacy.html
deleted file mode 100644
index 7c0b3c1..0000000
--- a/docs/legacy.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
To use itty.bitty, please enable JavaScript.
-
itty.bitty is experimental technology that renders linked content from outside sources.
Learn more .
-
This content is only as trustworthy as its source, and it should be treated with the caution
-you would show any insecure web page.
-
I understand Never show this
-
-
-
edit
-
diff --git a/docs/v1/base.css b/docs/v1/base.css
new file mode 100644
index 0000000..6fe47f3
--- /dev/null
+++ b/docs/v1/base.css
@@ -0,0 +1 @@
+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
diff --git a/docs/legacy/data-min.js b/docs/v1/data-min.js
similarity index 100%
rename from docs/legacy/data-min.js
rename to docs/v1/data-min.js
diff --git a/docs/legacy/data.js b/docs/v1/data.js
similarity index 100%
rename from docs/legacy/data.js
rename to docs/v1/data.js
diff --git a/docs/v1/edit.css b/docs/v1/edit.css
new file mode 100644
index 0000000..39fa54d
--- /dev/null
+++ b/docs/v1/edit.css
@@ -0,0 +1,223 @@
+body {
+ margin: 0 auto;
+ padding: 12vh 10vmin;
+ max-width: 35em;
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
+ line-height: 1.5em;
+ color: rgba(0, 0, 0, 0.87);
+}
+
+h1 {
+ font-weight: 400;
+}
+h2 {
+ font-weight: 500;
+}
+
+a {
+ color: #0070e0;
+}
+
+*[contenteditable="true"] {
+ display: inline-block;
+}
+
+body.loaded:not(.edited) #placeholder {
+ display: block;
+}
+
+#placeholder {
+ display: none;
+ font-style: italic;
+ color: rgba(0, 0, 0, 0.3);
+ pointer-events: none;
+ position: absolute;
+}
+
+body.drag #content {
+ outline: 3px dashed #ccc;
+ background-color: #fafafa;
+ border-radius: 1em;
+ pointer-events: all;
+}
+
+#content,
+#placeholder {
+ margin: -1em;
+ padding: 1em;
+ min-height: 7em;
+}
+
+#content {
+ width: 100%;
+ outline: none;
+}
+#content:focus {
+ outline-color: #ccc;
+}
+
+#doc-title {
+ outline: none;
+ min-width: 180px;
+ top: 0;
+ position: absolute;
+ padding: 0.5em 0;
+ font-family: monospace;
+ font-weight: bold;
+}
+
+body.edited #doc-title:empty:before,
+#doc-title:focus:empty:before {
+ content: "untitled";
+ color: rgba(0, 0, 0, 0.333);
+}
+
+#doc-title:focus {
+ border-bottom: 1px solid #ccc;
+}
+
+#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;
+ padding: 0.25em 1em;
+ font-size: smaller;
+ margin-bottom: 2em;
+}
+#doc-file:empty {
+ display: none;
+}
+
+#ib-info {
+ pointer-events: all;
+}
+#ib-info:hover {
+ pointer-events: all;
+ color: black;
+}
+
+/*#toolbar a#copy {
+ transition: transform 1s;
+ cursor: default;
+}
+
+#copy:active {
+ transform:translate(0, -0.5em);
+ transition: transform 100ms;
+ color:red;
+}
+*/
+
+#sharehint {
+ display: none;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ font-family: monospace;
+ font-weight: bold;
+ text-align: center;
+}
+@media only screen and (max-device-width: 480px) {
+ #twitter,
+ #copy {
+ display: none;
+ }
+ #sharehint {
+ display: block;
+ }
+ #menu-share-hint {
+ display: none;
+ }
+}
+
+#toolbar button {
+ vertical-align: baseline;
+
+ font-family: monospace;
+}
+
+#toolbar a.invalid {
+ text-decoration: line-through;
+}
+
+#length {
+ opacity: 0.54;
+}
+
+/*body.edited #toolbar {
+ opacity:1.0;
+ transform: translateY(0);
+}
+*/
+#toolbar {
+ position: fixed;
+ top: 0;
+ right: 0;
+ padding: 0.5em 1em;
+ text-align: right;
+ font-family: monospace;
+ font-weight: bold;
+ /*transform: translateY(-2em);*/
+ transition: transform 100ms ease-out;
+ background-color: white;
+ border-bottom-left-radius: 1em;
+ cursor: pointer;
+}
+
+#copy-message {
+ background: #2d2d2d;
+ color: white;
+ top: 0.5em;
+ right: 0.5em;
+ position: absolute;
+ padding: 0.5em 1em;
+ z-index: 100;
+ font-family: monospace;
+ font-weight: bold;
+}
+
+body:not(.copied) #copy-message {
+ display: none;
+}
+
+#menus-share-hint {
+ content: "hello";
+}
+#toolbar .disabled {
+ opacity: 0.333;
+}
+#toolbar a {
+ margin-left: 0.5em;
+ cursor: pointer;
+ text-decoration: none;
+ color: #333;
+}
+#toolbar a:hover {
+ text-decoration: underline;
+ color: #111;
+}
+
+.menu {
+ width: auto;
+ display: none;
+}
+#toolbar.menu-visible .menu {
+ display: block;
+}
+
+#toolbar.menu-visible #menu {
+ opacity: 0.54;
+}
+
+.menu hr {
+ border: none;
+}
diff --git a/docs/v1/edit.html b/docs/v1/edit.html
new file mode 100644
index 0000000..c4c41ac
--- /dev/null
+++ b/docs/v1/edit.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
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
+
+
+
+
\ No newline at end of file
diff --git a/docs/v1/edit.js b/docs/v1/edit.js
new file mode 100644
index 0000000..e0e48b1
--- /dev/null
+++ b/docs/v1/edit.js
@@ -0,0 +1,296 @@
+var QS = document.querySelector.bind(document);
+var QSS = document.querySelectorAll.bind(document);
+
+var DATA_PREFIX = "data:text/html;base64,";
+var DATA_PREFIX_8 = "data:text/html;charset=utf-8;base64,";
+var DATA_PREFIX_BXZE = "data:text/html;charset=utf-8;bxze64,";
+
+var b = document.documentElement.setAttribute(
+ "data-useragent",
+ navigator.userAgent
+);
+
+var importedFileData = undefined;
+
+var content = undefined;
+window.onload = function() {
+ window.onpopstate = function(e) {
+ setContent(e.state);
+ };
+ window.onhashchange = function(e) {
+ console.log("hash", e);
+ location.reload();
+ };
+ document.body.onclick = function(e) {
+ if (e.target == document.body) content.focus();
+ };
+ content = document.getElementById("content");
+ content.ondragenter = function(e) {
+ document.body.classList.add("drag");
+ };
+ content.ondragleave = function(e) {
+ document.body.classList.remove("drag");
+ };
+ content.addEventListener("keydown", handleKey);
+ content.addEventListener("keyup", handleInput);
+ QS("#doc-title").addEventListener("keyup", handleInput);
+ content.addEventListener("drop", handleDrop);
+ content.addEventListener("paste", handlePaste);
+ content.contentEditable = "true";
+ content.focus();
+ document.execCommand("selectAll", false, null);
+ QS("#qrcode").onclick = makeQRCode;
+ QS("#twitter").onclick = tweetLink;
+ QS("#copy").onclick = copyLink;
+ QS("#menu").onclick = toggleMenu;
+ var hash = window.location.hash.substring(1);
+
+ if (hash.length) {
+ var slashIndex = hash.indexOf("/");
+ var title = hash.substring(0, slashIndex);
+ if (title.length)
+ QS("#doc-title").innerText = document.title = decodeURIComponent(
+ title.replace(/_/g, " ")
+ );
+ hash = hash.substring(slashIndex + 1);
+ updateLink(hash, title);
+ if (hash.startsWith("?")) {
+ hash = hash.substring(1);
+ zipToString(hash, setContent);
+ }
+ } else {
+ updateBodyClass();
+ }
+};
+
+function setContent(html) {
+ content.innerHTML = html;
+ updateBodyClass();
+}
+
+function setFileName(name) {
+ QS("#doc-file").innerText = name;
+ if (name.length) {
+ setContent("");
+ document.body.classList.add("edited");
+ }
+}
+
+function updateBodyClass() {
+ var length = content.innerText.length;
+ if (length || importedFileData) {
+ document.body.classList.add("edited");
+ } else {
+ document.body.classList.remove("edited");
+ }
+ document.body.classList.add("loaded");
+}
+
+function handleDrop(e) {
+ e.preventDefault();
+ if (e.dataTransfer.files) {
+ var file = e.dataTransfer.files[0];
+ var reader = new FileReader();
+ reader.addEventListener(
+ "load",
+ function() {
+ var url = reader.result;
+ url = url.replace(DATA_PREFIX, DATA_PREFIX_8);
+ compressDataURI(url, function(url2) {
+ var ratio = url2.length / url.length;
+ console.log("Compressed to", ratio);
+ if (e.ctrlKey)
+ decompressDataURI(url2, undefined, function(url3) {
+ console.log("Verified", url == url3);
+ });
+ if (ratio > 0.95) url2 = url;
+ if (e.altKey) url2 = url2.replace(DATA_PREFIX_BXZE, "!");
+
+ importedFileData = url2;
+ updateLink(url2, file.name, true);
+ setFileName("📄" + file.name);
+ });
+ },
+ false
+ );
+ reader.readAsDataURL(file);
+ }
+ document.body.classList.remove("drag");
+}
+
+// TODO Command+Shift+T for title (H1), Command+Shift+H for headline (H2), Command+Shift+B for body text (remove any of the above)
+function handleKey(e) {
+ var code = e.which;
+ var handled = false;
+ if (e.metaKey && e.altKey) {
+ handled = true;
+ if (code == "1".charCodeAt(0)) {
+ document.execCommand("formatBlock", true, "
");
+ } else if (code == "2".charCodeAt(0)) {
+ document.execCommand("formatBlock", true, "");
+ } else if (code == 220) {
+ // \
+ document.execCommand("removeFormat");
+ } else if (code == "0".charCodeAt(0)) {
+ document.execCommand("formatBlock", true, "");
+ } else {
+ handled = false;
+ }
+ } else if (e.metaKey) {
+ if (code == "K".charCodeAt(0)) {
+ handled = true;
+ var url = prompt("Add a link", "");
+ if (url) {
+ document.execCommand("createLink", true, url);
+ }
+ }
+ }
+ if (handled) e.preventDefault();
+}
+
+var codepenRE = /(https:\/\/codepen\.io\/[\w]+\/(\w+)\/(\w+))/;
+function handlePaste(e) {
+ var clipboard = window.clipboardData || e.clipboardData;
+ var text = clipboard.getData("Text") || clipboard.getData("text/plain");
+ if ((match = text.match(codepenRE))) {
+ fetchCodepen(match[0]);
+ }
+}
+
+var TEMPLATE_MARKER = "/*use-itty-bitty-template*/";
+function fetchCodepen(url) {
+ var h, c, j;
+ $.when(
+ $.get({ url: url + ".html", cache: false }, function(html) {
+ h = html;
+ }),
+ $.get({ url: url + ".css", cache: false }, function(css) {
+ c = css;
+ }),
+ $.get({ url: url + ".js", cache: false }, function(js) {
+ j = js;
+ })
+ ).then(function() {
+ var useTemplate = c.indexOf(TEMPLATE_MARKER) >= 0;
+ var string =
+ '" +
+ h +
+ '";
+ stringToZip(string, function(zip) {
+ setFileName("✒️" + url);
+ var title = QS("#doc-title").innerText;
+ setTimeout(function() {
+ var data = (useTemplate ? "" : DATA_PREFIX_BXZE) + zip;
+ importedFileData = data;
+ updateLink(data, title);
+ }, 300);
+ });
+ });
+}
+
+function handleInput(e) {
+ updateBodyClass();
+ var text = content.innerText;
+ var title = QS("#doc-title").innerText;
+
+ var rawHTML = text.indexOf("") > 0;
+ if (rawHTML) {
+ text = text.replace(/[ |\t]+/g, " ").replace(/> + <");
+ } else {
+ text = content.innerHTML;
+ }
+
+ if (text.trim().length) {
+ stringToZip(text, function(zip) {
+ if (rawHTML) {
+ updateLink(DATA_PREFIX_BXZE + zip, title);
+ } else {
+ updateLink("?" + zip, title);
+ }
+ });
+ setFileName("");
+ } else if (importedFileData) {
+ updateLink(importedFileData, title);
+ } else {
+ updateLink("");
+ }
+}
+
+var maxLengths = {
+ // "#twitter": 4088,
+ // "#bitly": 2048,
+ "#qrcode": 2953
+};
+
+function updateLink(url, title, push) {
+ if (title) title = encodeURIComponent(title.trim().replace(/\s/g, "_"));
+ if (url.length) {
+ url = "/#" + (title || "") + "/" + url;
+ } else {
+ url = "/edit";
+ }
+ var hash = location.hash;
+ if (push || !hash || !hash.length) {
+ window.history.pushState(content.innerHTML, null, url);
+ } else {
+ window.history.replaceState(content.innerHTML, null, url);
+ }
+ var length = location.href.length;
+
+ QS("#length").innerText = length + " bytes";
+ QS("#length").href = url;
+ for (var key in maxLengths) {
+ var maxLength = maxLengths[key];
+ if (length > maxLength) {
+ QS(key).classList.add("invalid");
+ } else {
+ QS(key).classList.remove("invalid");
+ }
+ }
+}
+
+function makeQRCode() {
+ var url =
+ "https://zxing.org/w/chart?cht=qr&chs=548x548&chld=L|1&choe=UTF-8&chl=" +
+ encodeURIComponent(location.href);
+ this.href = url;
+}
+
+function toggleMenu() {
+ QS("#toolbar").classList.toggle("menu-visible");
+}
+function copyThenLink() {
+ copyLink();
+ return confirm("Copied your link to the clipboard. Paste it to share.");
+}
+function copyLink() {
+ var text = location.href;
+ 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);
+}
+
+function saveLink() {
+ var url = "/" + location.hash;
+ window.history.pushState(null, null, url);
+ location.reload();
+}
+
+function tweetLink() {
+ var url =
+ "https://twitter.com/intent/tweet?url=" + encodeURIComponent(location.href);
+ window.open(url, "_blank");
+ return false;
+}
diff --git a/docs/v1/favicon.ico b/docs/v1/favicon.ico
new file mode 100644
index 0000000..08dc97b
Binary files /dev/null and b/docs/v1/favicon.ico differ
diff --git a/docs/legacy/index-min.css b/docs/v1/index-min.css
similarity index 100%
rename from docs/legacy/index-min.css
rename to docs/v1/index-min.css
diff --git a/docs/legacy/index-min.js b/docs/v1/index-min.js
similarity index 100%
rename from docs/legacy/index-min.js
rename to docs/v1/index-min.js
diff --git a/docs/legacy/index.css b/docs/v1/index.css
similarity index 100%
rename from docs/legacy/index.css
rename to docs/v1/index.css
diff --git a/docs/legacy/index.html b/docs/v1/index.html
similarity index 100%
rename from docs/legacy/index.html
rename to docs/v1/index.html
diff --git a/docs/legacy/index.js b/docs/v1/index.js
similarity index 100%
rename from docs/legacy/index.js
rename to docs/v1/index.js
diff --git a/docs/legacy/index.src.html b/docs/v1/index.src.html
similarity index 100%
rename from docs/legacy/index.src.html
rename to docs/v1/index.src.html
diff --git a/docs/v1/manifest.appcache b/docs/v1/manifest.appcache
new file mode 100644
index 0000000..5255e9a
--- /dev/null
+++ b/docs/v1/manifest.appcache
@@ -0,0 +1,2 @@
+CACHE MANIFEST
+# v27
\ No newline at end of file