From 7c5eaa74d92ab6be2db7ea83ec6dd48145587539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Sun, 7 Jan 2024 16:18:49 +0100 Subject: [PATCH] Added a webservice static JS library --- js_library.go | 17 +++++++-- pkg.go | 2 +- static/js/websocket.js | 22 ------------ static/js/websocket.mjs | 77 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 25 deletions(-) delete mode 100644 static/js/websocket.js create mode 100644 static/js/websocket.mjs diff --git a/js_library.go b/js_library.go index a02bda2..a0cfd46 100644 --- a/js_library.go +++ b/js_library.go @@ -5,15 +5,28 @@ import ( "embed" "fmt" "net/http" + "regexp" ) var ( //go:embed static/js embedded embed.FS + pathMatcher *regexp.Regexp = regexp.MustCompile("^/_js/v[0-9]+/(.*)$") ) -func staticJSWebsocket(w http.ResponseWriter, r *http.Request) { - contents, err := embedded.ReadFile("static/js/websocket.js") +func (service *Service) staticJSHandler(w http.ResponseWriter, r *http.Request) { + var path string + if comp := pathMatcher.FindStringSubmatch(r.URL.Path); comp != nil { + path = fmt.Sprintf("static/js/%s", comp[1]) + } else { + service.logger.Debug("webservice", "request", r.URL.Path) + return + } + + service.logger.Debug("webservice", "request", r.URL.Path, "path", path) + w.Header().Add("Content-Type", "text/javascript") + + contents, err := embedded.ReadFile(path) if err != nil { fmt.Println(err) return diff --git a/pkg.go b/pkg.go index d87d33f..71ffd91 100644 --- a/pkg.go +++ b/pkg.go @@ -106,7 +106,7 @@ func New(configFilename, version string, logger *slog.Logger) (service *Service, http.HandleFunc("/_ws", service.websocketHandler) http.HandleFunc("/_ws/css_update", service.cssUpdateHandler) - http.HandleFunc("/_js/websocket.js", staticJSWebsocket) + http.HandleFunc("/_js/", service.staticJSHandler) return } // }}} diff --git a/static/js/websocket.js b/static/js/websocket.js deleted file mode 100644 index b3e92d7..0000000 --- a/static/js/websocket.js +++ /dev/null @@ -1,22 +0,0 @@ -package webservice - -import ( - // Standard - "embed" - "fmt" - "net/http" -) - -var ( - //go:embed foo.txt - embedded embed.FS -) - -func staticJSWebsocket(w http.ResponseWriter, r *http.Request) { - contents, err := embedded.ReadFile("foo.txt") - if err != nil { - fmt.Println(err) - return - } - w.Write(contents) -} diff --git a/static/js/websocket.mjs b/static/js/websocket.mjs new file mode 100644 index 0000000..459bae1 --- /dev/null +++ b/static/js/websocket.mjs @@ -0,0 +1,77 @@ +export class Websocket { + constructor() {//{{{ + this.websocket = null + this.websocket_int_ping = null + this.websocket_int_reconnect = null + this.hooks = { + open: [], + message: [], + error: [], + close: [], + } + }//}}} + + register(event, fn) {//{{{ + this.hooks[event].push(fn) + }//}}} + + start() {//{{{ + this.connect() + //this.loop() + }//}}} + loop() {//{{{ + setInterval(() => { + if (this.websocket === null) { + console.log("websocket loop connect") + this.connect() + } + }, 1000) + }//}}} + + connect() {//{{{ + const protocol = location.protocol; + const domain = location.hostname; + const port = location.port; + + let wsProtocol = 'wss' + if (protocol == 'http:') + wsProtocol = 'ws' + const websocketURI = `${wsProtocol}://${domain}:${port}/_ws` + + this.websocket = new WebSocket(websocketURI) + this.websocket.onopen = (evt) => this.open(evt) + this.websocket.onmessage = (evt) => this.message(evt) + this.websocket.onerror = (evt) => this.error(evt) + this.websocket.onclose = (evt) => this.close(evt) + }//}}} + open() {//{{{ + this.hooks.open.forEach(fn=>fn()) + // A ping interval to implement a rudimentary keep-alive. + }//}}} + close() {//{{{ + this.websocket = null + this.hooks.close.forEach(fn=>fn()) + }//}}} + error(evt) {//{{{ + this.websocket = null; + this.hooks.error.forEach(fn=>fn(evt)) + }//}}} + message(evt) {//{{{ + const msg = JSON.parse(evt.data) + if (msg.ID == '' && msg.Op == 'css_reload') + this.refreshCSS() + + this.hooks.message.forEach(fn=>fn(evt.data)) + return + }//}}} + + refreshCSS() {//{{{ + let links = document.getElementsByTagName('link') + Array.from(links).forEach(l=>{ + if (l.rel == 'stylesheet' && !l.hasAttribute('x-no-reload')) { + l.href = l.href.replace(/\?.*/, '') + `?cache=${Date.now()}` + console.log(l.href) + } + }) + }//}}} +}