diff --git a/src/flask/app_factory.py b/src/flask/app_factory.py index 348dbd6..5e40a69 100644 --- a/src/flask/app_factory.py +++ b/src/flask/app_factory.py @@ -97,6 +97,19 @@ def create_app(config: dict | None = None) -> Flask: if response.mimetype == "text/html": response.headers["Cache-Control"] = "no-store, must-revalidate" response.headers["Pragma"] = "no-cache" + elif response.mimetype in ("text/css", "application/javascript", + "text/javascript"): + # The static files must NEVER be reused from a cache. + + # Firefox kept serving a stale stylesheet even with + # `no-cache`, which meant the page had the new markup and + # the old CSS: the advice was expanded inline in the table + # instead of in a pop-out, and the long and short labels + # were both showing ("BREWING ADVICEADVICE"). + + # `no-store` is the only one that means "do not keep this". + response.headers["Cache-Control"] = "no-store, must-revalidate" + response.headers["Pragma"] = "no-cache" return response csrf = CSRFProtect(app) diff --git a/src/flask/static/css/app.css b/src/flask/static/css/app.css index 11dd675..9f5c882 100644 --- a/src/flask/static/css/app.css +++ b/src/flask/static/css/app.css @@ -999,10 +999,21 @@ table.data .comment { color: var(--text-muted); font-size: .84rem; } /* The script opens and closes the panel, and places it. The CSS only decides whether it is shown. */ +/* The panel is opened by the script, which removes the `hidden` + attribute and adds `is-open`. + + The `hidden` attribute is what makes this fail-safe: if the + stylesheet is stale and does not know about `.advice-pop` at all, + the panel is STILL hidden, so the advice cannot appear expanded + inside the table cell. */ .advice-pop.is-open { display: block; } +.advice-pop[hidden] { + display: none; +} + /* On a phone there is no hover, so the trigger is a button the script toggles, and the panel is pinned to the middle of the screen so it is readable whatever the table's width. */ diff --git a/src/flask/static/js/app.js b/src/flask/static/js/app.js index a8b0400..6c6b6d4 100644 --- a/src/flask/static/js/app.js +++ b/src/flask/static/js/app.js @@ -131,6 +131,11 @@ clearTimeout(closeTimer); closeTimer = null; } + /* The `hidden` attribute is removed as well as the + class added, so the panel is shown even if the + stylesheet is an older one that only knows about + the class. */ + panel.removeAttribute("hidden"); panel.classList.add("is-open"); trigger.setAttribute("aria-expanded", "true"); place(); @@ -138,6 +143,9 @@ function close() { panel.classList.remove("is-open"); + /* Put the attribute back, so a stale stylesheet + cannot leave the advice expanded in the cell. */ + panel.setAttribute("hidden", ""); trigger.setAttribute("aria-expanded", "false"); } diff --git a/src/flask/templates/brews.html b/src/flask/templates/brews.html index 7640b8a..b165c9a 100644 --- a/src/flask/templates/brews.html +++ b/src/flask/templates/brews.html @@ -126,7 +126,7 @@ {% endif %} -