Vendor Alpine, Flowbite and Datepicker bundles locally

Serve alpinejs 3.15.12, @alpinejs/mask 3.15.12, flowbite 2.4.1 and
flowbite-datepicker 2.0.0 from games/static/js/ instead of jsdelivr, so
pages (and browser tests) work without network access. Adds the
StaticScript primitive for vendored UMD bundles, which cannot be loaded
as ES modules.

https://claude.ai/code/session_01BKurBhE3Qj25p7Bfsg7EeK
This commit is contained in:
Claude
2026-06-12 21:18:35 +00:00
parent be919c992d
commit 88cf374f33
8 changed files with 2810 additions and 8 deletions
+2
View File
@@ -59,6 +59,7 @@ from common.components.primitives import (
SearchField,
SimpleTable,
Span,
StaticScript,
TableHeader,
TableRow,
TableTd,
@@ -112,6 +113,7 @@ __all__ = [
"searchselect_selected",
"SimpleTable",
"Span",
"StaticScript",
"Label",
"TableHeader",
"TableRow",
+6
View File
@@ -554,6 +554,12 @@ def ExternalScript(url: str) -> SafeText:
return mark_safe(f'<script src="{url}"></script>')
def StaticScript(filename: str) -> SafeText:
"""A plain (classic, non-module) `<script src=...>` tag for a static JS
file — for vendored UMD bundles, which break inside module scope."""
return mark_safe(f'<script src="{static("js/" + filename)}"></script>')
def YearPicker(
year: int | None = None,
available_years: tuple[int, ...] = (),
+6 -3
View File
@@ -309,9 +309,12 @@ def Page(
f' <script src="{static("js/htmx-redirect-toast.js")}"></script>\n'
f" {django_htmx_script(nonce=None)}\n"
f' <link rel="stylesheet" href="{static("base.css")}" />\n'
' <script src="https://cdn.jsdelivr.net/npm/flowbite@2.4.1/dist/flowbite.min.js"></script>\n'
' <script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/mask@3.x.x/dist/cdn.min.js"></script>\n'
' <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>\n'
# Vendored bundles (flowbite 2.4.1, alpinejs/@alpinejs/mask 3.15.12) —
# served locally so pages work offline (and in browser tests). The mask
# plugin must load before Alpine core; both stay deferred.
f' <script src="{static("js/flowbite.min.js")}"></script>\n'
f' <script defer src="{static("js/alpine-mask.min.js")}"></script>\n'
f' <script defer src="{static("js/alpine.min.js")}"></script>\n'
f" {_THEME_FOUC_SCRIPT}\n"
" </head>\n"
)