File size: 1,887 Bytes
795f737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
(el, suppliedPath) => {
  const norm = s => (s || '').replace(/\s+/g, ' ').trim().slice(0, 512);
  const tag = el.tagName.toLowerCase();
  const type = (el.getAttribute('type') || 'text').toLowerCase();
  const auto = (el.getAttribute('autocomplete') || '').toLowerCase();
  const sensitive = type === 'password' || /password|cc-|one-time-code/.test(auto);
  const roles = {button:'button', a:'link', textarea:'textbox', select:'combobox',
    summary:'button', h1:'heading', h2:'heading', h3:'heading', p:'text', output:'status'};
  const inputRoles = {checkbox:'checkbox', radio:'radio', button:'button', submit:'button', range:'slider'};
  const role = el.getAttribute('role') || (tag === 'input' ? (inputRoles[type] || 'textbox') : roles[tag]) || 'generic';
  const root = el.getRootNode();
  const labelled = (el.getAttribute('aria-labelledby') || '').split(/\s+/)
    .map(id => root.getElementById?.(id)?.textContent || '').join(' ').trim();
  const label = [...(el.labels || [])].map(x => x.textContent).join(' ');
  const name = sensitive ? '[REDACTED]' : norm(labelled || el.getAttribute('aria-label') || label ||
    (['input','textarea','select'].includes(tag) ? (el.getAttribute('placeholder') || el.getAttribute('title')) : el.textContent));
  const rect = el.getBoundingClientRect();
  const css = getComputedStyle(el);
  const visible = !!(el.isConnected && rect.width && rect.height && css.visibility !== 'hidden' && css.display !== 'none');
  const enabled = !el.matches(':disabled') && el.getAttribute('aria-disabled') !== 'true' && !el.closest('[inert]');
  let path = [], node = el;
  while (suppliedPath == null && node?.nodeType === 1) {
    const parent = node.parentNode;
    path.push([...parent.children].indexOf(node));
    node = parent.host || parent;
  }
  return {role, name, path:suppliedPath ?? path.reverse().join('/'), visible, enabled, sensitive};
}