diff options
-rw-r--r-- | module/entry-points/server.scm | 34 | ||||
-rw-r--r-- | module/server/macro.scm | 17 | ||||
-rw-r--r-- | static/script.js | 13 |
3 files changed, 46 insertions, 18 deletions
diff --git a/module/entry-points/server.scm b/module/entry-points/server.scm index 3dab6e9c..63fb83a8 100644 --- a/module/entry-points/server.scm +++ b/module/entry-points/server.scm @@ -39,20 +39,22 @@ (with-output-to-string (lambda () (display "<!doctype html>\n") (sxml->xml sxml)))) +(define (// . args) (string-join args file-name-separator-string )) + (define (directory-table dir) `(table (thead (tr (th "") (th "Name") (th "Perm"))) (tbody ,@(map (lambda (k) - (let* ((stat (lstat k))) + (let* ((stat (lstat (// dir k)))) `(tr (td ,(case (stat:type stat) [(directory) "📁"] [(regular) "📰"] [else "🙃"])) - (td (a (@ (href "/" ,dir ,k)) ,k)) + (td (a (@ (href "/" ,dir "/" ,k)) ,k)) (td ,(number->string (stat:perms stat) 8))))) - (cddr (scandir dir)))))) + (cdr (scandir dir)))))) (define-method (make-make-routes) @@ -99,7 +101,7 @@ (ical-main (parse-iso-date start) (parse-iso-date end)))))) - ;; TODO this returns "invalid" events, since the surrounding VCALENDAR is missing. + ;; TODO this fails if there's a period in the uid. (GET "/calendar/:uid.ics" (uid) (aif (get-event-by-uid uid) (return '((content-type text/calendar)) @@ -109,23 +111,23 @@ (return (build-response code: 404) (format #f "No component with UID=~a found." uid)))) - (GET "/static" () - (return - '((content-type text/html)) - (sxml->html-string - (directory-table "static/")))) + ;; NOTE this only handles files with extensions. Limited, but since this + ;; is mostly for development, and something like nginx should be used in + ;; production it isn't a huge problem. - (GET "/static/:filename.css" (filename) + (GET "/static/:*{.*}.:ext" (* ext) (return - `((content-type text/css)) - (call-with-input-file (string-append "static/" filename ".css") + ;; TODO actually check mimetype + `((content-type ,(string->symbol (string-append "text/" ext)))) + (call-with-input-file (string-append "static/" * "." ext) read-string))) - (GET "/static/:filename.js" (filename) + (GET "/static/:*{.*}" (*) (return - `((content-type text/javascript)) - (call-with-input-file (string-append "static/" filename ".js") - read-string))) + '((content-type text/html)) + (sxml->html-string + (directory-table (// "static" *))))) + (GET "/count" () ;; (sleep 1) diff --git a/module/server/macro.scm b/module/server/macro.scm index b9ce94bb..28565c3b 100644 --- a/module/server/macro.scm +++ b/module/server/macro.scm @@ -9,15 +9,28 @@ (define-public (parse-endpoint-string str) - (let ((rx (make-regexp ":([^/.]+)"))) + (let ((rx (make-regexp ":([^/.]+)(\\{([^}]+)\\})?([.])?"))) (let loop ((str str) (string "") (tokens '())) (let ((m (regexp-exec rx str 0))) (if (not m) + ;; done (values (string-append string str) (reverse tokens)) + (loop (match:suffix m) - (string-append string (match:prefix m) "([^/.]+)") + (string-append string (match:prefix m) + (aif (match:substring m 3) + (string-append "(" it ")") + "([^/.]+)") + ;; period directly following matched variable. + ;; since many variables break on period, we often + ;; want to match a literal period directly after them. + ;; Ideally all periods outside of pattern should be + ;; matched literally, but that's harder to implement. + (regexp-quote + (aif (match:substring m 4) + "." ""))) (cons (string->symbol (match:substring m 1)) tokens))))))) diff --git a/static/script.js b/static/script.js index b94e8f06..8617159a 100644 --- a/static/script.js +++ b/static/script.js @@ -222,6 +222,12 @@ function setVar(str, val) { document.documentElement.style.setProperty("--" + str, val); } +function close_all_popups () { + for (let popup of document.getElementsByClassName("popup")) { + popup.classList.remove("show"); + } +} + window.onload = function () { start_time.setTime(document.querySelector("meta[name='start-time']").content * 1000) end_time.setTime(document.querySelector("meta[name='end-time']").content * 1000) @@ -255,4 +261,11 @@ window.onload = function () { e.parentElement.removeAttribute("href"); } + document.onkeydown = function (evt) { + evt = evt || window.event; + if (evt.key.startsWith("Esc")) { + close_all_popups(); + } + } + } |