Compare commits
2
Commits
cd45cc2f17
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e4770f870 | ||
|
|
fb1088ceec |
@@ -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)
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
{% endif %}
|
||||
</span>
|
||||
</button>
|
||||
<div class="advice-pop" role="tooltip">
|
||||
<div class="advice-pop" role="tooltip" hidden>
|
||||
<div class="advice-pop__head">
|
||||
<span class="advice__label">Brewing advice</span>
|
||||
<button type="button" class="advice-pop__close"
|
||||
|
||||
@@ -1162,6 +1162,29 @@ def test_stale_advice_cannot_overwrite_a_comment_edited_outside_the_app(repo):
|
||||
assert doc["comment"] == "edited outside the app"
|
||||
|
||||
|
||||
def test_the_advice_pop_out_is_hidden_in_the_markup(client, repo):
|
||||
"""The pop-out carries the `hidden` attribute.
|
||||
|
||||
A stale stylesheet - one that does not know about `.advice-pop` at
|
||||
all - would otherwise leave the advice expanded inline in the table
|
||||
cell, running down the column and off the screen. The `hidden`
|
||||
attribute makes the markup fail-safe: the panel stays hidden until
|
||||
the script opens it.
|
||||
"""
|
||||
repo.users.insert_one({"username": "beer", "password": "beer_pass"})
|
||||
client.post("/login", data={"username": "beer", "password": "beer_pass"},
|
||||
follow_redirects=True)
|
||||
|
||||
seed_readings(repo, [("1", "Ale", "1042", "2026-01-01", False, "")])
|
||||
doc = repo.readings.find_one({"beer_run_id": "1"})
|
||||
repo.set_reading_advice(str(doc["_id"]), "Warm it to 21C and wait.", ok=True)
|
||||
|
||||
body = client.get("/brews").get_data(as_text=True)
|
||||
|
||||
assert 'class="advice-pop"' in body
|
||||
assert 'hidden' in body.split('class="advice-pop"')[1][:60]
|
||||
|
||||
|
||||
def test_a_failed_advice_is_marked_as_such(client, repo):
|
||||
"""A generation failure reads differently from real advice."""
|
||||
repo.users.insert_one({"username": "beer", "password": "beer_pass"})
|
||||
|
||||
Reference in New Issue
Block a user