Tab-radius gate: find Collapse's rule inside a selector list

The home link joined Collapse's rule (.vtl-collapse, .vtl-home { … }) so the
two share one box, and the gate only recognised a rule that named
.vtl-collapse alone, so it found no reference and failed on development. It
now reads the reference from any rule whose selector list names
.vtl-collapse as a whole selector (not :hover, -tx or a descendant), and its
self-test gains a poison that moves only that rule's radius.
This commit is contained in:
Doxa Maps 2026-09-30 21:17:42 +00:00
parent b138c876d5
commit bc3a5029a6

View file

@ -53,13 +53,21 @@ const fail = (m) => { console.error('TAB-RADIUS: FAIL — ' + m); process.exit(1
// catches 999px, 9999px and the occasional 50vh. // catches 999px, 9999px and the occasional 50vh.
const PILL_MIN = 100 const PILL_MIN = 100
// Does this line open a rule whose selector list names `cls` as a WHOLE selector? `.vtl-collapse, .vtl-home {`
// counts (the home link joined Collapse's rule so the two share one box); `.vtl-collapse:hover`,
// `.vtl-collapse-tx` and `.vtl.rail-collapsed .vtl-collapse` do not.
function opensRuleFor(ln, cls) {
const m = ln.match(/^\s*([^{}]+)\{/)
return !!m && m[1].split(',').map((x) => x.trim()).includes(cls)
}
function auditLines(lines) { function auditLines(lines) {
const problems = [] const problems = []
// ── the reference: .vtl-collapse's literal radius, read from the file, never assumed ────────── // ── the reference: .vtl-collapse's literal radius, read from the file, never assumed ──────────
const collapse = [] const collapse = []
lines.forEach((ln, i) => { lines.forEach((ln, i) => {
if (!/^\s*\.vtl-collapse\s*\{/.test(ln)) return if (!opensRuleFor(ln, '.vtl-collapse')) return
const m = ln.match(/border-radius:\s*([^;]+);/) const m = ln.match(/border-radius:\s*([^;]+);/)
if (m) collapse.push({ line: i + 1, value: m[1].trim() }) if (m) collapse.push({ line: i + 1, value: m[1].trim() })
}) })
@ -151,6 +159,9 @@ if (process.argv.includes('--self-test')) {
'cursor:pointer; border-radius:999px; font:inherit;')], 'cursor:pointer; border-radius:999px; font:inherit;')],
['literal-instead-of-token', (s) => s.replace('cursor:pointer; border-radius:var(--vtl-radius,8px); font:inherit;', ['literal-instead-of-token', (s) => s.replace('cursor:pointer; border-radius:var(--vtl-radius,8px); font:inherit;',
'cursor:pointer; border-radius:8px; font:inherit;')], 'cursor:pointer; border-radius:8px; font:inherit;')],
// the reference must be read from Collapse's rule even inside a selector list: change ONLY that rule's
// radius and the (unchanged) tabs no longer agree with it.
['collapse-radius-moved', (s) => s.split('\n').map((l) => (opensRuleFor(l, '.vtl-collapse') ? l.replace(/border-radius:\s*8px;/, 'border-radius:12px;') : l)).join('\n')],
] ]
let bad = 0 let bad = 0
for (const [name, poison] of cases) { for (const [name, poison] of cases) {
@ -161,7 +172,7 @@ if (process.argv.includes('--self-test')) {
if (!caught) bad++ if (!caught) bad++
} }
if (bad) { console.error(`TAB-RADIUS SELF-TEST: FAIL — ${bad} case(s) not caught.`); process.exit(1) } if (bad) { console.error(`TAB-RADIUS SELF-TEST: FAIL — ${bad} case(s) not caught.`); process.exit(1) }
console.log('TAB-RADIUS SELF-TEST: PASS — both regressions caught; tree untouched (poisoned in memory).') console.log('TAB-RADIUS SELF-TEST: PASS — every regression caught; tree untouched (poisoned in memory).')
process.exit(0) process.exit(0)
} }