Files
SoulStream/handoff/rounds/ins-r28-probe.txt
T
KeelrLeek 9f0601027c android: the handoff — the pending rounds, the pipeline, and what is unverified
Everything written this session that has not been through the device: rounds 43
to 48 (each patch adversarially verified, 43's transient-notice expectation
fixed), a partial round 49, the pipeline scripts, the Android Auto design and
the icon comparison mock. Also the two harness changes that were never A/B'd —
adaptive waits, which may only shorten a declared wait and never lengthen it,
and a ship that runs the mock walk and the deploy at the same time. The A/B and
its 255-step baseline are in handoff/tools; main stays at what the phone has
actually walked.
2026-09-14 07:57:41 -05:00

55 lines
3.0 KiB
Plaintext

/* ── what a screen reader would be handed ────────────────────────────
'exposed' is the tree TalkBack actually walks: nothing under
aria-hidden or inert, nothing display:none or zero-boxed. 'aname' is
the name it would announce — aria-label, aria-labelledby, then the
visible text with the aria-hidden subtrees left out (an Icon is
aria-hidden, so an icon-only control computes to nothing at all). A
PLACEHOLDER is deliberately not a name here: it goes away the moment
the field has text in it. Every backslash in this block is doubled —
it lives inside a template literal. */
var A11Y_SEL = 'button, [role=button], a, input, select, textarea, [role=tab], [role=switch], [role=slider], [role=checkbox]';
function exposed(el) {
if (el.closest('[aria-hidden="true"], [inert]')) return false;
if (!el.getClientRects().length) return false;
var st = getComputedStyle(el);
return st.visibility !== 'hidden' && st.display !== 'none';
}
function vistext(el) {
var out = '';
for (var i = 0; i < el.childNodes.length; i++) {
var n = el.childNodes[i];
if (n.nodeType === 3) { out += n.nodeValue; continue; }
if (n.nodeType !== 1) continue;
if (n.getAttribute('aria-hidden') === 'true') continue;
if (n.tagName === 'IMG') { out += ' ' + (n.getAttribute('alt') || ''); continue; }
out += ' ' + vistext(n);
}
return out;
}
function aname(el) {
var l = el.getAttribute('aria-label');
if (l && l.trim()) return l.trim();
var by = el.getAttribute('aria-labelledby');
if (by) {
var s = '';
by.split(' ').forEach(function (id) { var n = document.getElementById(id); if (n) s += ' ' + vistext(n); });
if (s.trim()) return s.replace(/\\s+/g, ' ').trim();
}
var t = el.tagName;
if (t === 'INPUT' || t === 'TEXTAREA' || t === 'SELECT') {
if (el.id) { var lab = document.querySelector('label[for="' + el.id + '"]'); if (lab && lab.textContent.trim()) return lab.textContent.replace(/\\s+/g, ' ').trim(); }
return (el.getAttribute('title') || '').trim();
}
return vistext(el).replace(/\\s+/g, ' ').trim() || (el.getAttribute('title') || '').trim();
}
function whatis(el) { return (el.tagName.toLowerCase() + '.' + String(el.className || '').split(' ').slice(0, 2).join('.')).slice(0, 36); }
function junk(el, nm) {
if (/^[0-9 .,:;+·—–-]+$/.test(nm)) return 'digits';
if (/\\.(png|jpe?g|webp|gif|svg|mp3|flac|m4a|ogg|wav)$/i.test(nm)) return 'file';
if (/^[⋯…×✕✓→←]$/.test(nm)) return 'glyph';
if (nm.length > 200 && !el.hasAttribute('aria-expanded')) return 'essay';
return '';
}
var a11yAll = [].filter.call(document.querySelectorAll(A11Y_SEL), exposed);
var a11yNone = a11yAll.filter(function (el) { return !aname(el); });