aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeuerfuchs <git@feuerfuchs.dev>2019-06-23 17:29:07 +0200
committerFeuerfuchs <git@feuerfuchs.dev>2019-06-23 17:29:07 +0200
commitc448abd99a470e1ec541027077dcdef0745270d8 (patch)
tree433def56b6f0e81457cbe39fc85f402a9e4e18a8
parentCheck type instead of file ext to render text via tpl (diff)
downloadgopherproxy-c448abd99a470e1ec541027077dcdef0745270d8.tar.gz
gopherproxy-c448abd99a470e1ec541027077dcdef0745270d8.tar.bz2
gopherproxy-c448abd99a470e1ec541027077dcdef0745270d8.zip
Show expandable thumbnails for images
-rw-r--r--Makefile1
-rw-r--r--assets/main.js39
-rw-r--r--assets/style.css2
-rw-r--r--css/main.scss58
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--gopherproxy.go42
-rw-r--r--js/main.ts42
-rw-r--r--template.go16
9 files changed, 176 insertions, 30 deletions
diff --git a/Makefile b/Makefile
index f25707c..da35555 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@ 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 --outFile assets/main.js js/main.ts
10 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=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=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=glyphs.txt --flavor='woff2' --output-file='assets/iosevka-term-ss03-regular.woff2'
12 go build -o ./gopherproxy ./cmd/gopherproxy/main.go 13 go build -o ./gopherproxy ./cmd/gopherproxy/main.go
diff --git a/assets/main.js b/assets/main.js
new file mode 100644
index 0000000..46cb7ee
--- /dev/null
+++ b/assets/main.js
@@ -0,0 +1,39 @@
1"use strict";
2var linkQryEls = document.getElementsByClassName('link--QRY');
3var i = linkQryEls.length;
4while (i--) {
5 linkQryEls[i].addEventListener('click', function (e) {
6 e.preventDefault();
7 var resp = prompt('Please enter required input: ', '');
8 if ((resp !== null) && (resp !== "")) {
9 window.location.href = e.target.href + '?' + resp;
10 }
11 return false;
12 });
13}
14var imgPreviewEls = document.getElementsByClassName('img-preview');
15i = imgPreviewEls.length;
16var _loop_1 = function () {
17 var imgPreviewEl = imgPreviewEls[i];
18 var child = imgPreviewEl.children[0];
19 var thumbnailUrl = child.src;
20 child.addEventListener('load', function (e) {
21 child.classList.remove('faded');
22 });
23 imgPreviewEls[i].addEventListener('click', function (e) {
24 e.preventDefault();
25 child.classList.add('faded');
26 if (child.classList.contains('expanded')) {
27 child.classList.remove('expanded');
28 child.src = thumbnailUrl;
29 }
30 else {
31 child.classList.add('expanded');
32 child.src = imgPreviewEl.href;
33 }
34 return false;
35 });
36};
37while (i--) {
38 _loop_1();
39}
diff --git a/assets/style.css b/assets/style.css
index 5891d3b..46ad8cb 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -1 +1 @@
@font-face{font-family:'Iosevka Term SS03';font-style:normal;font-weight:normal;src:url("/iosevka-term-ss03-regular.woff2") format("woff2"),url("/iosevka-term-ss03-regular.woff") format("woff")}body{margin:0;padding:0;background-color:#14171a;color:#cad1d8}::selection{color:#000;background-color:rgba(239,198,138,0.996)}:link{color:#fff}:visited{color:#cad1d8}.header{padding:.9em 1em;border-bottom:1px solid #353a3f;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.3;color:#686f76}.header__uripart{color:#929ba3}.header__uripart--last{color:#fff}.wrap{text-align:center}.content{display:inline-block;min-width:50em;min-width:85ch;margin:0;padding:2em 1em;text-align:left;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}.link-type{color:#929ba3} @font-face{font-family:'Iosevka Term SS03';font-style:normal;font-weight:normal;src:url("/iosevka-term-ss03-regular.woff2") format("woff2"),url("/iosevka-term-ss03-regular.woff") format("woff")}body{margin:0;padding:0;background-color:#14171a;color:#cad1d8}button{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;background:none;border:0;padding:0;color:#fff}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}::selection{color:#000;background-color:rgba(239,198,138,0.996)}:link{color:#fff}:visited{color:#cad1d8}.header{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;padding:.9em 1em;border-bottom:1px solid #353a3f;line-height:1.3;color:#686f76}.header__uripart{color:#929ba3}.header__uripart--last{color:#fff}.wrap{text-align:center}.content{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;display:inline-block;min-width:50em;min-width:85ch;margin:0;padding:2em 1em;text-align:left}.type-annotation{color:#929ba3}
diff --git a/css/main.scss b/css/main.scss
index d0646d7..0d5a5d9 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -10,6 +10,12 @@ $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@mixin monospace-font {
14 font-family: 'Iosevka Term SS03', 'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace;
15 font-size: 1 / 16 * 17em;
16 line-height: 1.5;
17}
18
13@font-face { 19@font-face {
14 font-family: 'Iosevka Term SS03'; 20 font-family: 'Iosevka Term SS03';
15 font-style: normal; 21 font-style: normal;
@@ -31,6 +37,35 @@ body {
31 color: $text; 37 color: $text;
32} 38}
33 39
40button {
41 @include monospace-font;
42
43 background: none;
44 border: 0;
45 padding: 0;
46 color: $text-plus;
47}
48
49img {
50 display: inline-block;
51 vertical-align: top;
52 max-width: 8em;
53 margin: .1em 0;
54
55 &::selection {
56 background-color: rgba($sel-background, .35);
57 }
58
59 &.expanded {
60 max-width: 40em;
61 max-width: 80ch;
62 }
63
64 &.faded {
65 opacity: .5;
66 }
67}
68
34::selection { 69::selection {
35 color: $sel-text; 70 color: $sel-text;
36 background-color: $sel-background; 71 background-color: $sel-background;
@@ -51,10 +86,10 @@ body {
51// } 86// }
52 87
53.header { 88.header {
89 @include monospace-font;
90
54 padding: .9em 1em; 91 padding: .9em 1em;
55 border-bottom: 1px solid $border; 92 border-bottom: 1px solid $border;
56 font-family: 'Iosevka Term SS03', 'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace;
57 font-size: 1 / 16 * 17em;
58 line-height: 1.3; 93 line-height: 1.3;
59 color: $text-faint; 94 color: $text-faint;
60} 95}
@@ -72,17 +107,16 @@ body {
72} 107}
73 108
74.content { 109.content {
75 display: inline-block; 110 @include monospace-font;
76 min-width: 50em; 111
77 min-width: 5ch + 80; 112 display: inline-block;
78 margin: 0; 113 min-width: 50em;
79 padding: 2em 1em; 114 min-width: 5ch + 80;
80 text-align: left; 115 margin: 0;
81 font-family: 'Iosevka Term SS03', 'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace; 116 padding: 2em 1em;
82 font-size: 1 / 16 * 17em; 117 text-align: left;
83 line-height: 1.5;
84} 118}
85 119
86.link-type { 120.type-annotation {
87 color: $text-minus; 121 color: $text-minus;
88} 122}
diff --git a/go.mod b/go.mod
index 099e4c0..b16bbe9 100644
--- a/go.mod
+++ b/go.mod
@@ -1,7 +1,9 @@
1module git.feuerfuchs.dev/Feuerfuchs/gopherproxy 1module git.feuerfuchs.dev/Feuerfuchs/gopherproxy
2 2
3require ( 3require (
4 github.com/davidbyttow/govips v0.0.0-20190304175058-d272f04c0fea
4 github.com/gobuffalo/packr v1.25.0 5 github.com/gobuffalo/packr v1.25.0
6 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
5 github.com/prologic/go-gopher v0.0.0-20181230133552-0c68ed5f58b0 7 github.com/prologic/go-gopher v0.0.0-20181230133552-0c68ed5f58b0
6 github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea 8 github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea
7) 9)
diff --git a/go.sum b/go.sum
index 89aa345..08d6ae0 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,8 @@
1github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 1github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4github.com/davidbyttow/govips v0.0.0-20190304175058-d272f04c0fea h1:ZtETbJTO1R3qVLdVbpjrDhD5fR8bYVhhq2RMi7rOlH4=
5github.com/davidbyttow/govips v0.0.0-20190304175058-d272f04c0fea/go.mod h1:a3qO525EPfJNYa0NXBcNtXzJvyQsJAxphEDa7OOHPBk=
4github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= 6github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
5github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= 7github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
6github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= 8github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
@@ -33,6 +35,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
33github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 35github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
34github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= 36github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
35github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= 37github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
38github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
39github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
36github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 40github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
37github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 41github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
38github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 42github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
diff --git a/gopherproxy.go b/gopherproxy.go
index 11c08d5..62b7446 100644
--- a/gopherproxy.go
+++ b/gopherproxy.go
@@ -10,6 +10,7 @@ import (
10 "log" 10 "log"
11 "net/http" 11 "net/http"
12 "net/url" 12 "net/url"
13 "regexp"
13 "strings" 14 "strings"
14 15
15 "github.com/temoto/robotstxt" 16 "github.com/temoto/robotstxt"
@@ -17,6 +18,8 @@ import (
17 "github.com/prologic/go-gopher" 18 "github.com/prologic/go-gopher"
18 19
19 "github.com/gobuffalo/packr" 20 "github.com/gobuffalo/packr"
21
22 "github.com/davidbyttow/govips/pkg/vips"
20) 23)
21 24
22type Item struct { 25type Item struct {
@@ -25,7 +28,7 @@ type Item struct {
25 Text string 28 Text string
26} 29}
27 30
28func renderDirectory(w http.ResponseWriter, tpl *template.Template, styletext string, uri string, hostport string, d gopher.Directory) error { 31func renderDirectory(w http.ResponseWriter, tpl *template.Template, styletext string, jstext string, uri string, hostport string, d gopher.Directory) error {
29 var title string 32 var title string
30 33
31 out := make([]Item, len(d.Items)) 34 out := make([]Item, len(d.Items))
@@ -78,9 +81,10 @@ func renderDirectory(w http.ResponseWriter, tpl *template.Template, styletext st
78 Title string 81 Title string
79 URI string 82 URI string
80 Style string 83 Style string
84 Script string
81 Lines []Item 85 Lines []Item
82 RawText string 86 RawText string
83 }{title, fmt.Sprintf("%s/%s", hostport, uri), styletext, out, ""}) 87 }{title, fmt.Sprintf("%s/%s", hostport, uri), styletext, jstext, out, ""})
84} 88}
85 89
86// GopherHandler returns a Handler that proxies requests 90// GopherHandler returns a Handler that proxies requests
@@ -88,7 +92,7 @@ func renderDirectory(w http.ResponseWriter, tpl *template.Template, styletext st
88// to the request path and renders the content using the provided template. 92// to the request path and renders the content using the provided template.
89// The optional robots parameters points to a robotstxt.RobotsData struct 93// The optional robots parameters points to a robotstxt.RobotsData struct
90// to test user agents against a configurable robotst.txt file. 94// to test user agents against a configurable robotst.txt file.
91func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, robotsdebug bool, styletext string, uri string) http.HandlerFunc { 95func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, robotsdebug bool, styletext string, jstext string, uri string) http.HandlerFunc {
92 return func(w http.ResponseWriter, req *http.Request) { 96 return func(w http.ResponseWriter, req *http.Request) {
93 agent := req.UserAgent() 97 agent := req.UserAgent()
94 path := strings.TrimPrefix(req.URL.Path, "/") 98 path := strings.TrimPrefix(req.URL.Path, "/")
@@ -140,14 +144,23 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, rob
140 Title string 144 Title string
141 URI string 145 URI string
142 Style string 146 Style string
147 Script string
143 RawText string 148 RawText string
144 Lines []Item 149 Lines []Item
145 }{uri, fmt.Sprintf("%s/%s", hostport, uri), styletext, buf.String(), nil}) 150 }{uri, fmt.Sprintf("%s/%s", hostport, uri), styletext, jstext, buf.String(), nil})
151 } else if parts[1] == "T" {
152 _, _, err = vips.NewTransform().
153 Load(res.Body).
154 ResizeStrategy(vips.ResizeStrategyAuto).
155 ResizeWidth(160).
156 Quality(75).
157 Output(w).
158 Apply()
146 } else { 159 } else {
147 io.Copy(w, res.Body) 160 io.Copy(w, res.Body)
148 } 161 }
149 } else { 162 } else {
150 if err := renderDirectory(w, tpl, styletext, uri, hostport, res.Dir); err != nil { 163 if err := renderDirectory(w, tpl, styletext, jstext, uri, hostport, res.Dir); err != nil {
151 io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) 164 io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err))
152 return 165 return
153 } 166 }
@@ -240,6 +253,11 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, uri string) error
240 styletext = "" 253 styletext = ""
241 } 254 }
242 255
256 jstext, err := box.FindString("main.js")
257 if err != nil {
258 jstext = ""
259 }
260
243 favicondata, err := box.Find("favicon.ico") 261 favicondata, err := box.Find("favicon.ico")
244 if err != nil { 262 if err != nil {
245 favicondata = []byte{} 263 favicondata = []byte{}
@@ -257,6 +275,9 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, uri string) error
257 "safeCss": func(s string) template.CSS { 275 "safeCss": func(s string) template.CSS {
258 return template.CSS(s) 276 return template.CSS(s)
259 }, 277 },
278 "safeJs": func(s string) template.JS {
279 return template.JS(s)
280 },
260 "HTMLEscape": func(s string) string { 281 "HTMLEscape": func(s string) string {
261 return html.EscapeString(s) 282 return html.EscapeString(s)
262 }, 283 },
@@ -267,6 +288,11 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, uri string) error
267 "pop": func(s []string) []string { 288 "pop": func(s []string) []string {
268 return s[:len(s)-1] 289 return s[:len(s)-1]
269 }, 290 },
291 "replace": func(pattern, output string, input interface{}) string {
292 var re = regexp.MustCompile(pattern)
293 var inputStr = fmt.Sprintf("%v", input)
294 return re.ReplaceAllString(inputStr, output)
295 },
270 } 296 }
271 297
272 tpl, err = template.New("gophermenu").Funcs(funcMap).Parse(tpltext) 298 tpl, err = template.New("gophermenu").Funcs(funcMap).Parse(tpltext)
@@ -274,7 +300,11 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, uri string) error
274 log.Fatal(err) 300 log.Fatal(err)
275 } 301 }
276 302
277 http.HandleFunc("/", GopherHandler(tpl, robotsdata, robotsdebug, styletext, uri)) 303 vips.Startup(&vips.Config{
304 ConcurrencyLevel: 2,
305 })
306
307 http.HandleFunc("/", GopherHandler(tpl, robotsdata, robotsdebug, styletext, jstext, uri))
278 http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) 308 http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata))
279 http.HandleFunc("/favicon.ico", FaviconHandler(favicondata)) 309 http.HandleFunc("/favicon.ico", FaviconHandler(favicondata))
280 http.HandleFunc("/iosevka-term-ss03-regular.woff", FontHandler(false, fontdataw)) 310 http.HandleFunc("/iosevka-term-ss03-regular.woff", FontHandler(false, fontdataw))
diff --git a/js/main.ts b/js/main.ts
new file mode 100644
index 0000000..21e589d
--- /dev/null
+++ b/js/main.ts
@@ -0,0 +1,42 @@
1let linkQryEls = document.getElementsByClassName('link--QRY');
2let i = linkQryEls.length;
3while (i--) {
4 linkQryEls[i].addEventListener('click', e => {
5 e.preventDefault();
6
7 const resp = prompt('Please enter required input: ', '');
8 if ((resp !== null) && (resp !== "")) {
9 window.location.href = (e.target as HTMLAnchorElement).href + '?' + resp;
10 }
11
12 return false;
13 });
14}
15
16let imgPreviewEls = document.getElementsByClassName('img-preview');
17i = imgPreviewEls.length;
18while (i--) {
19 const imgPreviewEl = imgPreviewEls[i] as HTMLAnchorElement;
20 const child = imgPreviewEl.children[0] as HTMLImageElement;
21 const thumbnailUrl = child.src;
22
23 child.addEventListener('load', e => {
24 child.classList.remove('faded');
25 });
26
27 imgPreviewEls[i].addEventListener('click', e => {
28 e.preventDefault();
29
30 child.classList.add('faded');
31
32 if (child.classList.contains('expanded')) {
33 child.classList.remove('expanded');
34 child.src = thumbnailUrl;
35 } else {
36 child.classList.add('expanded');
37 child.src = imgPreviewEl.href;
38 }
39
40 return false;
41 });
42}
diff --git a/template.go b/template.go
index 33486d5..f5f4f2b 100644
--- a/template.go
+++ b/template.go
@@ -47,7 +47,10 @@ var tpltext = `<!doctype html>
47 {{- $content = printf "%s\n" $content -}} 47 {{- $content = printf "%s\n" $content -}}
48 {{- end -}} 48 {{- end -}}
49 {{- if .Link -}} 49 {{- if .Link -}}
50 {{- $content = printf "%s%s" $content (printf "<span class=\"link-type\">%s </span><a class=\"link link--%s\" href=\"%s\">%s</a>" .Type .Type .Link (.Text | HTMLEscape)) -}} 50 {{- $content = printf "%s%s" $content (printf "<span class=\"type-annotation\">%s </span><a class=\"link link--%s\" href=\"%s\">%s</a>" .Type .Type .Link (.Text | HTMLEscape)) -}}
51 {{- if or (eq .Type "IMG") (eq .Type "GIF") -}}
52 {{- $content = printf "%s\n%s" $content (printf "<span class=\"type-annotation\"> -> </span><a class=\"img-preview\" href=\"%s\"><img src=\"%s\" /></a>" .Link (.Link | replace "^/(.*?)/I" "/$1/T")) -}}
53 {{- end -}}
51 {{- else -}} 54 {{- else -}}
52 {{- $content = printf "%s%s" $content (printf " %s" (.Text | HTMLEscape)) -}} 55 {{- $content = printf "%s%s" $content (printf " %s" (.Text | HTMLEscape)) -}}
53 {{- end -}} 56 {{- end -}}
@@ -59,16 +62,7 @@ var tpltext = `<!doctype html>
59 </pre> 62 </pre>
60 </main> 63 </main>
61 <script type="text/javascript"> 64 <script type="text/javascript">
62 var qry=document.getElementsByClassName('link--QRY') 65 {{ .Script | safeJs }}
63 var i=qry.length
64 while (i--) {
65 qry[i].addEventListener('click', function(e) {
66 e.preventDefault();
67 var resp=prompt("Please enter required input: ", "")
68 if (resp !== null && resp !== "") window.location = e.target.href + "?" + resp
69 return false;
70 })
71 }
72 </script> 66 </script>
73 </body> 67 </body>
74</html>` 68</html>`