diff --git a/data.min.js b/data.min.js new file mode 100644 index 0000000..3da1278 --- /dev/null +++ b/data.min.js @@ -0,0 +1 @@ +var BASE64_MARKER=";base64,";var LZMA64_MARKER=";bxze64,";function compressDataURI(dataURI,callback){var base64Index=dataURI.indexOf(BASE64_MARKER);var base64=dataURI.substring(base64Index+BASE64_MARKER.length);stringToZip(base64ToByteArray(base64),function(result){callback(dataURI.substring(0,base64Index)+LZMA64_MARKER+result)})}function base64ToByteArray(base64){var raw=window.atob(base64);var rawLength=raw.length;var array=new Uint8Array(new ArrayBuffer(rawLength));for(i=0;i0){var base64=dataURI.substring(base64Index+LZMA64_MARKER.length);zipToString(base64,function(result){stringToData(result,function(data){if(!data)return callback(undefined);callback(dataURI.substring(0,base64Index)+BASE64_MARKER+(preamble||"")+data.split(",")[1])})})}else{callback(dataURI)}}function zipToString(data,callback){var array=base64ToByteArray(data);LZMA.decompress(array,function(result,error){if(!(typeof result==="string"))result=new Uint8Array(result);if(error)console.error(error);callback(result)})}function stringToData(string,callback){if(!string.length)return callback("");var a=new FileReader;a.onload=function(e){callback(e.target.result.replace())};a.readAsDataURL(new Blob([string],{encoding:"UTF-8",type:"text/html;charset=UTF-8"}))}function dataToString(data,callback){var blob=dataURItoBlob(data);var reader=new FileReader;reader.onload=function(e){callback(reader.result)};reader.readAsText(blob)}function dataURItoBlob(dataURI){var byteString=atob(dataURI.split(",")[1]);var mimeString=dataURI.split(",")[0].split(":")[1].split(";")[0];var arrayBuffer=new ArrayBuffer(byteString.length);var _ia=new Uint8Array(arrayBuffer);for(var i=0;i - + itty.bitty +
-Itty bitty things
-can be shared within a link—
-type here to compose. -

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

about itty bitty

+
+ + - - QR Code -
+  menu +
\ No newline at end of file diff --git a/edit.js b/edit.js index f64a44c..bf37ccf 100644 --- a/edit.js +++ b/edit.js @@ -1,9 +1,11 @@ -var $ = document.querySelector.bind(document) -var $$ = document.querySelectorAll.bind(document) +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_BAZE = 'data:text/html;charset=utf-8;baze64,' +var DATA_PREFIX_BXZE = 'data:text/html;charset=utf-8;bxze64,' + +var b = document.documentElement.setAttribute('data-useragent', navigator.userAgent); var content = undefined window.onload = function() { @@ -15,17 +17,25 @@ window.onload = function() { content = document.getElementById("content"); 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); - $('#qrcode').onclick = makeQRCode - $('#copy').onclick = copyLink + QS('#qrcode').onclick = makeQRCode + QS('#twitter').onclick = copyThenLink + QS('#copy').onclick = copyLink + QS('#menu').onclick = toggleMenu var hash = window.location.hash.substring(1) + if (hash.length) { - updateLink(hash) - if (hash.startsWith('!')) { + 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); } @@ -46,6 +56,7 @@ function updateBodyClass() { } else { document.body.classList.remove("edited") } + document.body.classList.add("loaded") } function handleDrop(e) { @@ -63,8 +74,8 @@ function handleDrop(e) { console.log("Verified", url == url3,) }) if (ratio > 0.95) url2 = url; - if (e.altKey) url2 = url2.replace(DATA_PREFIX_BAZE, "!") - updateLink(url2, true) + if (e.altKey) url2 = url2.replace(DATA_PREFIX_BXZE, "!") + updateLink(url2, file.name, true) setFileContent('📄' + file.name) }) }, false); @@ -77,6 +88,8 @@ function setFileContent(name) { setContent(' ' + name + '

'); } + +// 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; @@ -93,7 +106,6 @@ function handleKey(e) { } else { handled = false } - } else if (e.metaKey) { if (code == 'K'.charCodeAt(0)) { handled = true; @@ -128,36 +140,37 @@ function fetchCodepen(url) { stringToZip(string, function(zip) { setFileContent('✒️' + url) setTimeout(function() { - updateLink((useTemplate ? "," : DATA_PREFIX_BAZE) + zip) + updateLink((useTemplate ? "" : DATA_PREFIX_BXZE) + zip) }, 300); }); }); } -function stripPrefix(url) { - if (url) { - var dataRE = /data:(text\/html[^,]*)(;base64),(.*)/ - var match = url.match(dataRE); - if (match) return "!" + match[3]; - } - return url; -} +// function stripPrefix(url) { +// if (url) { +// var dataRE = /data:(text\/html[^,]*)(;base64),(.*)/ +// var match = url.match(dataRE); +// if (match) return "!" + match[3]; +// } +// return url; +// } function handleInput(e) { updateBodyClass(); - var text = content.innerText + var text = content.innerText; + var title = QS("#doc-title").innerText; + var strip = false; if (text.indexOf(" 0) { text = text.replace(/[\n|\t]+/g,' ').replace(/> + <') } else { - var title = text.split("\n")[0] text = content.innerHTML strip = true } if (text.trim().length) { stringToZip(text, function(zip) { - updateLink("!" + zip) + updateLink("?" + zip, title) }); } else { updateLink("") @@ -166,11 +179,18 @@ function handleInput(e) { } var maxLengths = { - "#qrcode": 2610, + // "#twitter": 4088, + // "#bitly": 2048, + "#qrcode": 2953, } -function updateLink(url, push) { - url = "/#" + url +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); @@ -179,14 +199,14 @@ function updateLink(url, push) { } var length = location.href.length - $('#length').innerText = length + " bytes" - $('#length').href = url + QS('#length').innerText = length + " bytes" + QS('#length').href = url for (var key in maxLengths) { var maxLength = maxLengths[key] if (length > maxLength) { - $(key).classList.add("invalid") + QS(key).classList.add("invalid") } else { - $(key).classList.remove("invalid") + QS(key).classList.remove("invalid") } }; @@ -207,6 +227,13 @@ function makeQRCode() { //https://developers.google.com/chart/infographics/docs/qr_codes } +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"); @@ -215,6 +242,11 @@ function copyLink() { dummy.select(); document.execCommand("copy"); document.body.removeChild(dummy); + + document.body.addClass("copied") + setTimeout(function() { + document.body.removeClass("copied") + }, 300); } function saveLink() { diff --git a/favicon.js b/favicon.js new file mode 100644 index 0000000..be6c174 --- /dev/null +++ b/favicon.js @@ -0,0 +1,54 @@ +(function() { + var FavEmoji = function(unicode) { + 'use strict'; + var + canvas = document.createElement('canvas'), + getContext = function(w) { + canvas.width = canvas.height = w; + context = canvas.getContext('2d'); + context.font = 'normal normal normal 32px/' + w + 'px sans'; + context.textBaseline = 'middle'; + return context; + }, + hex2char = function(hex) { + var + result = '', + n = parseInt(hex, 16); + if(n <= 0xFFFF) + result += String.fromCharCode(n); + else if(n <= 0x10FFFF) { + n -= 0x10000 + result += String.fromCharCode(0xD800 | (n >> 10)) + String.fromCharCode(0xDC00 | (n & 0x3FF)); + } + return result; + }, + context = getContext(32), + content = unicode.replace(/[Uu]\+10([A-Fa-f0-9]{4})/g, function(str, match) { + return hex2char('10' + matches); + }).replace(/[Uu]\+([A-Fa-f0-9]{1,5})/g, function(str, match) { + return hex2char(match); + }), + iconWidth, + link = document.createElement('link'); + if(!canvas.toDataURL || !document.querySelectorAll) + return; + iconWidth = context.measureText(content).width; + if(iconWidth > canvas.width) + context = getContext(iconWidth); + context.fillText(content, (canvas.width - iconWidth) / 2, canvas.height / 2); + link.setAttribute('rel', 'icon'); + link.setAttribute('type', 'image/png'); + link.setAttribute('href', canvas.toDataURL('image/png')); + for(var icons = document.querySelectorAll('link[rel*=icon]'), i = 0, l = icons.length; i < l; i++) + icons[i].parentNode.removeChild(icons[i]); + document.getElementsByTagName('head')[0].appendChild(link); + }; + if(typeof define !== 'undefined' && define.amd) + define([], function() { + return FavEmoji; + }); + else if(typeof module !== 'undefined' && module.exports) + module.exports = FavEmoji; + else + this.FavEmoji = FavEmoji; +})(); \ No newline at end of file diff --git a/firebase.json b/firebase.json index 148d67f..b9d5cdd 100644 --- a/firebase.json +++ b/firebase.json @@ -5,7 +5,8 @@ "firebase.json", "**/.*", "**/node_modules/**", - "samples/**" + "samples/**", + "**/.git/**" ], "rewrites": [ { diff --git a/index.html b/index.html index ada6e42..48d928a 100644 --- a/index.html +++ b/index.html @@ -1,46 +1,55 @@ -itty bitty - - + + + + + - +edit + + + +edit + + + \ No newline at end of file diff --git a/manifest.appcache b/manifest.appcache index d583d17..e381f20 100644 --- a/manifest.appcache +++ b/manifest.appcache @@ -1,7 +1,4 @@ CACHE MANIFEST CACHE: -/ -/data.js -/favicon.ico -/src/lzma-d-min.js \ No newline at end of file +/ \ No newline at end of file