From c916503958453ca52c9a06a76656abf76c7a0a18 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 10 Nov 2026 14:12:00 +0100 Subject: [PATCH] fix: hide filter boxes and picker until wired A filter box read "Filter Options41 rows" in the page text and the file picker an empty "Setup Choose a setup": both do nothing without the script. They are written hidden, keep their room so nothing moves, and site.ts or the picker's script shows them. The count describes the input and is spaced from the label. One box markup for the build and the generator, and the Markdown copy skips hidden chrome. --- scripts/generate_site.py | 10 ++-------- scripts/site_markdown.py | 5 ++++- scripts/siteentries.py | 17 ++++++++++++---- tests/test_site_components.py | 2 +- tests/test_site_entry_tables.py | 7 ++++--- tests/test_site_platform_density.py | 3 ++- website/src/components/FilePicker.astro | 11 ++++++++--- website/src/plugins/rehype-stack-tables.mjs | 22 +++++++++++++++++---- website/src/scripts/site.ts | 9 +++++++++ website/src/styles/retrobios.css | 4 ++++ 10 files changed, 65 insertions(+), 25 deletions(-) diff --git a/scripts/generate_site.py b/scripts/generate_site.py index e1428de88..d6bf5b780 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -3818,14 +3818,8 @@ def _platform_file_list(rows: list[str], has_path: bool, anchor: str) -> list[st """ lines: list[str] = [] if len(rows) >= FILTER_ROWS: - field = f"rb-files-filter-{anchor}" - lines += [ - '
' - f'' - f'' - f'{len(rows):,} rows
', - "", - ] + lines += [siteentries.filter_box(f"rb-files-filter-{anchor}", "files", + ["File", "path", "status", "hash"], len(rows)), ""] kind = "rb-files rb-files-path" if has_path else "rb-files" return [*lines, f'
', *rows, "
"] diff --git a/scripts/site_markdown.py b/scripts/site_markdown.py index 4f99d03cd..6ce944994 100644 --- a/scripts/site_markdown.py +++ b/scripts/site_markdown.py @@ -123,7 +123,10 @@ class _Converter(HTMLParser): self._emit(f"**{' '.join(name.split())}:**") self._block() return - if self.skip or tag in SKIPPED or attr.get("aria-hidden") == "true" \ + # A `hidden` element is chrome the page's script shows (a filter + # box, the file picker, a setup's install chooser): a tab panel, + # hidden too, was read above. + if self.skip or tag in SKIPPED or attr.get("aria-hidden") == "true" or "hidden" in attr \ or classes & {"sr-only", "sl-anchor-link", "copy", "rb-anchor"}: if tag not in ("br", "img", "hr", "input", "wbr"): self.skip += 1 diff --git a/scripts/siteentries.py b/scripts/siteentries.py index 7fc5dc31c..c417c74bb 100644 --- a/scripts/siteentries.py +++ b/scripts/siteentries.py @@ -47,12 +47,21 @@ def filter_placeholder(labels: list[str]) -> str: def filter_box(ident: str, heading: str, labels: list[str], rows: int, noun: str = "rows") -> str: - """The filter box rehype-stack-tables.mjs writes above a long table.""" + """The filter box rehype-stack-tables.mjs writes above a long table. + + It is `hidden` until site.ts wires it: without the script it filters + nothing, so a reader with no JavaScript, a text dump and the search + skip it while the rows stay. retrobios.css keeps its room meanwhile, + so the table does not move when it shows. The count is the input's + description, and spaces keep label, field and count apart in any text + read from the HTML.""" return ( - f'
' + f'' + f'placeholder="{html.escape(filter_placeholder(labels))}" aria-describedby="{ident}-count"> ' + f'' + f"{rows:,} {noun}
" ) diff --git a/tests/test_site_components.py b/tests/test_site_components.py index a6f64c7bb..7385e7ff5 100644 --- a/tests/test_site_components.py +++ b/tests/test_site_components.py @@ -409,7 +409,7 @@ class WideTablesStackAndFiltersAreBuilt(unittest.TestCase): def test_the_filter_box_is_in_the_html(self): html = _built("gaps-files-to-source") - boxes = re.findall(r'
(.*?)
\s*]*>(.*?)\s*Filter [^<]+') diff --git a/tests/test_site_entry_tables.py b/tests/test_site_entry_tables.py index ae4e01d0b..807aefd03 100644 --- a/tests/test_site_entry_tables.py +++ b/tests/test_site_entry_tables.py @@ -49,8 +49,9 @@ class TheEntryTable(unittest.TestCase): def test_a_long_table_has_its_filter_box_and_stacks(self): lines = siteentries.entry_table(self._rows(25), gs.ENTRY_HEADS, "rb-entry-filter-x", "Required") text = "\n".join(lines) - self.assertRegex(text, r'
' + r' ' + r"25 rows
\n', text) # The Status column is empty on every row: not written. @@ -210,7 +211,7 @@ class TheWantedListIsOneFilteredTable(unittest.TestCase): self.assertIn("| Nintendo - GameCube - BIOS Images | 16 |", self.page) def test_every_dump_is_one_row_under_a_filter_box(self): - box = re.search(r'
.*?
\n]*>\n' + box = re.search(r'
]*>.*?
\n]*>\n' r"All 31 wanted dumps\n
"] * generate_site.FILTER_ROWS block = generate_site._platform_file_list(rows, False, "arcade") - self.assertTrue(block[0].startswith('