Both panels ran 4/4 on 5ded5ff. They converged on the board and doc-page
gaps independently.
- A board holding files lost both blur controls (they sat inside the
board suppression meant for the one-click wipe), while its items'
"◉ booth" labels pointed at them. Only the wipe is board-suppressed now.
- A blurred doc's own full page rendered clear. Its body is blurred there
too, with its own reveal and a Reveal all to put the blur back.
- set_booth_blurred followed a planted .blurbooth symlink (`touch`), and
the new control made that a click away. Anything at the name already
reads as fogged; otherwise it is created O_CREAT|O_EXCL|O_NOFOLLOW.
- The fog landing echoed `back` unchecked into the 303. It is now built
from the review ring, as the mark routes do.
- The fog form is its own region, so an in-place save refreshes its
label. Reveal all stays outside every region: its state lives in the
tab.
- The review's Space-to-advance no longer swallows Space on a focused
button or link.
- Top-bar controls stay on one line at phone width.
- Tests tightened:
- method="post" on the fog forms;
- exact blur values;
- a storage READ that throws;
- an item's own reveal carried across a swap;
- reveal gated where it can act.
r2b.toml: 26/26 proved. 774 passed.
265 lines
10 KiB
TOML
265 lines
10 KiB
TOML
# R2b — the Desk row, Reveal all, the theme toggle: every falsifier the
|
|
# contract claims (docs/contracts/r2b_desk_reveal_theme.contract.md), and the
|
|
# change each forbids. Merge 1 is D2 + D2b (the blur half); merge 2 adds D1 + D3.
|
|
|
|
unit = "reveal all, the booth blur toggle (merge 1)"
|
|
|
|
[[mutation]]
|
|
label = "D2 reveal all does not lift the tile's blur"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_reveals_every_blurred_surface_and_survives_the_next_page"
|
|
old = '''
|
|
.reveal-all .item.blurred img,.reveal-all .item.blurred video,'''
|
|
new = '''
|
|
.reveal-all-OFF .item.blurred img,.reveal-all .item.blurred video,'''
|
|
|
|
[[mutation]]
|
|
label = "D2 no pre-paint re-application: the next page of the reel is blurred again"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_reveals_every_blurred_surface_and_survives_the_next_page"
|
|
old = '''
|
|
if (b !== null && sessionStorage.getItem('booth.reveal:' + b) === '1') d.classList.add('reveal-all');'''
|
|
new = '''
|
|
if (false) d.classList.add('reveal-all');'''
|
|
|
|
[[mutation]]
|
|
label = "D2 the reveal is not scoped to the booth (any reveal in the tab reveals every booth)"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_on_booth_a_does_not_reveal_booth_b_or_the_desk"
|
|
old = '''
|
|
if (b !== null && sessionStorage.getItem('booth.reveal:' + b) === '1') d.classList.add('reveal-all');'''
|
|
new = '''
|
|
if (b !== null && sessionStorage.length > 0) d.classList.add('reveal-all');'''
|
|
|
|
[[mutation]]
|
|
label = "D2 per-tile reveal buttons do not stand down under reveal all"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_survives_an_in_place_save"
|
|
old = '''
|
|
.reveal-all .item.blurred .reveal,.reveal-all #vreveal{display:none}'''
|
|
new = '''
|
|
.reveal-all-OFF .item.blurred .reveal,.reveal-all #vreveal{display:none}'''
|
|
|
|
[[mutation]]
|
|
label = "D2 blur again wipes each item's own reveal"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_blur_again_restores_each_items_own_reveal"
|
|
old = '''
|
|
var on = d.classList.toggle('reveal-all');
|
|
try {'''
|
|
new = '''
|
|
var on = d.classList.toggle('reveal-all');
|
|
document.querySelectorAll('.item.revealed').forEach(function (i) { i.classList.remove('revealed'); });
|
|
try {'''
|
|
|
|
[[mutation]]
|
|
label = "D2 a storage write that throws swallows the click"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_never_shows_without_js_and_a_storage_failure_still_applies_the_click"
|
|
old = '''
|
|
var on = d.classList.toggle('reveal-all');
|
|
try {'''
|
|
new = '''
|
|
sessionStorage.setItem(key, '1');
|
|
var on = d.classList.toggle('reveal-all');
|
|
try {'''
|
|
|
|
[[mutation]]
|
|
label = "D2 the control shows without JS (server markup not hidden)"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_never_shows_without_js_and_a_storage_failure_still_applies_the_click"
|
|
old = '''
|
|
{% if all_items | selectattr('blurred') | list %}<button type="button" class="reveal-all-btn" data-reveal-all hidden title='''
|
|
new = '''
|
|
{% if all_items | selectattr('blurred') | list %}<button type="button" class="reveal-all-btn" data-reveal-all title='''
|
|
|
|
[[mutation]]
|
|
label = "D2 the control is markup even when nothing is blurred"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow.py::test_reveal_all_is_in_the_markup_only_when_something_is_blurred_and_always_hidden"
|
|
old = '''
|
|
{% if all_items | selectattr('blurred') | list %}<button'''
|
|
new = '''
|
|
{% if true %}<button'''
|
|
|
|
[[mutation]]
|
|
label = "D2 the review page does not carry data-booth"
|
|
file = "booth/templates/view.html"
|
|
test = "tests/test_flow.py::test_reveal_all_is_in_the_markup_only_when_something_is_blurred_and_always_hidden"
|
|
old = '''
|
|
{% block html_attrs %} data-booth="{{ name }}"{% endblock %}'''
|
|
new = '''
|
|
{% block html_attrs %}{% endblock %}'''
|
|
|
|
[[mutation]]
|
|
label = "D2b the header control's label does not follow the server's fog state"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow.py::test_the_booth_blur_toggle_works_without_js_and_lands_back_on_the_review"
|
|
old = '''
|
|
<input type="hidden" name="on" value="{{ '0' if booth_blurred else '1' }}">
|
|
<button title="{{ 'un-blur the whole booth'''
|
|
new = '''
|
|
<input type="hidden" name="on" value="1">
|
|
<button title="{{ 'un-blur the whole booth'''
|
|
|
|
[[mutation]]
|
|
label = "D2b the review's control drops `back` (fogging ejects you from the review)"
|
|
file = "booth/templates/view.html"
|
|
test = "tests/test_flow.py::test_the_booth_blur_toggle_works_without_js_and_lands_back_on_the_review"
|
|
old = '''
|
|
<input type="hidden" name="back" value="{{ file }}">'''
|
|
new = '''
|
|
'''
|
|
|
|
[[mutation]]
|
|
label = "D2b the Desk row does not say a booth is fogged"
|
|
file = "booth/templates/index.html"
|
|
test = "tests/test_flow.py::test_the_booth_blur_toggle_works_without_js_and_lands_back_on_the_review"
|
|
old = '''
|
|
{% if b.booth_blurred %}<span class="badge badge-blur"'''
|
|
new = '''
|
|
{% if false %}<span class="badge badge-blur"'''
|
|
|
|
[[mutation]]
|
|
label = "D2b an item blurred only by the booth offers a per-item un-blur that does nothing"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow.py::test_under_a_fogged_booth_each_items_blur_control_tells_the_truth"
|
|
old = '''
|
|
{% if it.blurred and not it.blurred_self %}'''
|
|
new = '''
|
|
{% if false %}'''
|
|
|
|
[[mutation]]
|
|
label = "D2b the per-item control reads the composed blur, not the item's own"
|
|
file = "booth/app.py"
|
|
test = "tests/test_flow.py::test_under_a_fogged_booth_each_items_blur_control_tells_the_truth"
|
|
old = '''
|
|
"blurred_self": it.rel in own_blur,'''
|
|
new = '''
|
|
"blurred_self": it.blurred,'''
|
|
|
|
# ---- folds: the heid code-review ("BLITZ-2") and bug-hunt ("FENRIR-6") panels on merge 1
|
|
|
|
[[mutation]]
|
|
label = "a board holding files loses the blur controls its labels point at"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow.py::test_a_board_with_files_gets_the_blur_controls_its_labels_point_at"
|
|
old = '''
|
|
{% if all_items %}
|
|
{# The fog form IS a region'''
|
|
new = '''
|
|
{% if not board %}
|
|
{# The fog form IS a region'''
|
|
|
|
[[mutation]]
|
|
label = "a blurred doc's own page renders clear"
|
|
file = "booth/templates/doc.html"
|
|
test = "tests/test_flow.py::test_a_blurred_docs_own_page_is_blurred_too"
|
|
old = '''
|
|
<div class="docbody{% if blurred %} is-blurred{% endif %}" id="docbody">'''
|
|
new = '''
|
|
<div class="docbody" id="docbody">'''
|
|
|
|
[[mutation]]
|
|
label = "the review offers Reveal all when only a doc (off the ring) is blurred"
|
|
file = "booth/templates/view.html"
|
|
test = "tests/test_flow.py::test_reveal_all_renders_where_it_can_act"
|
|
old = '''
|
|
{% if film | selectattr('blurred') | list %}<button'''
|
|
new = '''
|
|
{% if true %}<button'''
|
|
|
|
[[mutation]]
|
|
label = "the fog form is a GET (changes nothing with scripts off)"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow.py::test_the_booth_blur_toggle_works_without_js_and_lands_back_on_the_review"
|
|
old = '''<form class="blur-all{% if booth_blurred %} is-on{% endif %}" method="post" action="/b/{{ name_url }}/blurbooth">
|
|
<input type="hidden" name="on" value="{{ '0' if booth_blurred else '1' }}">
|
|
<button title="{{ 'un-blur the whole booth — per-item'''
|
|
new = '''<form class="blur-all{% if booth_blurred %} is-on{% endif %}" method="get" action="/b/{{ name_url }}/blurbooth">
|
|
<input type="hidden" name="on" value="{{ '0' if booth_blurred else '1' }}">
|
|
<button title="{{ 'un-blur the whole booth — per-item'''
|
|
|
|
[[mutation]]
|
|
label = "the swap stops carrying an item's own reveal"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_an_items_own_reveal_survives_an_in_place_save"
|
|
old = '''
|
|
['revealed', 'is-closed'].forEach(function (c) {'''
|
|
new = '''
|
|
['is-closed'].forEach(function (c) {'''
|
|
|
|
[[mutation]]
|
|
label = "a storage READ that throws raises out of the pre-paint script"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_never_shows_without_js_and_a_storage_failure_still_applies_the_click"
|
|
old = '''
|
|
try {
|
|
if (b !== null && sessionStorage.getItem('booth.reveal:' + b) === '1') d.classList.add('reveal-all');
|
|
} catch (e) {}'''
|
|
new = '''
|
|
if (b !== null && sessionStorage.getItem('booth.reveal:' + b) === '1') d.classList.add('reveal-all');'''
|
|
|
|
[[mutation]]
|
|
label = "fogging writes through a planted marker link"
|
|
file = "booth/app.py"
|
|
test = "tests/test_flow.py::test_fogging_never_writes_through_a_planted_marker_link"
|
|
old = '''
|
|
try:
|
|
os.lstat(marker)
|
|
return True
|
|
except FileNotFoundError:
|
|
pass
|
|
try:
|
|
os.close(os.open(marker, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o644))
|
|
except FileExistsError:
|
|
pass # lost a race to another fog: still fogged
|
|
return True'''
|
|
new = '''
|
|
marker.touch(exist_ok=True)
|
|
return True'''
|
|
|
|
[[mutation]]
|
|
label = "the fog landing echoes `back` unchecked"
|
|
file = "booth/app.py"
|
|
test = "tests/test_flow.py::test_the_fog_landing_is_built_from_the_ring_never_echoed"
|
|
old = '''
|
|
if back and back in review_chain(booth_items(booth)):'''
|
|
new = '''
|
|
if back:'''
|
|
|
|
[[mutation]]
|
|
label = "the fog form is outside every region (a swap leaves its label stale)"
|
|
file = "booth/templates/booth.html"
|
|
test = "tests/test_flow.py::test_the_booth_blur_toggle_works_without_js_and_lands_back_on_the_review"
|
|
old = '''
|
|
<span class="region-wrap" data-region="blur-booth"><form class="blur-all'''
|
|
new = '''
|
|
<span class="region-wrap"><form class="blur-all'''
|
|
|
|
[[mutation]]
|
|
label = "Space on a focused review button moves to the next item"
|
|
file = "booth/templates/view.html"
|
|
test = "tests/test_flow_browser.py::test_space_on_a_focused_review_button_presses_it_and_does_not_move_on"
|
|
old = '''e.target !== player && !(e.target.closest && e.target.closest('button, a, summary'))) {'''
|
|
new = '''e.target !== player) {'''
|
|
|
|
[[mutation]]
|
|
label = "the top-bar controls squeeze into multi-line stacks at phone width"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_the_review_and_doc_top_bars_fit_a_phone"
|
|
old = '''
|
|
.blur-all button,.reveal-all-btn{white-space:nowrap}
|
|
@media (max-width:600px){.reveal-all-btn .ra-note{display:none}}'''
|
|
new = '''
|
|
'''
|
|
|
|
[[mutation]]
|
|
label = "the Desk strip under another booth's reveal is lifted by a whisker (blur(0px) is not blurred)"
|
|
file = "booth/templates/base.html"
|
|
test = "tests/test_flow_browser.py::test_reveal_all_on_booth_a_does_not_reveal_booth_b_or_the_desk"
|
|
old = '''
|
|
.blurred-thumb{filter:blur(16px)}'''
|
|
new = '''
|
|
.blurred-thumb{filter:blur(0px)}'''
|