diff options
author | Feuerfuchs <git@feuerfuchs.dev> | 2020-05-18 18:51:19 +0200 |
---|---|---|
committer | Feuerfuchs <git@feuerfuchs.dev> | 2020-05-18 18:51:19 +0200 |
commit | c772716e98e11181d301deadeca52856ac18f085 (patch) | |
tree | 25039bd7739039c000ab748b1547b5e5514d0b7a | |
parent | WIP: Refactoring (diff) | |
download | gopherproxy-c772716e98e11181d301deadeca52856ac18f085.tar.gz gopherproxy-c772716e98e11181d301deadeca52856ac18f085.tar.bz2 gopherproxy-c772716e98e11181d301deadeca52856ac18f085.zip |
Improved Gemini support
-rw-r--r-- | assets/main.js | 2 | ||||
-rw-r--r-- | assets/style.css | 2 | ||||
-rw-r--r-- | css/main.scss | 26 | ||||
-rw-r--r-- | internal/port/gemini.go | 36 | ||||
-rw-r--r-- | internal/port/gopher.go | 16 | ||||
-rw-r--r-- | internal/port/main.go | 6 | ||||
-rw-r--r-- | internal/port/tpl/gemini.html | 11 | ||||
-rw-r--r-- | internal/port/tpl/gopher.html | 2 | ||||
-rw-r--r-- | internal/port/tpl/startpage.html | 2 | ||||
-rw-r--r-- | js/main.ts | 19 |
10 files changed, 86 insertions, 36 deletions
diff --git a/assets/main.js b/assets/main.js index 1fa4dcf..a658224 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]},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"),i=document.createElement("span");i.classList.add("type-annotation"),i.textContent=" -> ";var s=document.createElement("img");s.src=a,s.addEventListener("load",(function(e){s.classList.remove("faded")}));var r=document.createElement("a");r.classList.add("img-preview"),r.href=n.href,r.addEventListener("click",(function(e){return e.preventDefault(),s.classList.add("faded"),s.classList.contains("expanded")?(s.classList.remove("expanded"),s.src=a):(s.classList.add("expanded"),s.src=r.href),!1})),r.append(s),n.parentNode.insertBefore(r,n.nextSibling),n.parentNode.insertBefore(i,r),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+"/gopher/$1"):0===t.indexOf("gemini://")&&(t=t.replace(/^gemini:\/\/(.*)$/,location.origin+"/gemini/$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 (gopher://... or gemini://...):","");return null!==t&&""!==t.trim()&&(t=0===(t=t.trim()).indexOf("gopher://")?"gopher/"+t.substring(9):0===t.indexOf("gemini://")?"gemini/"+t.substring(9):"gopher/"+t,window.location.href=window.location.origin+"/"+t),!1}))}(),function(){var e=document.getElementsByClassName("wrap")[0],t=e.getElementsByClassName("content")[0],n=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0],a=function(e,t){void 0===t&&(t=!1),e?generateImageThumbnails():t||removeImageThumbnails(),n.textContent=e?"[yes]":"[no]"};n.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1})),a(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",a);var l=document.getElementsByClassName("setting--monospace-font")[0].getElementsByClassName("setting__value")[0],i=function(e){e?t.classList.add("content--prefer-monospace"):t.classList.remove("content--prefer-monospace"),l.textContent=e?"[yes]":"[no]"};l.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("monospaceFont"),!1})),i(settings.getValue("monospaceFont")),settings.addCallback("monospaceFont",i);var s=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0],r=function(t){t?e.classList.add("wrap--word-wrap"):e.classList.remove("wrap--word-wrap"),s.textContent=t?"[yes]":"[no]"};s.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1})),r(settings.getValue("wordWrap")),settings.addCallback("wordWrap",r);var o=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0],c=function(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),o.textContent=e?"[yes]":"[no]"};o.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1})),c(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",c)}(),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.createElement("div");l.classList.add("section");var s=document.createElement("span");s.classList.add("section__type"),s.textContent=" -> ";var i=document.createElement("img");i.src=a,i.addEventListener("load",(function(e){i.classList.remove("faded")}));var r=document.createElement("a");r.classList.add("section__content"),r.classList.add("img-preview"),r.href=n.href,r.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=r.href),!1})),r.append(i),l.append(s),l.append(r),n.parentNode.parentNode.insertBefore(l,n.parentNode.nextSibling)};t--;)n()}function removeImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length;t--;)e[t].parentNode.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+"/gopher/$1"):0===t.indexOf("gemini://")&&(t=t.replace(/^gemini:\/\/(.*)$/,location.origin+"/gemini/$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 (gopher://... or gemini://...):","");return null!==t&&""!==t.trim()&&(t=0===(t=t.trim()).indexOf("gopher://")?"gopher/"+t.substring(9):0===t.indexOf("gemini://")?"gemini/"+t.substring(9):"gopher/"+t,window.location.href=window.location.origin+"/"+t),!1}))}(),function(){var e=document.getElementsByClassName("wrap")[0],t=e.getElementsByClassName("content")[0],n=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0],a=function(e,t){void 0===t&&(t=!1),e?generateImageThumbnails():t||removeImageThumbnails(),n.textContent=e?"[yes]":"[no]"};n.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1})),a(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",a);var l=document.getElementsByClassName("setting--monospace-font")[0].getElementsByClassName("setting__value")[0],s=function(e){e?t.classList.add("content--prefer-monospace"):t.classList.remove("content--prefer-monospace"),l.textContent=e?"[yes]":"[no]"};l.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("monospaceFont"),!1})),s(settings.getValue("monospaceFont")),settings.addCallback("monospaceFont",s);var i=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0],r=function(t){t?e.classList.add("wrap--word-wrap"):e.classList.remove("wrap--word-wrap"),i.textContent=t?"[yes]":"[no]"};i.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1})),r(settings.getValue("wordWrap")),settings.addCallback("wordWrap",r);var o=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0],c=function(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),o.textContent=e?"[yes]":"[no]"};o.addEventListener("click",(function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1})),c(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",c)}(),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 e662925..a03e8b3 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:1em;line-height:1.5}pre{margin:0;font:inherit;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace;white-space:pre-wrap}h1,h2,h3,h4,h5,h6{font:inherit;font-weight:bold;color:#fff;margin:0}p{margin:0}ul,ol{margin:0;padding:0;list-style-type:none}ul li{padding-left:4ch}ul li::before{display:inline-block;width:2ch;padding-left:2ch;margin-left:-4ch;content:'–'}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;cursor:pointer}@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}.wrap--word-wrap{max-width:45em;max-width:90ch;margin:0 auto}.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:"Open Sans","Fira Sans","Roboto","Droid Sans",sans-serif}.content--monospace,.content--prefer-monospace{font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace}.section{display:flex;align-items:baseline;flex-direction:row;justify-content:flex-start;min-height:1.5em;padding-left:3em;padding-left:5ch}.section__type{flex:0 0 auto;margin-left:-3em;margin-left:-5ch;padding-right:1.25em;padding-right:2ch;width:1.75em;width:3ch;color:#929ba3;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace;text-align:right;user-select:none}.section__content{min-width:0;word-wrap:break-word}.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}pre{margin:0;font:inherit;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace;white-space:pre-wrap}h1,h2,h3,h4,h5,h6{font:inherit;font-weight:bold;color:#fff;margin:0}p{margin:0}ul,ol{margin:0;padding:0;list-style-type:none}ul li{padding-left:2.5em}ul li::before{display:inline-block;width:1.5em;padding-left:1em;margin-left:-2.5em;content:'–'}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;cursor:pointer}@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}.wrap--word-wrap{max-width:45em;max-width:90ch;margin:0 auto}.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:"Open Sans","Fira Sans","Roboto","Droid Sans",sans-serif}.content--monospace,.content--prefer-monospace{font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace}.section{display:flex;align-items:baseline;flex-direction:row;justify-content:flex-start;min-height:1.5em;padding-left:3em;padding-left:5ch}.section__type{flex:0 0 auto;margin-left:-3em;margin-left:-5ch;width:3em;width:5ch;color:#929ba3;font-family:"Iosevka Term SS03","IBM Plex Mono","Fira Code","Fira Mono","Roboto Mono","Droid Sans Mono",Monaco,Consolas,Courier,monospace;user-select:none;white-space:pre}.section__content{min-width:0;word-wrap:break-word}.is-plain .section{padding-left:0}.is-plain .section__type{display:none}.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 27a62ec..b768a87 100644 --- a/css/main.scss +++ b/css/main.scss | |||
@@ -28,7 +28,7 @@ body { | |||
28 | // ); | 28 | // ); |
29 | color: $text; | 29 | color: $text; |
30 | font-family: $font-monospace; | 30 | font-family: $font-monospace; |
31 | font-size: 1em; //1 / 16 * 17em; | 31 | font-size: 1 / 16 * 17em; |
32 | line-height: 1.5; | 32 | line-height: 1.5; |
33 | } | 33 | } |
34 | 34 | ||
@@ -58,13 +58,13 @@ ul, ol { | |||
58 | 58 | ||
59 | ul { | 59 | ul { |
60 | li { | 60 | li { |
61 | padding-left: 4ch; | 61 | padding-left: 2.5em; |
62 | 62 | ||
63 | &::before { | 63 | &::before { |
64 | display: inline-block; | 64 | display: inline-block; |
65 | width: 2ch; | 65 | width: 1.5em; |
66 | padding-left: 2ch; | 66 | padding-left: 1em; |
67 | margin-left: -4ch; | 67 | margin-left: -2.5em; |
68 | content: '–'; | 68 | content: '–'; |
69 | } | 69 | } |
70 | } | 70 | } |
@@ -259,20 +259,26 @@ strong { | |||
259 | flex: 0 0 auto; | 259 | flex: 0 0 auto; |
260 | margin-left: -3em; | 260 | margin-left: -3em; |
261 | margin-left: -5ch; | 261 | margin-left: -5ch; |
262 | padding-right: 1.25em; | 262 | width: 3em; |
263 | padding-right: 2ch; | 263 | width: 5ch; |
264 | width: 1.75em; | ||
265 | width: 3ch; | ||
266 | color: $text-minus; | 264 | color: $text-minus; |
267 | font-family: $font-monospace; | 265 | font-family: $font-monospace; |
268 | text-align: right; | ||
269 | user-select: none; | 266 | user-select: none; |
267 | white-space: pre; | ||
270 | } | 268 | } |
271 | 269 | ||
272 | &__content { | 270 | &__content { |
273 | min-width: 0; | 271 | min-width: 0; |
274 | word-wrap: break-word; | 272 | word-wrap: break-word; |
275 | } | 273 | } |
274 | |||
275 | .is-plain & { | ||
276 | padding-left: 0; | ||
277 | |||
278 | &__type { | ||
279 | display: none; | ||
280 | } | ||
281 | } | ||
276 | } | 282 | } |
277 | 283 | ||
278 | // | 284 | // |
diff --git a/internal/port/gemini.go b/internal/port/gemini.go index 740fccd..f67ca05 100644 --- a/internal/port/gemini.go +++ b/internal/port/gemini.go | |||
@@ -29,8 +29,9 @@ type GeminiTemplateVariables struct { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | type GeminiNavItem struct { | 31 | type GeminiNavItem struct { |
32 | Label string | 32 | Label string |
33 | URL string | 33 | URL string |
34 | Current bool | ||
34 | } | 35 | } |
35 | 36 | ||
36 | type GeminiSection struct { | 37 | type GeminiSection struct { |
@@ -40,6 +41,32 @@ type GeminiSection struct { | |||
40 | Items []string | 41 | Items []string |
41 | } | 42 | } |
42 | 43 | ||
44 | func urlToGeminiNav(url string) (items []GeminiNavItem) { | ||
45 | partialURL := "/gemini" | ||
46 | parts := strings.Split(url, "/") | ||
47 | |||
48 | if len(parts) != 0 && parts[len(parts)-1] == "" { | ||
49 | parts = parts[:len(parts)-1] | ||
50 | } | ||
51 | |||
52 | for i, part := range parts { | ||
53 | partialURL = partialURL + "/" + part | ||
54 | |||
55 | current := false | ||
56 | if i == len(parts)-1 || (len(parts) == 2 && i == 0) { | ||
57 | current = true | ||
58 | } | ||
59 | |||
60 | items = append(items, GeminiNavItem{ | ||
61 | Label: part, | ||
62 | URL: partialURL, | ||
63 | Current: current, | ||
64 | }) | ||
65 | } | ||
66 | |||
67 | return | ||
68 | } | ||
69 | |||
43 | func resolveURL(uri string, baseURL *url.URL) (resolvedURL string) { | 70 | func resolveURL(uri string, baseURL *url.URL) (resolvedURL string) { |
44 | if strings.HasPrefix(uri, "//") { | 71 | if strings.HasPrefix(uri, "//") { |
45 | resolvedURL = "/gemini/" + strings.TrimPrefix(uri, "//") | 72 | resolvedURL = "/gemini/" + strings.TrimPrefix(uri, "//") |
@@ -137,6 +164,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
137 | Type: libgemini.RAW_TEXT.String(), | 164 | Type: libgemini.RAW_TEXT.String(), |
138 | Text: fmt.Sprintf("Error: %s", err), | 165 | Text: fmt.Sprintf("Error: %s", err), |
139 | }}, | 166 | }}, |
167 | Nav: urlToGeminiNav(hostport), | ||
140 | IsPlain: true, | 168 | IsPlain: true, |
141 | }); e != nil { | 169 | }); e != nil { |
142 | log.Println("Template error: " + e.Error()) | 170 | log.Println("Template error: " + e.Error()) |
@@ -167,6 +195,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
167 | Type: libgemini.RAW_TEXT.String(), | 195 | Type: libgemini.RAW_TEXT.String(), |
168 | Text: fmt.Sprintf("Error: %s", err), | 196 | Text: fmt.Sprintf("Error: %s", err), |
169 | }}, | 197 | }}, |
198 | Nav: urlToGeminiNav(fmt.Sprintf("%s/%s", hostport, uri)), | ||
170 | IsPlain: true, | 199 | IsPlain: true, |
171 | }); e != nil { | 200 | }); e != nil { |
172 | log.Println("Template error: " + e.Error()) | 201 | log.Println("Template error: " + e.Error()) |
@@ -190,6 +219,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
190 | Type: libgemini.RAW_TEXT.String(), | 219 | Type: libgemini.RAW_TEXT.String(), |
191 | Text: fmt.Sprintf("Error: %s", err), | 220 | Text: fmt.Sprintf("Error: %s", err), |
192 | }}, | 221 | }}, |
222 | Nav: urlToGeminiNav(fmt.Sprintf("%s/%s", hostport, uri)), | ||
193 | IsPlain: true, | 223 | IsPlain: true, |
194 | }); e != nil { | 224 | }); e != nil { |
195 | log.Println("Template error: " + e.Error()) | 225 | log.Println("Template error: " + e.Error()) |
@@ -211,6 +241,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
211 | Type: libgemini.RAW_TEXT.String(), | 241 | Type: libgemini.RAW_TEXT.String(), |
212 | Text: fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), | 242 | Text: fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), |
213 | }}, | 243 | }}, |
244 | Nav: urlToGeminiNav(fmt.Sprintf("%s/%s", hostport, uri)), | ||
214 | IsPlain: true, | 245 | IsPlain: true, |
215 | }); err != nil { | 246 | }); err != nil { |
216 | log.Println("Template error: " + err.Error()) | 247 | log.Println("Template error: " + err.Error()) |
@@ -252,6 +283,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
252 | URL: fmt.Sprintf("%s/%s", hostport, uri), | 283 | URL: fmt.Sprintf("%s/%s", hostport, uri), |
253 | Assets: assetList, | 284 | Assets: assetList, |
254 | Sections: sections, | 285 | Sections: sections, |
286 | Nav: urlToGeminiNav(fmt.Sprintf("%s/%s", hostport, uri)), | ||
255 | IsPlain: isPlain, | 287 | IsPlain: isPlain, |
256 | }); err != nil { | 288 | }); err != nil { |
257 | log.Println("Template error: " + err.Error()) | 289 | log.Println("Template error: " + err.Error()) |
diff --git a/internal/port/gopher.go b/internal/port/gopher.go index d2283c6..cb5e60c 100644 --- a/internal/port/gopher.go +++ b/internal/port/gopher.go | |||
@@ -49,10 +49,14 @@ func trimLeftChars(s string, n int) string { | |||
49 | return s[:0] | 49 | return s[:0] |
50 | } | 50 | } |
51 | 51 | ||
52 | func urlToNav(url string) (items []GopherNavItem) { | 52 | func urlToGopherNav(url string) (items []GopherNavItem) { |
53 | partialURL := "/gopher" | 53 | partialURL := "/gopher" |
54 | parts := strings.Split(url, "/") | 54 | parts := strings.Split(url, "/") |
55 | 55 | ||
56 | if len(parts) != 0 && parts[len(parts)-1] == "" { | ||
57 | parts = parts[:len(parts)-1] | ||
58 | } | ||
59 | |||
56 | for i, part := range parts { | 60 | for i, part := range parts { |
57 | if i == 1 { | 61 | if i == 1 { |
58 | partialURL = partialURL + "/1" | 62 | partialURL = partialURL + "/1" |
@@ -151,7 +155,7 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL | |||
151 | URL: fmt.Sprintf("%s/%s", hostport, uri), | 155 | URL: fmt.Sprintf("%s/%s", hostport, uri), |
152 | Assets: assetList, | 156 | Assets: assetList, |
153 | Lines: out, | 157 | Lines: out, |
154 | Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)), | 158 | Nav: urlToGopherNav(fmt.Sprintf("%s/%s", hostport, uri)), |
155 | }) | 159 | }) |
156 | } | 160 | } |
157 | 161 | ||
@@ -194,7 +198,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
194 | Lines: []GopherItem{{ | 198 | Lines: []GopherItem{{ |
195 | Text: fmt.Sprintf("Error: %s", err), | 199 | Text: fmt.Sprintf("Error: %s", err), |
196 | }}, | 200 | }}, |
197 | Nav: urlToNav(hostport), | 201 | Nav: urlToGopherNav(hostport), |
198 | IsPlain: true, | 202 | IsPlain: true, |
199 | }); e != nil { | 203 | }); e != nil { |
200 | log.Println("Template error: " + e.Error()) | 204 | log.Println("Template error: " + e.Error()) |
@@ -224,7 +228,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
224 | Lines: []GopherItem{{ | 228 | Lines: []GopherItem{{ |
225 | Text: fmt.Sprintf("Error: %s", err), | 229 | Text: fmt.Sprintf("Error: %s", err), |
226 | }}, | 230 | }}, |
227 | Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)), | 231 | Nav: urlToGopherNav(fmt.Sprintf("%s/%s", hostport, uri)), |
228 | IsPlain: true, | 232 | IsPlain: true, |
229 | }); e != nil { | 233 | }); e != nil { |
230 | log.Println("Template error: " + e.Error()) | 234 | log.Println("Template error: " + e.Error()) |
@@ -246,7 +250,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
246 | Lines: []GopherItem{{ | 250 | Lines: []GopherItem{{ |
247 | Text: buf.String(), | 251 | Text: buf.String(), |
248 | }}, | 252 | }}, |
249 | Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)), | 253 | Nav: urlToGopherNav(fmt.Sprintf("%s/%s", hostport, uri)), |
250 | IsPlain: true, | 254 | IsPlain: true, |
251 | }); err != nil { | 255 | }); err != nil { |
252 | log.Println("Template error: " + err.Error()) | 256 | log.Println("Template error: " + err.Error()) |
@@ -271,7 +275,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
271 | Lines: []GopherItem{{ | 275 | Lines: []GopherItem{{ |
272 | Text: fmt.Sprintf("Error: %s", err), | 276 | Text: fmt.Sprintf("Error: %s", err), |
273 | }}, | 277 | }}, |
274 | Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)), | 278 | Nav: urlToGopherNav(fmt.Sprintf("%s/%s", hostport, uri)), |
275 | IsPlain: false, | 279 | IsPlain: false, |
276 | }); e != nil { | 280 | }); e != nil { |
277 | log.Println("Template error: " + e.Error()) | 281 | log.Println("Template error: " + e.Error()) |
diff --git a/internal/port/main.go b/internal/port/main.go index 763057b..fe85ba4 100644 --- a/internal/port/main.go +++ b/internal/port/main.go | |||
@@ -237,9 +237,15 @@ func ListenAndServe(bind, startpagefile string, robotsfile string, robotsdebug b | |||
237 | "hasPrefix": func(s string, prefix string) bool { | 237 | "hasPrefix": func(s string, prefix string) bool { |
238 | return strings.HasPrefix(s, prefix) | 238 | return strings.HasPrefix(s, prefix) |
239 | }, | 239 | }, |
240 | "hasSuffix": func(s string, suffix string) bool { | ||
241 | return strings.HasSuffix(s, suffix) | ||
242 | }, | ||
240 | "title": func(s string) string { | 243 | "title": func(s string) string { |
241 | return strings.Title(s) | 244 | return strings.Title(s) |
242 | }, | 245 | }, |
246 | "string": func(s interface{}) string { | ||
247 | return fmt.Sprint(s) | ||
248 | }, | ||
243 | } | 249 | } |
244 | 250 | ||
245 | // | 251 | // |
diff --git a/internal/port/tpl/gemini.html b/internal/port/tpl/gemini.html index df50d50..8d20da1 100644 --- a/internal/port/tpl/gemini.html +++ b/internal/port/tpl/gemini.html | |||
@@ -35,11 +35,16 @@ | |||
35 | {{- else if eq .Type "REFLOW_TEXT" -}} | 35 | {{- else if eq .Type "REFLOW_TEXT" -}} |
36 | <div class="section"><p class="section__content">{{- .Text -}}</p></div> | 36 | <div class="section"><p class="section__content">{{- .Text -}}</p></div> |
37 | {{- else if eq .Type "LINK" -}} | 37 | {{- else if eq .Type "LINK" -}} |
38 | <div class="section"><span class="section__type">=></span><a class="section__content" href="{{ .URL }}">{{- .Text -}}</a></div> | 38 | {{- $linkCls := "link" -}} |
39 | {{- $url := string .URL -}} | ||
40 | {{- if or (hasSuffix $url ".jpg") (hasSuffix $url ".jpeg") (hasSuffix $url ".png") (hasSuffix $url ".gif") -}} | ||
41 | {{- $linkCls = "link--IMG" -}} | ||
42 | {{- end -}} | ||
43 | <div class="section"><span class="section__type"> =></span><a class="section__content {{ $linkCls }}" href="{{ .URL }}">{{- .Text -}}</a></div> | ||
39 | {{- else if eq .Type "HEADING_1" -}} | 44 | {{- else if eq .Type "HEADING_1" -}} |
40 | <div class="section"><span class="section__type">#</span><h1 class="section__content">{{- .Text -}}</h1></div> | 45 | <div class="section"><span class="section__type"> #</span><h1 class="section__content">{{- .Text -}}</h1></div> |
41 | {{- else if eq .Type "HEADING_2" -}} | 46 | {{- else if eq .Type "HEADING_2" -}} |
42 | <div class="section"><span class="section__type">##</span><h2 class="section__content">{{- .Text -}}</h2></div> | 47 | <div class="section"><span class="section__type"> ##</span><h2 class="section__content">{{- .Text -}}</h2></div> |
43 | {{- else if eq .Type "HEADING_3" -}} | 48 | {{- else if eq .Type "HEADING_3" -}} |
44 | <div class="section"><span class="section__type">###</span><h3 class="section__content">{{- .Text -}}</h3></div> | 49 | <div class="section"><span class="section__type">###</span><h3 class="section__content">{{- .Text -}}</h3></div> |
45 | {{- else if eq .Type "LIST" -}} | 50 | {{- else if eq .Type "LIST" -}} |
diff --git a/internal/port/tpl/gopher.html b/internal/port/tpl/gopher.html index 5436123..6eb607c 100644 --- a/internal/port/tpl/gopher.html +++ b/internal/port/tpl/gopher.html | |||
@@ -35,7 +35,7 @@ | |||
35 | {{- $page := . -}} | 35 | {{- $page := . -}} |
36 | {{- range .Lines -}} | 36 | {{- range .Lines -}} |
37 | {{- if .Link -}} | 37 | {{- if .Link -}} |
38 | <div class="section"><span class="section__type">{{- .Type -}}</span><a class="section__content" href="{{ .Link }}">{{- .Text -}}</a></div> | 38 | <div class="section"><span class="section__type">{{- .Type -}}</span><a class="section__content link link--{{ .Type }}" href="{{ .Link }}">{{- .Text -}}</a></div> |
39 | {{- else -}} | 39 | {{- else -}} |
40 | <div class="section"><span class="section__type"></span><pre class="section__content">{{- .Text -}}</pre></div> | 40 | <div class="section"><span class="section__type"></span><pre class="section__content">{{- .Text -}}</pre></div> |
41 | {{- end -}} | 41 | {{- end -}} |
diff --git a/internal/port/tpl/startpage.html b/internal/port/tpl/startpage.html index cfe519d..772ac90 100644 --- a/internal/port/tpl/startpage.html +++ b/internal/port/tpl/startpage.html | |||
@@ -18,7 +18,7 @@ | |||
18 | </header> | 18 | </header> |
19 | 19 | ||
20 | <main class="wrap"> | 20 | <main class="wrap"> |
21 | <pre class="content content--has-monospace-font"> | 21 | <pre class="content content--monospace"> |
22 | {{- .Content -}} | 22 | {{- .Content -}} |
23 | </pre> | 23 | </pre> |
24 | </main> | 24 | </main> |
@@ -246,10 +246,11 @@ function generateImageThumbnails() { | |||
246 | const linkImgEl = linkImgEls[i] as HTMLAnchorElement; | 246 | const linkImgEl = linkImgEls[i] as HTMLAnchorElement; |
247 | const thumbnailUrl = linkImgEl.href.replace(/^(.*?)\/I/, '$1/T'); | 247 | const thumbnailUrl = linkImgEl.href.replace(/^(.*?)\/I/, '$1/T'); |
248 | 248 | ||
249 | const lineBreakEl = document.createTextNode('\n'); | 249 | const sectionEl = document.createElement('div'); |
250 | sectionEl.classList.add('section'); | ||
250 | 251 | ||
251 | const typeAnnotEl = document.createElement('span'); | 252 | const typeAnnotEl = document.createElement('span'); |
252 | typeAnnotEl.classList.add('type-annotation'); | 253 | typeAnnotEl.classList.add('section__type'); |
253 | typeAnnotEl.textContent = ' -> '; | 254 | typeAnnotEl.textContent = ' -> '; |
254 | 255 | ||
255 | const thumbnailEl = document.createElement('img'); | 256 | const thumbnailEl = document.createElement('img'); |
@@ -259,6 +260,7 @@ function generateImageThumbnails() { | |||
259 | }); | 260 | }); |
260 | 261 | ||
261 | const thumbnailAnchorEl = document.createElement('a'); | 262 | const thumbnailAnchorEl = document.createElement('a'); |
263 | thumbnailAnchorEl.classList.add('section__content'); | ||
262 | thumbnailAnchorEl.classList.add('img-preview'); | 264 | thumbnailAnchorEl.classList.add('img-preview'); |
263 | thumbnailAnchorEl.href = linkImgEl.href; | 265 | thumbnailAnchorEl.href = linkImgEl.href; |
264 | thumbnailAnchorEl.addEventListener('click', e => { | 266 | thumbnailAnchorEl.addEventListener('click', e => { |
@@ -278,9 +280,9 @@ function generateImageThumbnails() { | |||
278 | }); | 280 | }); |
279 | 281 | ||
280 | thumbnailAnchorEl.append(thumbnailEl); | 282 | thumbnailAnchorEl.append(thumbnailEl); |
281 | linkImgEl.parentNode!.insertBefore(thumbnailAnchorEl, linkImgEl.nextSibling); | 283 | sectionEl.append(typeAnnotEl); |
282 | linkImgEl.parentNode!.insertBefore(typeAnnotEl, thumbnailAnchorEl); | 284 | sectionEl.append(thumbnailAnchorEl); |
283 | linkImgEl.parentNode!.insertBefore(lineBreakEl, typeAnnotEl); | 285 | linkImgEl.parentNode!.parentNode!.insertBefore(sectionEl, linkImgEl.parentNode!.nextSibling); |
284 | } | 286 | } |
285 | } | 287 | } |
286 | 288 | ||
@@ -288,12 +290,7 @@ function removeImageThumbnails() { | |||
288 | const linkImgEls = document.querySelectorAll('.link--IMG, .link--GIF'); | 290 | const linkImgEls = document.querySelectorAll('.link--IMG, .link--GIF'); |
289 | let i = linkImgEls.length; | 291 | let i = linkImgEls.length; |
290 | while (i--) { | 292 | while (i--) { |
291 | const linkImgEl = linkImgEls[i]; | 293 | linkImgEls[i].parentNode!.nextSibling!.remove(); |
292 | let j = 3; | ||
293 | |||
294 | while (j-- && linkImgEl.nextSibling) { | ||
295 | linkImgEl.nextSibling.remove(); | ||
296 | } | ||
297 | } | 294 | } |
298 | } | 295 | } |
299 | 296 | ||