diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | assets/iosevka-aile-regular.woff | bin | 0 -> 11672 bytes | |||
-rw-r--r-- | assets/iosevka-aile-regular.woff2 | bin | 0 -> 9516 bytes | |||
-rw-r--r-- | assets/main.js | 2 | ||||
-rw-r--r-- | assets/style.css | 2 | ||||
-rw-r--r-- | css/main.scss | 9 | ||||
-rw-r--r-- | fonts/iosevka-aile-regular.ttf | bin | 0 -> 497504 bytes | |||
-rw-r--r-- | gopherproxy.go | 26 | ||||
-rw-r--r-- | js/main.ts | 32 | ||||
-rw-r--r-- | template.go | 13 |
10 files changed, 77 insertions, 9 deletions
@@ -10,6 +10,8 @@ build: clean | |||
10 | tsc --strict --module none --outFile /dev/stdout js/* | terser --compress --mangle -o assets/main.js -- | 10 | tsc --strict --module none --outFile /dev/stdout js/* | terser --compress --mangle -o assets/main.js -- |
11 | pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff' --with-zopfli --output-file='assets/iosevka-term-ss03-regular.woff' | 11 | pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff' --with-zopfli --output-file='assets/iosevka-term-ss03-regular.woff' |
12 | pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff2' --output-file='assets/iosevka-term-ss03-regular.woff2' | 12 | pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff2' --output-file='assets/iosevka-term-ss03-regular.woff2' |
13 | pyftsubset fonts/iosevka-aile-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff' --with-zopfli --output-file='assets/iosevka-aile-regular.woff' | ||
14 | pyftsubset fonts/iosevka-aile-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff2' --output-file='assets/iosevka-aile-regular.woff2' | ||
13 | go build -o ./gopherproxy ./cmd/gopherproxy/main.go | 15 | go build -o ./gopherproxy ./cmd/gopherproxy/main.go |
14 | 16 | ||
15 | profile: | 17 | profile: |
diff --git a/assets/iosevka-aile-regular.woff b/assets/iosevka-aile-regular.woff new file mode 100644 index 0000000..fa16c36 --- /dev/null +++ b/assets/iosevka-aile-regular.woff | |||
Binary files differ | |||
diff --git a/assets/iosevka-aile-regular.woff2 b/assets/iosevka-aile-regular.woff2 new file mode 100644 index 0000000..fa3b36c --- /dev/null +++ b/assets/iosevka-aile-regular.woff2 | |||
Binary files differ | |||
diff --git a/assets/main.js b/assets/main.js index a30a250..be36478 100644 --- a/assets/main.js +++ b/assets/main.js | |||
@@ -1 +1 @@ | |||
"use strict";var KeyValueStore=function(){function e(e){this.data=e;for(var t=0,n=Object.keys(e);t<n.length;t++){var a=n[t],l=e[a];if(l.valueRange&&-1===l.valueRange.indexOf(l.value))throw new Error('Invalid value "'+l.value+'" for ID "'+a+'"')}}return e.prototype.getValue=function(e){return this.data[e].value},e.prototype.setValue=function(e,t){var n=this.data[e];if(n.valueRange&&-1===n.valueRange.indexOf(t))throw new Error('Invalid value "'+t+'" for ID "'+e+'"');n.value=t,n.callbacks&&n.callbacks.forEach((function(e){e(t)}))},e.prototype.cycleValue=function(e,t){void 0===t&&(t=1);var n=this.data[e];if(!n)throw new Error('Invalid ID "'+e+'"');var a=n.value;if(n.valueRange){var l=n.valueRange.indexOf(a)+t;l>=n.valueRange.length?l=0:l<0&&(l=n.valueRange.length-1),a=n.value=n.valueRange[l]}else{if("number"!=typeof a)throw new Error("Can't cycle \""+e+'"');a+=t,n.value=a}return n.callbacks&&n.callbacks.forEach((function(e){e(a)})),a},e.prototype.addCallback=function(e,t){var n=this.data[e];n.callbacks||(n.callbacks=[]),n.callbacks.push(t)},e}();function ensureSetting(e,t){var n=localStorage.getItem(e);return null===n&&(n=t,localStorage.setItem(e,n)),n}var settings=new KeyValueStore({wordWrap:{value:"1"===ensureSetting("word-wrap","1"),callbacks:[function(e){localStorage.setItem("word-wrap",e?"1":"0")}],valueRange:[!1,!0]},imagePreviews:{value:"1"===ensureSetting("image-previews","1"),callbacks:[function(e){localStorage.setItem("image-previews",e?"1":"0")}],valueRange:[!1,!0]},clickablePlainLinks:{value:"1"===ensureSetting("clickable-plain-links","1"),callbacks:[function(e){localStorage.setItem("clickable-plain-links",e?"1":"0")}],valueRange:[!1,!0]}});function generateImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length,n=function(){var n=e[t],a=n.href.replace(/^(.*?)\/I/,"$1/T"),l=document.createTextNode("\n"),i=document.createElement("span");i.classList.add("type-annotation"),i.textContent=" -> ";var r=document.createElement("img");r.src=a,r.addEventListener("load",(function(e){r.classList.remove("faded")}));var s=document.createElement("a");s.classList.add("img-preview"),s.href=n.href,s.addEventListener("click",(function(e){return e.preventDefault(),r.classList.add("faded"),r.classList.contains("expanded")?(r.classList.remove("expanded"),r.src=a):(r.classList.add("expanded"),r.src=s.href),!1})),s.append(r),n.parentNode.insertBefore(s,n.nextSibling),n.parentNode.insertBefore(i,s),n.parentNode.insertBefore(l,i)};t--;)n()}function removeImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length;t--;)for(var n=e[t],a=3;a--&&n.nextSibling;)n.nextSibling.remove()}function generateMarkupForPlainLinks(){if(document.body.classList.contains("is-plain")){var e=document.getElementsByClassName("content")[0];e.innerHTML=e.innerHTML.replace(/\b[a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*/g,(function(e){var t=e;return 0===t.indexOf("gopher://")&&(t=t.replace(/^gopher:\/\/(.*)$/,location.origin+"/$1")),'<a href="'+t+'">'+e+"</a>"})),e.innerHTML=e.innerHTML.replace(/\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g,(function(e){return'<a href="'+e+'">'+e+"</a>"}))}}function removeMarkupForPlainLinks(){if(document.body.classList.contains("is-plain"))for(var e=document.getElementsByClassName("content")[0],t=e.getElementsByTagName("a"),n=t.length;n--;){var a=t[n],l=document.createTextNode(a.textContent);e.replaceChild(l,a)}}!function(){for(var e=document.getElementsByClassName("link--QRY"),t=e.length;t--;)e[t].addEventListener("click",(function(e){e.preventDefault();var t=prompt("Please enter required input: ","");return null!==t&&""!==t&&(window.location.href=e.target.href+"?"+t),!1}))}(),function(){for(var e=document.getElementsByClassName("location__prefix"),t=e.length;t--;)e[t].addEventListener("click",(function(e){e.preventDefault();var t=prompt("Please enter new location: ","");return null!==t&&""!==t.trim()&&(0===(t=t.trim()).indexOf("gopher://")&&(t=t.substring(9)),window.location.href=window.location.origin+"/"+t),!1}))}(),function(){var e=document.getElementsByClassName("content")[0],t=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0],n=function(e,n){void 0===n&&(n=!1),e?generateImageThumbnails():n||removeImageThumbnails(),t.textContent=e?"[yes]":"[no]"};t.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1})),n(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",n);var a=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0],l=function(t){t?e.classList.add("content--wrap"):e.classList.remove("content--wrap"),a.textContent=t?"[yes]":"[no]"};a.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1})),l(settings.getValue("wordWrap")),settings.addCallback("wordWrap",l);var i=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0],r=function(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),i.textContent=e?"[yes]":"[no]"};i.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1})),r(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",r)}(),function(){for(var e=document.getElementsByClassName("modal"),t=e.length,n=function(){var n=e[t],a=n.getElementsByClassName("modal__content")[0],l=n.getElementsByClassName("modal__close-btn")[0];document.addEventListener("click",(function(e){n.classList.contains("modal--visible")&&(e.target===a||a.contains(e.target)||(n.classList.remove("modal--visible"),e.preventDefault(),e.stopPropagation()))}),!0),document.addEventListener("keydown",(function(e){n.classList.contains("modal--visible")&&27===e.keyCode&&n.classList.remove("modal--visible")})),l.addEventListener("click",(function(e){return e.preventDefault(),n.classList.remove("modal--visible"),!1}))};t--;)n();var a=document.getElementsByClassName("settings-btn")[0],l=document.getElementsByClassName("modal--settings")[0];a.addEventListener("click",(function(e){return e.preventDefault(),l.classList.add("modal--visible"),!1}))}(); \ No newline at end of file | "use strict";var KeyValueStore=function(){function e(e){this.data=e;for(var t=0,n=Object.keys(e);t<n.length;t++){var a=n[t],l=e[a];if(l.valueRange&&-1===l.valueRange.indexOf(l.value))throw new Error('Invalid value "'+l.value+'" for ID "'+a+'"')}}return e.prototype.getValue=function(e){return this.data[e].value},e.prototype.setValue=function(e,t){var n=this.data[e];if(n.valueRange&&-1===n.valueRange.indexOf(t))throw new Error('Invalid value "'+t+'" for ID "'+e+'"');n.value=t,n.callbacks&&n.callbacks.forEach((function(e){e(t)}))},e.prototype.cycleValue=function(e,t){void 0===t&&(t=1);var n=this.data[e];if(!n)throw new Error('Invalid ID "'+e+'"');var a=n.value;if(n.valueRange){var l=n.valueRange.indexOf(a)+t;l>=n.valueRange.length?l=0:l<0&&(l=n.valueRange.length-1),a=n.value=n.valueRange[l]}else{if("number"!=typeof a)throw new Error("Can't cycle \""+e+'"');a+=t,n.value=a}return n.callbacks&&n.callbacks.forEach((function(e){e(a)})),a},e.prototype.addCallback=function(e,t){var n=this.data[e];n.callbacks||(n.callbacks=[]),n.callbacks.push(t)},e}();function ensureSetting(e,t){var n=localStorage.getItem(e);return null===n&&(n=t,localStorage.setItem(e,n)),n}var settings=new KeyValueStore({wordWrap:{value:"1"===ensureSetting("word-wrap","1"),callbacks:[function(e){localStorage.setItem("word-wrap",e?"1":"0")}],valueRange:[!1,!0]},monospaceFont:{value:"1"===ensureSetting("monospace-font","1"),callbacks:[function(e){localStorage.setItem("monospace-font",e?"1":"0")}],valueRange:[!1,!0]},imagePreviews:{value:"1"===ensureSetting("image-previews","1"),callbacks:[function(e){localStorage.setItem("image-previews",e?"1":"0")}],valueRange:[!1,!0]},clickablePlainLinks:{value:"1"===ensureSetting("clickable-plain-links","1"),callbacks:[function(e){localStorage.setItem("clickable-plain-links",e?"1":"0")}],valueRange:[!1,!0]}});function generateImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length,n=function(){var n=e[t],a=n.href.replace(/^(.*?)\/I/,"$1/T"),l=document.createTextNode("\n"),s=document.createElement("span");s.classList.add("type-annotation"),s.textContent=" -> ";var i=document.createElement("img");i.src=a,i.addEventListener("load",(function(e){i.classList.remove("faded")}));var o=document.createElement("a");o.classList.add("img-preview"),o.href=n.href,o.addEventListener("click",(function(e){return e.preventDefault(),i.classList.add("faded"),i.classList.contains("expanded")?(i.classList.remove("expanded"),i.src=a):(i.classList.add("expanded"),i.src=o.href),!1})),o.append(i),n.parentNode.insertBefore(o,n.nextSibling),n.parentNode.insertBefore(s,o),n.parentNode.insertBefore(l,s)};t--;)n()}function removeImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length;t--;)for(var n=e[t],a=3;a--&&n.nextSibling;)n.nextSibling.remove()}function generateMarkupForPlainLinks(){if(document.body.classList.contains("is-plain")){var e=document.getElementsByClassName("content")[0];e.innerHTML=e.innerHTML.replace(/\b[a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*/g,(function(e){var t=e;return 0===t.indexOf("gopher://")&&(t=t.replace(/^gopher:\/\/(.*)$/,location.origin+"/$1")),'<a href="'+t+'">'+e+"</a>"})),e.innerHTML=e.innerHTML.replace(/\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g,(function(e){return'<a href="'+e+'">'+e+"</a>"}))}}function removeMarkupForPlainLinks(){if(document.body.classList.contains("is-plain"))for(var e=document.getElementsByClassName("content")[0],t=e.getElementsByTagName("a"),n=t.length;n--;){var a=t[n],l=document.createTextNode(a.textContent);e.replaceChild(l,a)}}!function(){for(var e=document.getElementsByClassName("link--QRY"),t=e.length;t--;)e[t].addEventListener("click",(function(e){e.preventDefault();var t=prompt("Please enter required input: ","");return null!==t&&""!==t&&(window.location.href=e.target.href+"?"+t),!1}))}(),function(){for(var e=document.getElementsByClassName("location__prefix"),t=e.length;t--;)e[t].addEventListener("click",(function(e){e.preventDefault();var t=prompt("Please enter new location: ","");return null!==t&&""!==t.trim()&&(0===(t=t.trim()).indexOf("gopher://")&&(t=t.substring(9)),window.location.href=window.location.origin+"/"+t),!1}))}(),function(){var e=document.getElementsByClassName("content")[0],t=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0],n=function(e,n){void 0===n&&(n=!1),e?generateImageThumbnails():n||removeImageThumbnails(),t.textContent=e?"[yes]":"[no]"};t.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1})),n(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",n);var a=document.getElementsByClassName("setting--monospace-font")[0].getElementsByClassName("setting__value")[0],l=function(t){t?e.classList.add("content--has-monospace-font"):e.classList.remove("content--has-monospace-font"),a.textContent=t?"[yes]":"[no]"};a.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("monospaceFont"),!1})),l(settings.getValue("monospaceFont")),settings.addCallback("monospaceFont",l);var s=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0],i=function(t){t?e.classList.add("content--wrap"):e.classList.remove("content--wrap"),s.textContent=t?"[yes]":"[no]"};s.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1})),i(settings.getValue("wordWrap")),settings.addCallback("wordWrap",i);var o=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0],r=function(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),o.textContent=e?"[yes]":"[no]"};o.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1})),r(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",r)}(),function(){for(var e=document.getElementsByClassName("modal"),t=e.length,n=function(){var n=e[t],a=n.getElementsByClassName("modal__content")[0],l=n.getElementsByClassName("modal__close-btn")[0];document.addEventListener("click",(function(e){n.classList.contains("modal--visible")&&(e.target===a||a.contains(e.target)||(n.classList.remove("modal--visible"),e.preventDefault(),e.stopPropagation()))}),!0),document.addEventListener("keydown",(function(e){n.classList.contains("modal--visible")&&27===e.keyCode&&n.classList.remove("modal--visible")})),l.addEventListener("click",(function(e){return e.preventDefault(),n.classList.remove("modal--visible"),!1}))};t--;)n();var a=document.getElementsByClassName("settings-btn")[0],l=document.getElementsByClassName("modal--settings")[0];a.addEventListener("click",(function(e){return e.preventDefault(),l.classList.add("modal--visible"),!1}))}(); \ No newline at end of file | ||
diff --git a/assets/style.css b/assets/style.css index 1ad0b19..28efa0b 100644 --- a/assets/style.css +++ b/assets/style.css | |||
@@ -1 +1 @@ | |||
body{margin:0;padding:0;background-color:#14171a;color:#cad1d8;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace;font-size:1.0625em;line-height:1.5}h1,h2,h3,h4,h5,h6{font:inherit;color:#fff;margin:0}button{background:none;border:0;padding:0;color:#fff;font:inherit;text-decoration:underline;cursor:pointer}button:focus{outline:1px dotted currentColor}img{display:inline-block;vertical-align:top;max-width:8em;margin:.1em 0}img::selection{background-color:rgba(239,198,138,0.35)}img.expanded{max-width:40em;max-width:80ch}img.faded{opacity:.5}strong{font-weight:normal}::selection{color:#000;background-color:rgba(239,198,138,0.996)}:link{color:#fff}:visited{color:#cad1d8}:link:hover,:visited:hover{color:#fff}.header-base{display:flex;flex-direction:row;align-items:center;justify-content:space-between;border-bottom:1px solid #353a3f}.header{padding:.9em 1em;color:#929ba3}.location{flex:0 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-overflow:ellipsis '|';margin-right:.5em}.location__prefix{margin-right:.3em;color:#929ba3}@media (hover: hover){.location__prefix:hover{color:#fff}}.location__prefix--mobile{display:none}.location__slash{margin:0 .3em}.location__uripart{color:#fff}.location__uripart+.location__slash+.location__uripart{color:#cad1d8}.location__uripart:link:hover,.location__uripart:visited:hover{color:#fff}.actions{flex:0 0 auto}.actions :visited{color:#fff}.action{display:inline}.action+.action::before{content:' | '}.wrap{padding:2em 1em;text-align:center}.content{box-sizing:border-box;display:inline-block;min-width:0;max-width:100%;margin:0;padding:0;text-align:left;font:inherit}.content--wrap{white-space:pre-wrap;word-wrap:break-word}.content--has-type-annotations{padding-left:3em;padding-left:5ch}.type-annotation{margin-left:-3em;margin-left:-5ch;color:#929ba3;white-space:pre}.modal{position:fixed;top:0;left:0;z-index:100;display:none;width:100%;height:100%;box-sizing:border-box;padding:2em;background-color:rgba(0,0,0,0.75)}.modal--visible{display:block}.modal__content{max-width:30em;padding:1.5em 1.8em;margin:0 auto;background-color:#14171a;box-shadow:0 .3em 2em #000;text-align:left}.modal__head{padding-bottom:.75em;margin-bottom:1.5em}.modal__title{padding-right:1em;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:uppercase}.setting{display:flex;flex-direction:row;align-items:baseline;justify-content:space-between}.setting::after{order:2;flex:1 1 auto;display:block;height:0;margin:0 .5em;border-bottom:2px dotted #353a3f;content:''}.setting__label{order:1}.setting__value{order:3}@media screen and (max-width: 800px){body{font-size:1em}.modal{padding:1em}.modal__content{padding:1em 1.3em}}@media screen and (max-width: 500px){.location__prefix{display:none}.location__prefix--mobile{display:inline}.action{display:block}.action+.action::before{content:''}}@media screen and (max-width: 280px){.location__prefix--mobile{display:none}} | body{margin:0;padding:0;background-color:#14171a;color:#cad1d8;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace;font-size:1.0625em;line-height:1.5}h1,h2,h3,h4,h5,h6{font:inherit;color:#fff;margin:0}button{background:none;border:0;padding:0;color:#fff;font:inherit;text-decoration:underline;cursor:pointer}button:focus{outline:1px dotted currentColor}img{display:inline-block;vertical-align:top;max-width:8em;margin:.1em 0}img::selection{background-color:rgba(239,198,138,0.35)}img.expanded{max-width:40em;max-width:80ch}img.faded{opacity:.5}strong{font-weight:normal}::selection{color:#000;background-color:rgba(239,198,138,0.996)}:link{color:#fff}:visited{color:#cad1d8}:link:hover,:visited:hover{color:#fff}.header-base{display:flex;flex-direction:row;align-items:center;justify-content:space-between;border-bottom:1px solid #353a3f}.header{padding:.9em 1em;color:#929ba3}.location{flex:0 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-overflow:ellipsis '|';margin-right:.5em}.location__prefix{margin-right:.3em;color:#929ba3}@media (hover: hover){.location__prefix:hover{color:#fff}}.location__prefix--mobile{display:none}.location__slash{margin:0 .3em}.location__uripart{color:#fff}.location__uripart+.location__slash+.location__uripart{color:#cad1d8}.location__uripart:link:hover,.location__uripart:visited:hover{color:#fff}.actions{flex:0 0 auto}.actions :visited{color:#fff}.action{display:inline}.action+.action::before{content:' | '}.wrap{padding:2em 1em;text-align:center}.content{box-sizing:border-box;display:inline-block;min-width:0;max-width:100%;margin:0;padding:0;text-align:left;font:inherit;font-family:"Iosevka Aile","Fira Sans","Roboto","Droid Sans",sans-serif}.content--wrap{white-space:pre-wrap;word-wrap:break-word}.content--has-type-annotations{padding-left:3em;padding-left:5ch}.content--has-monospace-font{font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace}.type-annotation{margin-left:-3em;margin-left:-5ch;color:#929ba3;white-space:pre;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace}.modal{position:fixed;top:0;left:0;z-index:100;display:none;width:100%;height:100%;box-sizing:border-box;padding:2em;background-color:rgba(0,0,0,0.75)}.modal--visible{display:block}.modal__content{max-width:30em;padding:1.5em 1.8em;margin:0 auto;background-color:#14171a;box-shadow:0 .3em 2em #000;text-align:left}.modal__head{padding-bottom:.75em;margin-bottom:1.5em}.modal__title{padding-right:1em;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:uppercase}.setting{display:flex;flex-direction:row;align-items:baseline;justify-content:space-between}.setting::after{order:2;flex:1 1 auto;display:block;height:0;margin:0 .5em;border-bottom:2px dotted #353a3f;content:''}.setting__label{order:1}.setting__value{order:3}@media screen and (max-width: 800px){body{font-size:1em}.modal{padding:1em}.modal__content{padding:1em 1.3em}}@media screen and (max-width: 500px){.location__prefix{display:none}.location__prefix--mobile{display:inline}.action{display:block}.action+.action::before{content:''}}@media screen and (max-width: 280px){.location__prefix--mobile{display:none}} | ||
diff --git a/css/main.scss b/css/main.scss index a6b1ee9..4cf5285 100644 --- a/css/main.scss +++ b/css/main.scss | |||
@@ -10,7 +10,8 @@ $border: mix(hsl(210, 100%, 95%), $background, 16%); | |||
10 | $sel-background: rgba($accent, .996); | 10 | $sel-background: rgba($accent, .996); |
11 | $sel-text: #000; | 11 | $sel-text: #000; |
12 | 12 | ||
13 | $font-monospace: 'Iosevka Term SS03', 'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace; | 13 | $font-monospace: 'Iosevka Term SS03', 'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace; |
14 | $font-proportional: 'Iosevka Aile', 'Fira Sans', 'Roboto', 'Droid Sans', sans-serif; | ||
14 | 15 | ||
15 | // | 16 | // |
16 | // Basic element styles | 17 | // Basic element styles |
@@ -198,6 +199,7 @@ strong { | |||
198 | padding: 0; | 199 | padding: 0; |
199 | text-align: left; | 200 | text-align: left; |
200 | font: inherit; | 201 | font: inherit; |
202 | font-family: $font-proportional; | ||
201 | 203 | ||
202 | &--wrap { | 204 | &--wrap { |
203 | white-space: pre-wrap; | 205 | white-space: pre-wrap; |
@@ -208,6 +210,10 @@ strong { | |||
208 | padding-left: 3em; | 210 | padding-left: 3em; |
209 | padding-left: 5ch; | 211 | padding-left: 5ch; |
210 | } | 212 | } |
213 | |||
214 | &--has-monospace-font { | ||
215 | font-family: $font-monospace; | ||
216 | } | ||
211 | } | 217 | } |
212 | 218 | ||
213 | .type-annotation { | 219 | .type-annotation { |
@@ -215,6 +221,7 @@ strong { | |||
215 | margin-left: -5ch; | 221 | margin-left: -5ch; |
216 | color: $text-minus; | 222 | color: $text-minus; |
217 | white-space: pre; | 223 | white-space: pre; |
224 | font-family: $font-monospace; | ||
218 | } | 225 | } |
219 | 226 | ||
220 | // | 227 | // |
diff --git a/fonts/iosevka-aile-regular.ttf b/fonts/iosevka-aile-regular.ttf new file mode 100644 index 0000000..7cad586 --- /dev/null +++ b/fonts/iosevka-aile-regular.ttf | |||
Binary files differ | |||
diff --git a/gopherproxy.go b/gopherproxy.go index d98ef7c..34e6ff8 100644 --- a/gopherproxy.go +++ b/gopherproxy.go | |||
@@ -30,10 +30,12 @@ type Item struct { | |||
30 | } | 30 | } |
31 | 31 | ||
32 | type AssetList struct { | 32 | type AssetList struct { |
33 | Style string | 33 | Style string |
34 | JS string | 34 | JS string |
35 | FontW string | 35 | FontW string |
36 | FontW2 string | 36 | FontW2 string |
37 | PropFontW string | ||
38 | PropFontW2 string | ||
37 | } | 39 | } |
38 | 40 | ||
39 | func renderDirectory(w http.ResponseWriter, tpl *template.Template, assetList AssetList, uri string, hostport string, d gopher.Directory) error { | 41 | func renderDirectory(w http.ResponseWriter, tpl *template.Template, assetList AssetList, uri string, hostport string, d gopher.Directory) error { |
@@ -299,6 +301,18 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency i | |||
299 | } | 301 | } |
300 | fontw2Asset := fmt.Sprintf("/iosevka-term-ss03-regular-%x.woff2", md5.Sum(fontdataw2)) | 302 | fontw2Asset := fmt.Sprintf("/iosevka-term-ss03-regular-%x.woff2", md5.Sum(fontdataw2)) |
301 | 303 | ||
304 | propfontdataw, err := box.Find("iosevka-aile-regular.woff") | ||
305 | if err != nil { | ||
306 | propfontdataw = []byte{} | ||
307 | } | ||
308 | propfontwAsset := fmt.Sprintf("/iosevka-aile-regular-%x.woff", md5.Sum(propfontdataw)) | ||
309 | |||
310 | propfontdataw2, err := box.Find("iosevka-aile-regular.woff2") | ||
311 | if err != nil { | ||
312 | propfontdataw2 = []byte{} | ||
313 | } | ||
314 | propfontw2Asset := fmt.Sprintf("/iosevka-aile-regular-%x.woff2", md5.Sum(propfontdataw2)) | ||
315 | |||
302 | styledata, err := box.Find("style.css") | 316 | styledata, err := box.Find("style.css") |
303 | if err != nil { | 317 | if err != nil { |
304 | styledata = []byte{} | 318 | styledata = []byte{} |
@@ -368,13 +382,15 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency i | |||
368 | ConcurrencyLevel: vipsconcurrency, | 382 | ConcurrencyLevel: vipsconcurrency, |
369 | }) | 383 | }) |
370 | 384 | ||
371 | http.HandleFunc("/", GopherHandler(tpl, robotsdata, AssetList{styleAsset, jsAsset, fontwAsset, fontw2Asset}, robotsdebug, uri)) | 385 | http.HandleFunc("/", GopherHandler(tpl, robotsdata, AssetList{styleAsset, jsAsset, fontwAsset, fontw2Asset, propfontwAsset, propfontw2Asset}, robotsdebug, uri)) |
372 | http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) | 386 | http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) |
373 | http.HandleFunc("/favicon.ico", FaviconHandler(favicondata)) | 387 | http.HandleFunc("/favicon.ico", FaviconHandler(favicondata)) |
374 | http.HandleFunc(styleAsset, StyleHandler(styledata)) | 388 | http.HandleFunc(styleAsset, StyleHandler(styledata)) |
375 | http.HandleFunc(jsAsset, JavaScriptHandler(jsdata)) | 389 | http.HandleFunc(jsAsset, JavaScriptHandler(jsdata)) |
376 | http.HandleFunc(fontwAsset, FontHandler(false, fontdataw)) | 390 | http.HandleFunc(fontwAsset, FontHandler(false, fontdataw)) |
377 | http.HandleFunc(fontw2Asset, FontHandler(true, fontdataw2)) | 391 | http.HandleFunc(fontw2Asset, FontHandler(true, fontdataw2)) |
392 | http.HandleFunc(propfontwAsset, FontHandler(false, propfontdataw)) | ||
393 | http.HandleFunc(propfontw2Asset, FontHandler(true, propfontdataw2)) | ||
378 | //http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/")))) | 394 | //http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/")))) |
379 | 395 | ||
380 | return http.ListenAndServe(bind, nil) | 396 | return http.ListenAndServe(bind, nil) |
@@ -21,6 +21,15 @@ const settings = new KeyValueStore({ | |||
21 | ], | 21 | ], |
22 | valueRange: [false, true] | 22 | valueRange: [false, true] |
23 | }, | 23 | }, |
24 | monospaceFont: { | ||
25 | value: ensureSetting('monospace-font', '1') === '1', | ||
26 | callbacks: [ | ||
27 | value => { | ||
28 | localStorage.setItem('monospace-font', value ? '1' : '0'); | ||
29 | } | ||
30 | ], | ||
31 | valueRange: [false, true] | ||
32 | }, | ||
24 | imagePreviews: { | 33 | imagePreviews: { |
25 | value: ensureSetting('image-previews', '1') === '1', | 34 | value: ensureSetting('image-previews', '1') === '1', |
26 | callbacks: [ | 35 | callbacks: [ |
@@ -110,6 +119,29 @@ const settings = new KeyValueStore({ | |||
110 | 119 | ||
111 | // | 120 | // |
112 | 121 | ||
122 | const settingMonospaceFontEl = document.getElementsByClassName('setting--monospace-font')[0]; | ||
123 | const settingMonospaceFontValueEl = settingMonospaceFontEl.getElementsByClassName('setting__value')[0]; | ||
124 | const settingMonospaceFontCallback = (value: boolean) => { | ||
125 | if (value) { | ||
126 | contentEl.classList.add("content--has-monospace-font"); | ||
127 | } else { | ||
128 | contentEl.classList.remove("content--has-monospace-font"); | ||
129 | } | ||
130 | |||
131 | settingMonospaceFontValueEl.textContent = value ? '[yes]' : '[no]'; | ||
132 | } | ||
133 | |||
134 | settingMonospaceFontValueEl.addEventListener('click', e => { | ||
135 | e.preventDefault(); | ||
136 | settings.cycleValue('monospaceFont'); | ||
137 | return false; | ||
138 | }); | ||
139 | |||
140 | settingMonospaceFontCallback(settings.getValue('monospaceFont')); | ||
141 | settings.addCallback('monospaceFont', settingMonospaceFontCallback); | ||
142 | |||
143 | // | ||
144 | |||
113 | const settingWordWrapEl = document.getElementsByClassName('setting--word-wrap')[0]; | 145 | const settingWordWrapEl = document.getElementsByClassName('setting--word-wrap')[0]; |
114 | const settingWordWrapValueEl = settingWordWrapEl.getElementsByClassName('setting__value')[0]; | 146 | const settingWordWrapValueEl = settingWordWrapEl.getElementsByClassName('setting__value')[0]; |
115 | const settingWordWrapCallback = (value: boolean) => { | 147 | const settingWordWrapCallback = (value: boolean) => { |
diff --git a/template.go b/template.go index 7aee61a..54aa53a 100644 --- a/template.go +++ b/template.go | |||
@@ -15,6 +15,13 @@ var tpltext = `<!doctype html> | |||
15 | src: url('{{ .Assets.FontW2 }}') format('woff2'), | 15 | src: url('{{ .Assets.FontW2 }}') format('woff2'), |
16 | url('{{ .Assets.FontW }}') format('woff'); | 16 | url('{{ .Assets.FontW }}') format('woff'); |
17 | } | 17 | } |
18 | @font-face { | ||
19 | font-family: 'Iosevka Aile'; | ||
20 | font-style: normal; | ||
21 | font-weight: normal; | ||
22 | src: url('{{ .Assets.PropFontW2 }}') format('woff2'), | ||
23 | url('{{ .Assets.PropFontW }}') format('woff'); | ||
24 | } | ||
18 | </style> | 25 | </style> |
19 | </head> | 26 | </head> |
20 | <body class="{{ if not .Lines }}is-plain{{ end }}"> | 27 | <body class="{{ if not .Lines }}is-plain{{ end }}"> |
@@ -63,7 +70,7 @@ var tpltext = `<!doctype html> | |||
63 | </div> | 70 | </div> |
64 | </header> | 71 | </header> |
65 | <main class="wrap"> | 72 | <main class="wrap"> |
66 | <pre class="content{{ if .Lines }} content--has-type-annotations{{ end }}"> | 73 | <pre class="content content--has-monospace-font{{ if .Lines }} content--has-type-annotations{{ end }}"> |
67 | {{- if .Lines -}} | 74 | {{- if .Lines -}} |
68 | {{- $content := "" -}} | 75 | {{- $content := "" -}} |
69 | {{- range .Lines -}} | 76 | {{- range .Lines -}} |
@@ -92,6 +99,10 @@ var tpltext = `<!doctype html> | |||
92 | <strong class="setting__label">Wrap wide content</strong> | 99 | <strong class="setting__label">Wrap wide content</strong> |
93 | <button class="setting__value">[N/A]</button> | 100 | <button class="setting__value">[N/A]</button> |
94 | </div> | 101 | </div> |
102 | <div class="setting setting--monospace-font"> | ||
103 | <strong class="setting__label">Monospace font</strong> | ||
104 | <button class="setting__value">[N/A]</button> | ||
105 | </div> | ||
95 | <div class="setting setting--image-previews"> | 106 | <div class="setting setting--image-previews"> |
96 | <strong class="setting__label">Image thumbnails</strong> | 107 | <strong class="setting__label">Image thumbnails</strong> |
97 | <button class="setting__value">[N/A]</button> | 108 | <button class="setting__value">[N/A]</button> |