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('