Recognize aria-hidden="true" as decorative, add class-name id fallback
Elements with aria-hidden="true" are already fully removed from the accessibility tree, equivalent in intent to alt="" - they were wrongly flagged as errors instead of the same decorative warning alt="" gets. On role="img" elements with no wrapping link, aria-label, or (now) aria-hidden exemption, imageIdentifier() also had no way to build an exclusion key at all, so the exclude click silently did nothing. Added a className-based fallback identifier as a last resort so these elements can still be excluded individually. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
f9cfa1c91e
commit
9b76767838
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -71,12 +71,16 @@
|
||||||
// src ist die stabilste Kennung eines Bildes über mehrere Seitenaufrufe hinweg
|
// src ist die stabilste Kennung eines Bildes über mehrere Seitenaufrufe hinweg
|
||||||
if (img.tagName === 'IMG') return img.currentSrc || img.src || null;
|
if (img.tagName === 'IMG') return img.currentSrc || img.src || null;
|
||||||
|
|
||||||
// Nicht-<img>-Elemente mit role="img" (z.B. Inline-<svg>) haben kein src.
|
// Nicht-<img>-Elemente mit role="img" (z.B. Inline-<svg> oder <div role="img">)
|
||||||
// Fallback: umgebender Link oder aria-label als Kennung.
|
// haben kein src. Fallback: umgebender Link, aria-label, oder als letzte
|
||||||
|
// Möglichkeit die class (z.B. bei reinen Icon-Fonts/CSS-Icons ohne jeden
|
||||||
|
// Text). Der instanceIdentifier()-Zähler unterscheidet danach weiterhin
|
||||||
|
// gleich aussehende Duplikate voneinander.
|
||||||
const link = img.closest ? img.closest('a[href]') : null;
|
const link = img.closest ? img.closest('a[href]') : null;
|
||||||
if (link && link.href) return `role-img:${link.href}`;
|
if (link && link.href) return `role-img:${link.href}`;
|
||||||
const label = img.getAttribute('aria-label');
|
const label = img.getAttribute('aria-label');
|
||||||
if (label) return `role-img:${label}`;
|
if (label) return `role-img:${label}`;
|
||||||
|
if (img.className) return `role-img:class:${img.className}`;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,6 +363,7 @@
|
||||||
const labelledBy = resolveIdRefs('aria-labelledby', img);
|
const labelledBy = resolveIdRefs('aria-labelledby', img);
|
||||||
const hasTitle = img.hasAttribute('title');
|
const hasTitle = img.hasAttribute('title');
|
||||||
const hasLongdesc = img.hasAttribute('longdesc');
|
const hasLongdesc = img.hasAttribute('longdesc');
|
||||||
|
const isAriaHidden = img.getAttribute('aria-hidden') === 'true';
|
||||||
const hasAccessibleName = hasAriaLabel || describedBy !== null || labelledBy !== null;
|
const hasAccessibleName = hasAriaLabel || describedBy !== null || labelledBy !== null;
|
||||||
const linkPrefix = isInsideLink(img) ? 'Bild in Link: ' : '';
|
const linkPrefix = isInsideLink(img) ? 'Bild in Link: ' : '';
|
||||||
|
|
||||||
|
|
@ -373,6 +378,14 @@
|
||||||
const isDecorative = altValue.trim().length === 0;
|
const isDecorative = altValue.trim().length === 0;
|
||||||
segments = [linkPrefix, { code: `alt="${altValue}"` }, ...extras];
|
segments = [linkPrefix, { code: `alt="${altValue}"` }, ...extras];
|
||||||
kind = isDecorative ? 'warning' : 'success';
|
kind = isDecorative ? 'warning' : 'success';
|
||||||
|
} else if (isAriaHidden && !hasAccessibleName) {
|
||||||
|
// aria-hidden="true" entfernt das Element bereits vollständig aus dem
|
||||||
|
// Accessibility-Tree – für Screenreader ist es so, als gäbe es kein
|
||||||
|
// Bild. Das ist eine gültige Alternative zu alt="" bei dekorativen
|
||||||
|
// Elementen (v.a. bei role="img" auf Nicht-<img>-Elementen), daher
|
||||||
|
// hier keine Fehlermeldung, sondern dieselbe Einstufung wie alt="".
|
||||||
|
segments = [linkPrefix, { code: 'aria-hidden="true"' }, ...extras];
|
||||||
|
kind = 'warning';
|
||||||
} else if (hasAccessibleName) {
|
} else if (hasAccessibleName) {
|
||||||
const resolvedName = hasAriaLabel ? img.getAttribute('aria-label') : (labelledBy || describedBy);
|
const resolvedName = hasAriaLabel ? img.getAttribute('aria-label') : (labelledBy || describedBy);
|
||||||
segments = [
|
segments = [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue