aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeuerfuchs <git@feuerfuchs.dev>2019-06-26 21:51:25 +0200
committerFeuerfuchs <git@feuerfuchs.dev>2019-06-26 21:51:25 +0200
commit2986f020c87a69224233292969d817de6155e658 (patch)
treee012e5d2b60ece9c38ee8dff8b0a527fe6dfdf17
parentFix URL regex for ending slashes (diff)
downloadgopherproxy-2986f020c87a69224233292969d817de6155e658.tar.gz
gopherproxy-2986f020c87a69224233292969d817de6155e658.tar.bz2
gopherproxy-2986f020c87a69224233292969d817de6155e658.zip
Code cleanup
-rw-r--r--.drone.yml22
-rw-r--r--.gitignore2
-rw-r--r--.goreleaser.yml9
-rw-r--r--.vscode/settings.json3
-rw-r--r--LICENSE3
-rw-r--r--Makefile6
-rw-r--r--README.md51
-rw-r--r--_config.yml1
-rw-r--r--assets/main.js2
-rw-r--r--fonts/glyphs.txt (renamed from glyphs.txt)0
-rw-r--r--js/main.ts20
11 files changed, 52 insertions, 67 deletions
diff --git a/.drone.yml b/.drone.yml
deleted file mode 100644
index 0065a03..0000000
--- a/.drone.yml
+++ /dev/null
@@ -1,22 +0,0 @@
1kind: pipeline
2name: default
3
4steps:
5 - name: build
6 image: golang:latest
7 commands:
8 - make test
9
10 - name: coverage
11 image: plugins/codecov
12 settings:
13 token:
14 from_secret: codecov-token
15
16 - name: notify
17 image: plugins/webhook
18 urls: https://msgbus.mills.io/ci.mills.io
19 when:
20 status:
21 - success
22 - failure
diff --git a/.gitignore b/.gitignore
index 32c3689..e036b02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ dist
4coverage.txt 4coverage.txt
5 5
6gopherproxy 6gopherproxy
7
8.vscode
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index 8376981..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,9 +0,0 @@
1build:
2 main: cmd/gopherproxy/main.go
3 binary: gopherproxy
4 goos:
5 - windows
6 - darwin
7 - linux
8 goarch:
9 - amd64
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 8c45cda..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
1{
2 "go.formatTool": "goimports"
3} \ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 72873e6..3595902 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,6 @@
1Copyright (C) 2019 Feuerfuchs <me@feuerfuchs.dev>
1Copyright (C) 2016 James Mills 2Copyright (C) 2016 James Mills
2 3
3go-gopher is covered by the MIT license::
4
5Permission is hereby granted, free of charge, to any person 4Permission is hereby granted, free of charge, to any person
6obtaining a copy of this software and associated documentation 5obtaining a copy of this software and associated documentation
7files (the "Software"), to deal in the Software without restriction, 6files (the "Software"), to deal in the Software without restriction,
diff --git a/Makefile b/Makefile
index fa3998e..652aee5 100644
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,9 @@ dev: build
7 7
8build: clean 8build: clean
9 sassc -t compressed css/main.scss assets/style.css 9 sassc -t compressed css/main.scss assets/style.css
10 tsc --strict --module none --outFile /dev/stdout js/KeyValueStore.ts js/main.ts | uglifyjs -c -m -o assets/main.js -- 10 tsc --strict --module none --outFile /dev/stdout js/* | uglifyjs -c -m -o assets/main.js --
11 pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=glyphs.txt --flavor='woff' --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' --output-file='assets/iosevka-term-ss03-regular.woff'
12 pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=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 go build -o ./gopherproxy ./cmd/gopherproxy/main.go 13 go build -o ./gopherproxy ./cmd/gopherproxy/main.go
14 14
15profile: 15profile:
diff --git a/README.md b/README.md
index 4b89136..49ed7c5 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,51 @@
1# Gopher (RFC 1436) Web Proxy 1# Gopher (RFC 1436) Web Proxy
2 2
3[![Build Status](https://cloud.drone.io/api/badges/prologic/gopherproxy/status.svg)](https://cloud.drone.io/prologic/gopherproxy)
4[![CodeCov](https://codecov.io/gh/prologic/gopherproxy/branch/master/graph/badge.svg)](https://codecov.io/gh/prologic/gopherproxy)
5[![Go Report Card](https://goreportcard.com/badge/prologic/gopherproxy)](https://goreportcard.com/report/prologic/gopherproxy)
6[![GoDoc](https://godoc.org/git.feuerfuchs.dev/Feuerfuchs/gopherproxy?status.svg)](https://godoc.org/git.feuerfuchs.dev/Feuerfuchs/gopherproxy)
7[![Sourcegraph](https://sourcegraph.com/git.feuerfuchs.dev/Feuerfuchs/gopherproxy/-/badge.svg)](https://sourcegraph.com/git.feuerfuchs.dev/Feuerfuchs/gopherproxy?badge)
8
9gopherproxy is a Gopher (RFC 1436) Web Proxy that acts as a gateway into Gopherspace 3gopherproxy is a Gopher (RFC 1436) Web Proxy that acts as a gateway into Gopherspace
10by proxying standard Web HTTP requests to Gopher requests of the target server. 4by proxying standard Web HTTP requests to Gopher requests of the target server.
11 5
12gopherproxy is written in Go (#golang) using the 6gopherproxy is a fork of https://github.com/prologic/gopherproxy.
13[go-gopher](https://github.com/prologic/go-gopher) library. 7
8Demo: https://gopher.feuerfuchs.dev/
9
10
11## Requirements
12
13gopherproxy requires the following programs and libraries:
14
15- libvips: Fast on-demand thumbnail generation
14 16
15Demo: https://gopher.mills.io/
16 17
17## Installation 18## Installation
18 19
19 $ go install git.feuerfuchs.dev/Feuerfuchs/gopherproxy/... 20 $ go install git.feuerfuchs.dev/Feuerfuchs/gopherproxy/...
20 21
21### Docker
22 22
23Run directly from a prebuild image from the [Docker Hub](https://hub.docker.com): 23## Usage
24 24
25```#!bash 25```#!bash
26$ docker run -p 8000:8000 prologic/gopherproxy 26$ gopherproxy
27``` 27```
28 28
29Or build your own custom image from a source checkout: 29Then simply visit: http://localhost:8000/
30 30
31```#!bash
32$ docker build -t gopherproxy .
33$ docker run -p 80:80 gopherproxy -uri floodgap.com
34```
35 31
36## Usage 32## Development
37 33
38```#!bash 34For development, the following libraries and programs are required in addition
39$ gopherproxy 35to the previously listed ones:
40``` 36
37- **SASS (sassc):** Compiling SCSS to CSS
38- **TypeScript (tsc):** Compiling TypeScript to JavaScript
39- **UglifyJS (uglifyjs):** Minifying JavaScript
40- **fonttools (pyftsubset):** Minifying fonts
41
42Folder structure:
43
44- **assets:** Compiled assets that will be embedded into the executable using packr
45- **css:** SCSS source files
46- **fonts:** Fonts that will be minified
47- **js:** TypeScript source files
41 48
42Then simply visit: http://localhost/gopher.floodgap.com
43 49
44## Related 50## Related
45 51
@@ -52,6 +58,7 @@ Related projects:
52 gopherclient is a cross-platform QT/QML GUI Gopher Client 58 gopherclient is a cross-platform QT/QML GUI Gopher Client
53 using the gopherproxy library as its backend. 59 using the gopherproxy library as its backend.
54 60
61
55## License 62## License
56 63
57MIT 64MIT
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index 3397c9a..0000000
--- a/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
1theme: jekyll-theme-architect \ No newline at end of file
diff --git a/assets/main.js b/assets/main.js
index ab1a9d0..33aa76d 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"),valueRange:[!1,!0]},imagePreviews:{value:"1"===ensureSetting("image-previews","1"),valueRange:[!1,!0]},clickablePlainLinks:{value:"1"===ensureSetting("clickable-plain-links","1"),valueRange:[!1,!0]}});function generateImageThumbnails(){for(var r=document.querySelectorAll(".link--IMG, .link--GIF"),s=r.length,e=function(){var e=r[s],t=e.href.replace(/^(.*?)\/I/,"$1/T"),n=document.createTextNode("\n"),a=document.createElement("span");a.classList.add("type-annotation"),a.textContent=" -> ";var l=document.createElement("img");l.src=t,l.addEventListener("load",function(e){l.classList.remove("faded")});var i=document.createElement("a");i.classList.add("img-preview"),i.href=e.href,i.addEventListener("click",function(e){return e.preventDefault(),l.classList.add("faded"),l.classList.contains("expanded")?(l.classList.remove("expanded"),l.src=t):(l.classList.add("expanded"),l.src=i.href),!1}),i.append(l),e.parentNode.insertBefore(i,e.nextSibling),e.parentNode.insertBefore(a,i),e.parentNode.insertBefore(n,a)};s--;)e()}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(){function e(e,t){void 0===t&&(t=!1),e?generateImageThumbnails():t||removeImageThumbnails(),localStorage.setItem("image-previews",e?"1":"0"),n.textContent=e?"[yes]":"[no]"}var t=document.getElementsByClassName("content")[0],n=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0];n.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1}),e(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",e);function a(e){e?t.classList.add("content--wrap"):t.classList.remove("content--wrap"),localStorage.setItem("word-wrap",e?"1":"0"),l.textContent=e?"[yes]":"[no]"}var l=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0];l.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1}),a(settings.getValue("wordWrap")),settings.addCallback("wordWrap",a);function i(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),localStorage.setItem("clickable-plain-links",e?"1":"0"),r.textContent=e?"[yes]":"[no]"}var r=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0];r.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1}),i(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",i)}(),function(){for(var a=document.getElementsByClassName("modal"),l=a.length,e=function(){var t=a[l],n=t.getElementsByClassName("modal__content")[0],e=t.getElementsByClassName("modal__close-btn")[0];document.addEventListener("click",function(e){t.classList.contains("modal--visible")&&(e.target===n||n.contains(e.target)||(t.classList.remove("modal--visible"),e.preventDefault(),e.stopPropagation()))},!0),document.addEventListener("keydown",function(e){t.classList.contains("modal--visible")&&27===e.keyCode&&t.classList.remove("modal--visible")}),e.addEventListener("click",function(e){return e.preventDefault(),t.classList.remove("modal--visible"),!1})};l--;)e();var t=document.getElementsByClassName("settings-btn")[0],n=document.getElementsByClassName("modal--settings")[0];t.addEventListener("click",function(e){return e.preventDefault(),n.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]},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 r=document.querySelectorAll(".link--IMG, .link--GIF"),s=r.length,e=function(){var e=r[s],t=e.href.replace(/^(.*?)\/I/,"$1/T"),n=document.createTextNode("\n"),a=document.createElement("span");a.classList.add("type-annotation"),a.textContent=" -> ";var l=document.createElement("img");l.src=t,l.addEventListener("load",function(e){l.classList.remove("faded")});var i=document.createElement("a");i.classList.add("img-preview"),i.href=e.href,i.addEventListener("click",function(e){return e.preventDefault(),l.classList.add("faded"),l.classList.contains("expanded")?(l.classList.remove("expanded"),l.src=t):(l.classList.add("expanded"),l.src=i.href),!1}),i.append(l),e.parentNode.insertBefore(i,e.nextSibling),e.parentNode.insertBefore(a,i),e.parentNode.insertBefore(n,a)};s--;)e()}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(){function e(e,t){void 0===t&&(t=!1),e?generateImageThumbnails():t||removeImageThumbnails(),n.textContent=e?"[yes]":"[no]"}var t=document.getElementsByClassName("content")[0],n=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0];n.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1}),e(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",e);function a(e){e?t.classList.add("content--wrap"):t.classList.remove("content--wrap"),l.textContent=e?"[yes]":"[no]"}var l=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0];l.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1}),a(settings.getValue("wordWrap")),settings.addCallback("wordWrap",a);function i(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),r.textContent=e?"[yes]":"[no]"}var r=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0];r.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1}),i(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",i)}(),function(){for(var a=document.getElementsByClassName("modal"),l=a.length,e=function(){var t=a[l],n=t.getElementsByClassName("modal__content")[0],e=t.getElementsByClassName("modal__close-btn")[0];document.addEventListener("click",function(e){t.classList.contains("modal--visible")&&(e.target===n||n.contains(e.target)||(t.classList.remove("modal--visible"),e.preventDefault(),e.stopPropagation()))},!0),document.addEventListener("keydown",function(e){t.classList.contains("modal--visible")&&27===e.keyCode&&t.classList.remove("modal--visible")}),e.addEventListener("click",function(e){return e.preventDefault(),t.classList.remove("modal--visible"),!1})};l--;)e();var t=document.getElementsByClassName("settings-btn")[0],n=document.getElementsByClassName("modal--settings")[0];t.addEventListener("click",function(e){return e.preventDefault(),n.classList.add("modal--visible"),!1})}(); \ No newline at end of file
diff --git a/glyphs.txt b/fonts/glyphs.txt
index 1f4af23..1f4af23 100644
--- a/glyphs.txt
+++ b/fonts/glyphs.txt
diff --git a/js/main.ts b/js/main.ts
index b099496..32c5a5b 100644
--- a/js/main.ts
+++ b/js/main.ts
@@ -14,14 +14,29 @@ function ensureSetting(key: string, defaultValue: string): string {
14const settings = new KeyValueStore({ 14const settings = new KeyValueStore({
15 wordWrap: { 15 wordWrap: {
16 value: ensureSetting('word-wrap', '1') === '1', 16 value: ensureSetting('word-wrap', '1') === '1',
17 callbacks: [
18 value => {
19 localStorage.setItem('word-wrap', value ? '1' : '0');
20 }
21 ],
17 valueRange: [false, true] 22 valueRange: [false, true]
18 }, 23 },
19 imagePreviews: { 24 imagePreviews: {
20 value: ensureSetting('image-previews', '1') === '1', 25 value: ensureSetting('image-previews', '1') === '1',
26 callbacks: [
27 value => {
28 localStorage.setItem('image-previews', value ? '1' : '0');
29 }
30 ],
21 valueRange: [false, true] 31 valueRange: [false, true]
22 }, 32 },
23 clickablePlainLinks: { 33 clickablePlainLinks: {
24 value: ensureSetting('clickable-plain-links', '1') === '1', 34 value: ensureSetting('clickable-plain-links', '1') === '1',
35 callbacks: [
36 value => {
37 localStorage.setItem('clickable-plain-links', value ? '1' : '0');
38 }
39 ],
25 valueRange: [false, true] 40 valueRange: [false, true]
26 }, 41 },
27}); 42});
@@ -81,7 +96,6 @@ const settings = new KeyValueStore({
81 removeImageThumbnails(); 96 removeImageThumbnails();
82 } 97 }
83 98
84 localStorage.setItem('image-previews', value ? '1' : '0');
85 settingImagePreviewValueEl.textContent = value ? '[yes]' : '[no]'; 99 settingImagePreviewValueEl.textContent = value ? '[yes]' : '[no]';
86 } 100 }
87 101
@@ -105,7 +119,6 @@ const settings = new KeyValueStore({
105 contentEl.classList.remove("content--wrap"); 119 contentEl.classList.remove("content--wrap");
106 } 120 }
107 121
108 localStorage.setItem('word-wrap', value ? '1' : '0');
109 settingWordWrapValueEl.textContent = value ? '[yes]' : '[no]'; 122 settingWordWrapValueEl.textContent = value ? '[yes]' : '[no]';
110 } 123 }
111 124
@@ -129,7 +142,6 @@ const settings = new KeyValueStore({
129 removeMarkupForPlainLinks(); 142 removeMarkupForPlainLinks();
130 } 143 }
131 144
132 localStorage.setItem('clickable-plain-links', value ? '1' : '0');
133 clickablePlainLinksValueEl.textContent = value ? '[yes]' : '[no]'; 145 clickablePlainLinksValueEl.textContent = value ? '[yes]' : '[no]';
134 } 146 }
135 147
@@ -254,7 +266,7 @@ function generateMarkupForPlainLinks() {
254 } 266 }
255 267
256 const contentEl = document.getElementsByClassName('content')[0]; 268 const contentEl = document.getElementsByClassName('content')[0];
257 const urlRegex = /\b([a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*)/g; 269 const urlRegex = /\b[a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*/g;
258 const mailRegex = /\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g; 270 const mailRegex = /\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g;
259 271
260 contentEl.innerHTML = contentEl.innerHTML.replace(urlRegex, match => { 272 contentEl.innerHTML = contentEl.innerHTML.replace(urlRegex, match => {