diff --git a/src/application-globals.rkt b/src/application-globals.rkt index 5884804..0d6b3dd 100644 --- a/src/application-globals.rkt +++ b/src/application-globals.rkt @@ -164,7 +164,8 @@ #:siteinfo [siteinfo-in #f] #:user-cookies [user-cookies-in #f] #:online-styles [online-styles #t] - #:path [path-in #f]) + #:path [path-in #f] + #:jsonp [jsonp-in #f]) (define siteinfo (or siteinfo-in siteinfo-default)) (define head-data (or head-data-in ((head-data-getter wikiname)))) (define user-cookies (or user-cookies-in (user-cookies-getter req))) @@ -200,12 +201,14 @@ (script "const BWData = " ,(jsexpr->string (hasheq 'wikiname wikiname 'strict_proxy (config-true? 'strict_proxy) - 'path path))) + 'path path + 'jsonp jsonp-in))) + (script (@ (type "importmap")) ,importmap) ,(if (config-true? 'feature_search_suggestions) `(script (@ (type "module") (src ,(get-static-url "search-suggestions.js")))) "") (script (@ (type "module") (src ,(get-static-url "countdown.js")))) - (script (@ (defer) (src ,(get-static-url "tabs.js")))) + (script (@ (type "module") (src ,(get-static-url "tabs.js")))) (link (@ (rel "icon") (href ,(u (λ (v) (config-true? 'strict_proxy)) (λ (v) (u-proxy-url v)) (head-data^-icon-url head-data)))))) diff --git a/src/page-wiki-jsonp.rkt b/src/page-wiki-jsonp.rkt index 0c7918c..ada846e 100644 --- a/src/page-wiki-jsonp.rkt +++ b/src/page-wiki-jsonp.rkt @@ -61,7 +61,8 @@ END #:wikiname wikiname #:title (url-segments->guess-title segments) #:siteinfo siteinfo-default - #:path path)) + #:path path + #:jsonp #t)) (when (config-true? 'debug) (xexp->html body)) (response/output diff --git a/src/static-data.rkt b/src/static-data.rkt index 1255ca5..ec7eede 100644 --- a/src/static-data.rkt +++ b/src/static-data.rkt @@ -1,16 +1,20 @@ #lang typed/racket/base (require racket/path racket/runtime-path - racket/string) + racket/string + typed/json) (provide get-static-url + importmap link-header) (define-runtime-path path-static "../static") (define static-data - (for/hash : (Immutable-HashTable Path Nonnegative-Integer)([f (directory-list path-static)]) + (for/hash : (Immutable-HashTable Path Nonnegative-Integer) + ([f (directory-list path-static)] + #:when (not (regexp-match? #rx"^.#|^#|~$" (path->string f)))) (define built (simple-form-path (build-path path-static f))) (values built (file-or-directory-modify-seconds built)))) @@ -21,12 +25,21 @@ (build-path path-static path-or-filename)))) (format "/static/~a?t=~a" (file-name-from-path the-path) (hash-ref static-data the-path))) +(: importmap String) +(define importmap + (jsexpr->string + `#hasheq((imports . ,(for/hasheq : (Immutable-HashTable Symbol String) + ([(k v) (in-hash static-data)] + #:when (equal? (path-get-extension k) #".js")) + (values (string->symbol (path->string (path-replace-extension (assert (file-name-from-path k) path?) #""))) + (get-static-url k))))))) + ; https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload (: link-header String) (define link-header - (let* ([with-t '(("main.css" "as=style"))] - [without-t '(("preact.js" "as=script") - ("source-sans-pro-v21-vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2" "as=font" "crossorigin" "type=font/woff2"))] + (let* ([with-t '(("main.css" "as=style") + ("preact.js" "as=script"))] + [without-t '(("source-sans-pro-v21-vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2" "as=font" "crossorigin" "type=font/woff2"))] [with-t-full (map (λ ([path : (Listof String)]) (cons (get-static-url (car path)) (cdr path))) with-t)] [without-t-full (map (λ ([path : (Listof String)]) (cons (format "/static/~a" (car path)) (cdr path))) without-t)] [all (append with-t-full without-t-full)] diff --git a/static/countdown.js b/static/countdown.js index ad8d0be..92b9c06 100644 --- a/static/countdown.js +++ b/static/countdown.js @@ -2,7 +2,7 @@ // sample: bandori/wiki/BanG_Dream!_Wikia // sample: ensemble-stars/wiki/The_English_Ensemble_Stars_Wiki -import {h, htm, render, signal, computed, effect} from "./preact.js" +import {h, htm, render, signal, computed, effect} from "preact" const html = htm.bind(h) const now = signal(Date.now()) diff --git a/static/jsonp.js b/static/jsonp.js index 851f86e..a183b0f 100644 --- a/static/jsonp.js +++ b/static/jsonp.js @@ -1,6 +1,11 @@ -import {h, htm, render, signal, computed, effect} from "./preact.js" +import {h, htm, render, signal, computed, effect} from "preact" const html = htm.bind(h) +// *** Status + +const loaded = signal(false) +export {loaded} + // *** Loading indicator render(html`Loading, please wait...`, document.getElementById("loading")) @@ -69,6 +74,7 @@ async function cont() { if (redirectTo) { redirectTo.click() } + loaded.value = true }) xhr.open("POST", "/api/render/wiki") diff --git a/static/search-suggestions.js b/static/search-suggestions.js index e0a32d6..ddd2927 100644 --- a/static/search-suggestions.js +++ b/static/search-suggestions.js @@ -1,4 +1,4 @@ -import {h, htm, render, signal, computed, effect} from "./preact.js" +import {h, htm, render, signal, computed, effect} from "preact" const html = htm.bind(h) const classNames = classArr => classArr.filter(el => el).join(" ") diff --git a/static/tabs.js b/static/tabs.js index 718b48e..bbf5d2a 100644 --- a/static/tabs.js +++ b/static/tabs.js @@ -1,19 +1,22 @@ -"use strict"; +import {effect} from "preact" +import {loaded} from "jsonp" const tabFromHash = location.hash.length > 1 ? location.hash.substring(1) : null -for (const tabber of document.body.querySelectorAll(".wds-tabber")) { - for (const [tab, content] of getTabberTabs(tabber)) { - // set up click listener on every tab - tab.addEventListener("click", e => { - setCurrentTab(tabber, tab, content) - e.preventDefault() - }) +function setUpAllTabs() { + for (const tabber of document.body.querySelectorAll(".wds-tabber")) { + for (const [tab, content] of getTabberTabs(tabber)) { + // set up click listener on every tab + tab.addEventListener("click", e => { + setCurrentTab(tabber, tab, content) + e.preventDefault() + }) - // re-open a specific tab on page load based on the URL hash - if (tab.dataset.hash === tabFromHash) { - setCurrentTab(tabber, tab, content) - tab.scrollIntoView() + // re-open a specific tab on page load based on the URL hash + if (tab.dataset.hash === tabFromHash) { + setCurrentTab(tabber, tab, content) + tab.scrollIntoView() + } } } } @@ -37,4 +40,16 @@ function setCurrentTab(tabber, tab, content) { } } +if (!BWData.jsonp) { + setUpAllTabs() +} else if (loaded.value) { + setUpAllTabs() +} else { + effect(() => { + if (loaded.value) { + setUpAllTabs() + } + }) +} + document.body.classList.remove("bw-tabs-nojs")