diff --git a/docs/index.html b/docs/index.html index 5f4b0d3..a900249 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,10 +2,10 @@
itty.bitty is experimental technology that renders linked content from outside sources. Learn more. @@ -15,4 +15,5 @@ you would show any insecure web page.
edit +
Download
diff --git a/docs/index.src/index-min.css b/docs/index.src/index-min.css index a5b1624..f86f66c 100644 --- a/docs/index.src/index-min.css +++ b/docs/index.src/index-min.css @@ -1 +1 @@ -body{font-family:sans-serif}#iframe{border:0;position:absolute;top:0;left:0;width:100%;height:100%}#edit{font-family:monospace;font-weight:bold;color:rgba(0,0,0,0.54);position:absolute;z-index:100;position:absolute;top:.85em;right:1em;display:none}#edit:not(:hover){text-decoration:none}#warning{position:absolute;border-radius:4px;background-color:#feecc2;padding:1em;font-size:16px;width:20em;z-index:100;top:10vh;left:50vw;margin-left:-10em}#warning:empty{display:none}body.toasting #iframe,body.toasting #edit{opacity:.5;pointer-events:none}body.toasting #toast{box-sizing:border-box;background-color:#feecc2;border-radius:4px;font-size:13px;left:50%;top:10px;margin-left:-160px;padding:1em;position:absolute;max-width:320px;z-index:101}body:not(.toasting) #toast,body.toasting #warning{display:none} +body{font-family:sans-serif}#iframe{border:0;position:absolute;top:0;left:0;width:100%;height:100%}#edit{font-family:monospace;font-weight:bold;color:rgba(0,0,0,0.54);position:absolute;z-index:100;position:absolute;top:.85em;right:1em;display:none}#edit:not(:hover){text-decoration:none}#warning{position:absolute;border-radius:4px;background-color:#feecc2;padding:1em;font-size:16px;width:20em;z-index:100;top:10vh;left:50vw;margin-left:-10em}#warning:empty{display:none}body.toasting #iframe,body.toasting #edit{opacity:.5;pointer-events:none}body.toasting #toast{box-sizing:border-box;background-color:#feecc2;border-radius:4px;font-size:13px;left:50%;top:10px;margin-left:-160px;padding:1em;position:absolute;max-width:320px;z-index:101}body:not(.toasting) #toast,body.toasting #warning{display:none}body:not(.download) #download{display:none}#download{background:#fafafa;width:100vw;height:100vh;position:absolute;top:0;left:0;display:flex;text-decoration:none;color:black;justify-content:center;align-items:center;flex-direction:column;font-size:14px}#dl-image{width:128px;height:128px;background-position: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");padding:20px 32px;box-sizing:border-box;display:flex;justify-content:center;align-items:center;color:rgba(0,0,0,0.3);font-weight:bold}#dl-button{text-decoration:none;background:gray;color:white;padding:.5em 1em;border-radius:2em;display:none}#dl-button:hover{background:black}#dl-name{margin-bottom:2em} diff --git a/docs/index.src/index-min.js b/docs/index.src/index-min.js index 53ae692..5f24b0f 100644 --- a/docs/index.src/index-min.js +++ b/docs/index.src/index-min.js @@ -1 +1 @@ -var HEAD_TAGS="PGJhc2UgdGFyZ2V0PSJfdG9wIj4K";var HEAD_TAGS_EXTENDED="PG1ldGEgY2hhcnNldD0idXRmLTgiPjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgiPjxiYXNlIHRhcmdldD0iX3RvcCI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj5ib2R5e21hcmdpbjowIGF1dG87cGFkZGluZzoxMnZtaW4gMTB2bWluO21heC13aWR0aDozNWVtO2xpbmUtaGVpZ2h0OjEuNWVtO2ZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCxzYW5zLXNlcmlmO3dvcmQtd3JhcDogYnJlYWstd29yZDt9PC9zdHlsZT4g";function dismiss(){if(document.getElementById("never").checked)window.localStorage.setItem("toasted",true);document.body.classList.remove("toasting")}window.onhashchange=window.onload=function(){var hash=window.location.hash.substring(1);if(hash.length<3){location.href="/edit"}else{var iframe=document.getElementById("iframe");var link=document.getElementById("edit");var preamble=undefined;var slashIndex=hash.indexOf("/");var title=hash.substring(0,slashIndex);document.title=title.length?decodeURIComponent(title.replace(/_/g," ")):location.hostname;hash=hash.substring(slashIndex+1);var editable=hash.charAt(0)=="?";if(editable){hash=hash.substring(1)}if(hash.indexOf("data:")!=0){var colon=hash.indexOf(":");if(colon>0&&colon<15){document.body.classList.remove("toasting");return window.location.replace(hash)}var compressed=true;preamble=HEAD_TAGS_EXTENDED;hash="data:text/html;charset=utf-8;"+(compressed?"bxze64,":"base64,")+hash}else if(hash.indexOf("data:text/html;")==0){preamble=HEAD_TAGS}else if(hash.indexOf("data:text/plain;")==0){preamble=HEAD_TAGS_EXTENDED}link.onclick=function(){location.href="/edit"+location.hash};var isIE=navigator.userAgent.match(/rv:11/);var isEdge=navigator.userAgent.match(/Edge\//);if((isEdge||isIE)&&location.href.length==2083){document.getElementById("warning").innerHTML='Edge only supports shorter URLs (maximum 2083 bytes).
Larger sites may require a different browser.
Learn more'}decompressDataURI(hash,preamble,(function(hash){if(!hash)return;iframe.sandbox="allow-downloads allow-scripts allow-forms allow-top-navigation allow-popups allow-modals allow-popups-to-escape-sandbox";if(!isIE){if(hash)iframe.src=hash}else{dataToString(hash,(function(content){var doc=iframe.contentWindow.document;doc.open();doc.write(content);doc.close()}))}}));var link=document.getElementById("edit");link.href="/edit"+location.hash;link.style.display=editable?"block":"none"}}; +var HEAD_TAGS="PGJhc2UgdGFyZ2V0PSJfdG9wIj4K";var HEAD_TAGS_EXTENDED="PG1ldGEgY2hhcnNldD0idXRmLTgiPjxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgiPjxiYXNlIHRhcmdldD0iX3RvcCI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj5ib2R5e21hcmdpbjowIGF1dG87cGFkZGluZzoxMnZtaW4gMTB2bWluO21heC13aWR0aDozNWVtO2xpbmUtaGVpZ2h0OjEuNWVtO2ZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCxzYW5zLXNlcmlmO3dvcmQtd3JhcDogYnJlYWstd29yZDt9PC9zdHlsZT4g";function dismiss(){if(document.getElementById("never").checked)window.localStorage.setItem("toasted",true);document.body.classList.remove("toasting")}var validTypes=["image/svg+xml"];window.onhashchange=window.onload=function(){var hash=window.location.hash.substring(1);if(hash.length<3){location.href="/edit"}else{var iframe=document.getElementById("iframe");var link=document.getElementById("edit");var preamble=undefined;var download=undefined;var slashIndex=hash.indexOf("/");var title=hash.substring(0,slashIndex);document.title=title.length?decodeURIComponent(title.replace(/_/g," ")):location.hostname;hash=hash.substring(slashIndex+1);var editable=hash.charAt(0)=="?";if(editable){hash=hash.substring(1)}if(hash.indexOf("data:")!=0){var colon=hash.indexOf(":");if(colon>0&&colon<15){document.body.classList.remove("toasting");return window.location.replace(hash)}var compressed=true;preamble=HEAD_TAGS_EXTENDED;hash="data:text/html;charset=utf-8;"+(compressed?"bxze64,":"base64,")+hash}else if(hash.indexOf("data:text/html;")==0){preamble=HEAD_TAGS}else if(hash.indexOf("data:text/plain;")==0){preamble=HEAD_TAGS_EXTENDED}else{let match=hash.match(/data:([^;]+)/);let type=match[1];console.log("match",match,type);if(!validTypes.includes(type)){console.log("unknown type, rendering as download");let extension=title.split(".");document.querySelector("#dl-name").innerText=title;if(extension.length>1)document.querySelector("#dl-image").innerText=extension.pop();download=document.querySelector("#download");download.download=title}}link.onclick=function(){location.href="/edit"+location.hash};var isIE=navigator.userAgent.match(/rv:11/);var isEdge=navigator.userAgent.match(/Edge\//);if((isEdge||isIE)&&location.href.length==2083){document.getElementById("warning").innerHTML='Edge only supports shorter URLs (maximum 2083 bytes).
Larger sites may require a different browser.
Learn more'}decompressDataURI(hash,preamble,(function(dataURL){if(!dataURL)return;iframe.sandbox="allow-downloads allow-scripts allow-forms allow-top-navigation allow-popups allow-modals allow-popups-to-escape-sandbox";if(download){try{download.href=dataURL;download.click();document.body.classList.add("download")}catch(e){iframe.src=dataURL}}else if(!isIE){iframe.src=dataURL}else{dataToString(dataURL,(function(content){var doc=iframe.contentWindow.document;doc.open();doc.write(content);doc.close()}))}}));var link=document.getElementById("edit");link.href="/edit"+location.hash;link.style.display=editable?"block":"none"}}; diff --git a/docs/index.src/index.css b/docs/index.src/index.css index 5e6f4bc..6ff7702 100644 --- a/docs/index.src/index.css +++ b/docs/index.src/index.css @@ -60,3 +60,52 @@ body:not(.toasting) #toast, body.toasting #warning { display: none; } + +body:not(.download) #download { + display:none; +} + +#download { + background:#fafafa; + width:100vw; + height:100vh; + position:absolute; + top:0; + left:0; + display:flex; + text-decoration: none; + color:black; + justify-content: center; + align-items: center; + flex-direction: column; + font-size:14px; + +} +#dl-image { + width:128px; + height:128px; + background-position: 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"); + padding: 20px 32px; + box-sizing: border-box; + display:flex; + justify-content: center; + align-items: center;; + color:rgba(0,0,0,0.3); + font-weight:bold; +} +#dl-button { + text-decoration:none; + background:gray; + color:white; + padding:0.5em 1em; + border-radius:2em; + display:none; +} +#dl-button:hover { + background:black; +} +#dl-name { +margin-bottom:2em; +} diff --git a/docs/index.src/index.html b/docs/index.src/index.html index 001b43d..97f1908 100644 --- a/docs/index.src/index.html +++ b/docs/index.src/index.html @@ -16,4 +16,5 @@ you would show any insecure web page.
edit +
Download
\ No newline at end of file diff --git a/docs/index.src/index.js b/docs/index.src/index.js index f0921e5..48fbee7 100644 --- a/docs/index.src/index.js +++ b/docs/index.src/index.js @@ -7,6 +7,8 @@ function dismiss() { document.body.classList.remove("toasting") } +var validTypes = ["image/svg+xml"] + window.onhashchange = window.onload = function() { var hash = window.location.hash.substring(1); if (hash.length < 3) { @@ -17,6 +19,7 @@ window.onhashchange = window.onload = function() { var iframe = document.getElementById("iframe"); var link = document.getElementById("edit"); var preamble = undefined; + var download = undefined; var slashIndex = hash.indexOf("/"); var title = hash.substring(0, slashIndex); @@ -45,6 +48,19 @@ window.onhashchange = window.onload = function() { preamble = HEAD_TAGS; } else if (hash.indexOf("data:text/plain;") == 0) { preamble = HEAD_TAGS_EXTENDED; + } else { + let match = hash.match(/data:([^;]+)/) + let type = match[1]; + console.log("match", match, type) + + if (!validTypes.includes(type)) { + console.log("unknown type, rendering as download") + let extension = title.split(".") + document.querySelector("#dl-name").innerText = title; + if (extension.length > 1) document.querySelector("#dl-image").innerText = extension.pop(); + download = document.querySelector("#download"); + download.download = title; + } } link.onclick = function() { location.href = "/edit" + location.hash; @@ -56,14 +72,22 @@ window.onhashchange = window.onload = function() { document.getElementById("warning").innerHTML = 'Edge only supports shorter URLs (maximum 2083 bytes).
Larger sites may require a different browser.
Learn more'; } - decompressDataURI(hash, preamble, function(hash) { - if (!hash) return; - iframe.sandbox = - "allow-downloads allow-scripts allow-forms allow-top-navigation allow-popups allow-modals allow-popups-to-escape-sandbox"; - if (!isIE) { - if (hash) iframe.src = hash; + decompressDataURI(hash, preamble, function(dataURL) { + if (!dataURL) return; + iframe.sandbox = "allow-downloads allow-scripts allow-forms allow-top-navigation allow-popups allow-modals allow-popups-to-escape-sandbox"; + + if (download) { + try { + download.href = dataURL + download.click(); + document.body.classList.add("download"); + } catch (e) { + iframe.src = dataURL; + } + } else if (!isIE) { + iframe.src = dataURL; } else { - dataToString(hash, function(content) { + dataToString(dataURL, function(content) { var doc = iframe.contentWindow.document; doc.open(); doc.write(content); diff --git a/firebase.json b/firebase.json index 4a78365..b4e14b4 100644 --- a/firebase.json +++ b/firebase.json @@ -1,6 +1,6 @@ { "hosting": { - "public": "public", + "public": "docs", "ignore": [ "firebase.json", "**/.*",