Version HTML5 asset URLs
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-17 11:48:43 +03:00
parent 0a16058ebd
commit d3ae2459ce
3 changed files with 25 additions and 13 deletions
+15 -3
View File
@@ -1,8 +1,11 @@
from __future__ import annotations
from html import escape
from pathlib import Path
from urllib.parse import quote
_HTML5_ASSETS_DIR = Path(__file__).resolve().parent / "static" / "html5"
def _page(title: str, body: str) -> str:
return f"""<!doctype html>
@@ -11,14 +14,23 @@ def _page(title: str, body: str) -> str:
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{escape(title)}</title>
<link rel="stylesheet" href="/html5/assets/html5.css" />
<script defer src="/html5/assets/htmx.min.js"></script>
<script defer src="/html5/assets/htmx-ext-sse.js"></script>
<link rel="stylesheet" href="{_asset_url("html5.css")}" />
<script defer src="{_asset_url("htmx.min.js")}"></script>
<script defer src="{_asset_url("htmx-ext-sse.js")}"></script>
</head>
<body>{body}</body>
</html>"""
def _asset_url(filename: str) -> str:
asset_path = _HTML5_ASSETS_DIR / filename
try:
version = str(int(asset_path.stat().st_mtime))
except OSError:
version = "dev"
return f"/html5/assets/{quote(filename)}?v={version}"
def _project_link(project: object, active_project_id: str) -> str:
project_id = str(getattr(project, "project_id", ""))
name = str(getattr(project, "name", project_id))
+1 -1
View File
@@ -140,7 +140,7 @@ _HTML5_ASSETS_DIR = Path(__file__).resolve().parent / "static" / "html5"
class Html5StaticFiles(StaticFiles):
def file_response(self, *args, **kwargs):
response = super().file_response(*args, **kwargs)
response.headers.setdefault("Cache-Control", "public, max-age=3600")
response.headers.setdefault("Cache-Control", "public, max-age=86400")
return response
+9 -9
View File
@@ -35,9 +35,9 @@ def assert_html5_contract(text: str, *markers: str, full_page: bool = False) ->
if full_page:
assert "<!doctype html>" in text
assert "<style>" not in text
assert "/html5/assets/html5.css" in text
assert "/html5/assets/htmx.min.js" in text
assert "/html5/assets/htmx-ext-sse.js" in text
assert re.search(r'/html5/assets/html5\.css\?v=[^"]+', text)
assert re.search(r'/html5/assets/htmx\.min\.js\?v=[^"]+', text)
assert re.search(r'/html5/assets/htmx-ext-sse\.js\?v=[^"]+', text)
else:
assert "<html" not in text
for marker in markers:
@@ -152,9 +152,9 @@ def test_html5_server_rendered_project_editor(tmp_path: Path):
assert 'hx-swap="outerHTML"' in editor.text
assert "hx-ext=\"sse\"" in editor.text
assert f"sse-connect=\"/html5/projects/{project_id}/events\"" in editor.text
assert '/html5/assets/html5.css' in editor.text
assert '/html5/assets/htmx.min.js' in editor.text
assert '/html5/assets/htmx-ext-sse.js' in editor.text
assert re.search(r'/html5/assets/html5\.css\?v=[^"]+', editor.text)
assert re.search(r'/html5/assets/htmx\.min\.js\?v=[^"]+', editor.text)
assert re.search(r'/html5/assets/htmx-ext-sse\.js\?v=[^"]+', editor.text)
assert "unpkg.com" not in editor.text
assert "client-js: htmx+sse only" in editor.text
css = client.get("/html5/assets/html5.css")
@@ -257,17 +257,17 @@ def test_html5_server_rendered_project_editor(tmp_path: Path):
htmx_asset = client.get("/html5/assets/htmx.min.js")
assert htmx_asset.status_code == 200
assert "javascript" in htmx_asset.headers["content-type"]
assert htmx_asset.headers["cache-control"] == "public, max-age=3600"
assert htmx_asset.headers["cache-control"] == "public, max-age=86400"
assert "htmx" in htmx_asset.text
sse_asset = client.get("/html5/assets/htmx-ext-sse.js")
assert sse_asset.status_code == 200
assert "javascript" in sse_asset.headers["content-type"]
assert sse_asset.headers["cache-control"] == "public, max-age=3600"
assert sse_asset.headers["cache-control"] == "public, max-age=86400"
assert "sse" in sse_asset.text
css_asset = client.get("/html5/assets/html5.css")
assert css_asset.status_code == 200
assert "text/css" in css_asset.headers["content-type"]
assert css_asset.headers["cache-control"] == "public, max-age=3600"
assert css_asset.headers["cache-control"] == "public, max-age=86400"
assert ".workspace" in css_asset.text