From de5cc38cee0daa1057f2d0e6b649a0dc45bb3831 Mon Sep 17 00:00:00 2001 From: Sascha Date: Tue, 14 Jul 2026 10:37:45 +0200 Subject: [PATCH] Give aria-hidden its own non-excludable "info" status; make OK non-excludable too aria-hidden="true" was sharing the "warning" bucket with real problems (empty alt, ARIA-name-without-alt) even though it needs no action - the element is already fully removed from the accessibility tree. It now gets its own "info"/"Hinweis" kind with a dedicated badge, icon, and summary count. Exclusion only makes sense for things you'd want to mark as "reviewed, intentionally left as-is": errors and real warnings. "success" and the new "info" kind no longer get a click handler at all, since there is nothing to exclude - clicking them is now a no-op. Co-Authored-By: Claude Sonnet 5 --- dist/alt-text-checker.min.js | 2 +- dist/bookmarklet.txt | 2 +- src/alt-text-checker.js | 33 +++++++++++++++++++++------------ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dist/alt-text-checker.min.js b/dist/alt-text-checker.min.js index 7a869dc..ee2b681 100644 --- a/dist/alt-text-checker.min.js +++ b/dist/alt-text-checker.min.js @@ -1 +1 @@ -!function(){"use strict";const e="atc",t={success:{bg:"lime",outline:"#000",text:"#000"},error:{bg:"#EB0000",outline:"#fff",text:"#fff"},warning:{bg:"orange",outline:"#000",text:"#000"},excluded:{bg:"#e0e0e0",outline:"#666",text:"#333"},info:{bg:"yellow",outline:"#000",text:"#000"}},n={success:"OK",error:"FEHLER",warning:"WARNUNG",excluded:"AUSGESCHLOSSEN",info:"INFO"},o={"font-family":"sans-serif","font-size":"small",padding:"5px 8px",outline:"2px dotted #000","outline-offset":"-3px",border:"0",cursor:"default","z-index":"2147483647"};function l(){return"alt-text-checker:excluded:"+location.href}function r(){try{const e=localStorage.getItem(l());return e?JSON.parse(e):[]}catch(e){return[]}}function i(e){if(null===e)return;const t=r(),n=t.indexOf(e);-1===n?t.push(e):t.splice(n,1),function(e){try{localStorage.setItem(l(),JSON.stringify(e))}catch(e){}}(t)}function a(e,t,n,o,l){if(t=t||document,o=o||new Set,l=l||new Set,o.has(t))return 0;o.add(t);let r=0;return Array.from(t.querySelectorAll(e)).forEach(e=>{l.has(e)||(l.add(e),n(e),r+=1)}),Array.from(t.querySelectorAll("*")).forEach(t=>{t.shadowRoot&&(r+=a(e,t.shadowRoot,n,o,l))}),r}function c(e){return!(!e.parentNode||"A"!==e.parentNode.tagName&&!c(e.parentNode))}function s(l,r,i,a){const c=t[r],s=!!(a=a||{}).global,u=document.createElement(s?"label":"button");u.className=`${e} ${e}-${r}`.trim();const d=Object.assign({},o,{"background-color":c.bg,"outline-color":c.outline,color:c.text});if("absolute"===a.position){const e=l.getBoundingClientRect();d.position="absolute",d.left=`${e.left+window.scrollX}px`,d.top=`${e.top+window.scrollY}px`}var g;a.extraStyle&&Object.assign(d,a.extraStyle),u.setAttribute("style",(g=d,Object.keys(g).map(e=>`${e}:${g[e]}`).join(";")));const f=a.icon||"";if(s)u.textContent=f?`${f} ${i}`:i;else{u.appendChild(document.createTextNode(f));const t=document.createElement("span");t.className=`${e}-badge`,t.textContent=n[r]||"",t.style.marginLeft="4px",t.style.fontWeight="700",u.appendChild(t);const o=document.createElement("span");if(o.className=`${e}-details`,o.appendChild(function(e){const t=document.createDocumentFragment();return e.forEach(e=>{if("string"==typeof e)t.appendChild(document.createTextNode(e));else if(void 0!==e.code){const n=document.createElement("code");n.textContent=e.code,t.appendChild(n)}else if(void 0!==e.strike){const n=document.createElement("s");n.textContent=e.strike,t.appendChild(n)}}),t}(i)),o.style.color="inherit",o.style.marginLeft="4px",u.appendChild(o),!a.alwaysOpen){o.style.display="none";const t=()=>{0===document.querySelectorAll(`.${e}-toggle:checked`).length&&(o.style.display="inline")},n=()=>{0===document.querySelectorAll(`.${e}-toggle:checked`).length&&(o.style.display="none")};u.addEventListener("focus",t),u.addEventListener("mouseover",t),u.addEventListener("blur",n),u.addEventListener("mouseout",n)}}if(a.onClick&&u.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),a.onClick()}),s&&a.withToggle){u.appendChild(document.createTextNode(" — alle Details anzeigen"));const t=document.createElement("input");t.type="checkbox",t.className=`${e}-toggle`,t.style.margin="0 0 0 4px",t.style.verticalAlign="baseline",t.addEventListener("change",function(){document.querySelectorAll(`.${e}-details`).forEach(e=>{e.style.display=this.checked?"inline":"none"})}),u.appendChild(t)}return s&&(document.querySelectorAll(`.${e}-global`).forEach(e=>e.remove()),u.className+=` ${e}-global`),"absolute"===a.position?document.body.appendChild(u):(a.insertInto||l.parentNode).appendChild(u),u}function u(e,t){const n=t.getAttribute(e);if(!n)return null;const o=n.split(" ").map(e=>e.trim()).filter(Boolean),l=[];return o.forEach(n=>{const o=document.getElementById(n);if(!o)return;s(o,"warning",[`Referenziert von [${e}="`,{code:t.id||"…"},'"]'],{icon:"⚠️",position:"absolute"});const r=o.textContent.trim();r&&l.push(r)}),l.length?l.join(" "):null}!function t(){a(`.${e}`,document,e=>e.remove());const n=r(),o=new Map,l={ok:0,error:0,warning:0,excluded:0,total:0};a("a[alt], button[alt], label[alt]",document,e=>{s(e,"error",[`<${e.tagName.toLowerCase()}> mit ungültigem `,{code:`alt="${e.getAttribute("alt")}"`}],{icon:"✖",position:"absolute"})}),a('img, [role="img"]',document,e=>{l.total+=1;const r=function(e,t){const n=function(e){if("IMG"===e.tagName)return e.currentSrc||e.src||null;const t=e.closest?e.closest("a[href]"):null;if(t&&t.href)return`role-img:${t.href}`;const n=e.getAttribute("aria-label");return n?`role-img:${n}`:e.className?`role-img:class:${e.className}`:null}(e);if(null===n)return null;const o=t.get(n)||0;return t.set(n,o+1),`${n}#${o}`}(e,o);if(function(e,t){return null!==e&&t.includes(e)}(r,n))return l.excluded+=1,void s(e,"excluded",["Ausgeschlossen (manuell als dekorativ markiert)"],{icon:"⦸",position:"absolute",onClick:()=>{i(r),t()}});const a=e.hasAttribute("alt"),d=a?e.getAttribute("alt"):null,g=e.hasAttribute("aria-label"),f=u("aria-describedby",e),m=u("aria-labelledby",e),p=e.hasAttribute("title"),h=e.hasAttribute("longdesc"),b="true"===e.getAttribute("aria-hidden"),y=g||null!==f||null!==m,x=c(e)?"Bild in Link: ":"",$=[];let A,w;if(p&&$.push(" ",{code:`title="${e.getAttribute("title")}"`}),h&&$.push(" ",{code:`longdesc="${e.getAttribute("longdesc")}"`}),a){const e=0===d.trim().length;A=[x,{code:`alt="${d}"`},...$],w=e?"warning":"success"}else if(b&&!y)A=[x,{code:'aria-hidden="true"'},...$],w="warning";else if(y){A=[p?"":x,{strike:"alt"}," fehlt, aber ARIA-Name vorhanden: ",{code:g?e.getAttribute("aria-label"):m||f},...$],w="warning"}else A=[x,{strike:"alt"}," fehlt",...$],w="error";l["success"===w?"ok":w]+=1,s(e,w,A,{icon:"success"===w?"✔":"error"===w?"✖":"⚠️",position:"absolute",onClick:()=>{i(r),t()}})});const d=l.error>0?"error":l.warning>0?"warning":"success",g=l.total?`Bilder: ${l.total} · ✔ ${l.ok} OK · ✖ ${l.error} Fehler · ⚠️ ${l.warning} Warnung · ⦸ ${l.excluded} ausgeschlossen`:"Keine Bilder auf dieser Seite gefunden.";s(document.body,l.total?d:"info",g,{global:!0,withToggle:!!l.total,extraStyle:{position:"fixed",top:"0",left:"0"}})}()}(); \ No newline at end of file +!function(){"use strict";const e="atc",t={success:{bg:"lime",outline:"#000",text:"#000"},error:{bg:"#EB0000",outline:"#fff",text:"#fff"},warning:{bg:"orange",outline:"#000",text:"#000"},excluded:{bg:"#e0e0e0",outline:"#666",text:"#333"},info:{bg:"yellow",outline:"#000",text:"#000"}},n={success:"OK",error:"FEHLER",warning:"WARNUNG",excluded:"AUSGESCHLOSSEN",info:"HINWEIS"},o={error:!0,warning:!0},l={"font-family":"sans-serif","font-size":"small",padding:"5px 8px",outline:"2px dotted #000","outline-offset":"-3px",border:"0",cursor:"default","z-index":"2147483647"};function r(){return"alt-text-checker:excluded:"+location.href}function i(){try{const e=localStorage.getItem(r());return e?JSON.parse(e):[]}catch(e){return[]}}function a(e){if(null===e)return;const t=i(),n=t.indexOf(e);-1===n?t.push(e):t.splice(n,1),function(e){try{localStorage.setItem(r(),JSON.stringify(e))}catch(e){}}(t)}function c(e,t,n,o,l){if(t=t||document,o=o||new Set,l=l||new Set,o.has(t))return 0;o.add(t);let r=0;return Array.from(t.querySelectorAll(e)).forEach(e=>{l.has(e)||(l.add(e),n(e),r+=1)}),Array.from(t.querySelectorAll("*")).forEach(t=>{t.shadowRoot&&(r+=c(e,t.shadowRoot,n,o,l))}),r}function s(e){return!(!e.parentNode||"A"!==e.parentNode.tagName&&!s(e.parentNode))}function u(o,r,i,a){const c=t[r],s=!!(a=a||{}).global,u=document.createElement(s?"label":"button");u.className=`${e} ${e}-${r}`.trim();const d=Object.assign({},l,{"background-color":c.bg,"outline-color":c.outline,color:c.text});if("absolute"===a.position){const e=o.getBoundingClientRect();d.position="absolute",d.left=`${e.left+window.scrollX}px`,d.top=`${e.top+window.scrollY}px`}var f;a.extraStyle&&Object.assign(d,a.extraStyle),u.setAttribute("style",(f=d,Object.keys(f).map(e=>`${e}:${f[e]}`).join(";")));const g=a.icon||"";if(s)u.textContent=g?`${g} ${i}`:i;else{u.appendChild(document.createTextNode(g));const t=document.createElement("span");t.className=`${e}-badge`,t.textContent=n[r]||"",t.style.marginLeft="4px",t.style.fontWeight="700",u.appendChild(t);const o=document.createElement("span");if(o.className=`${e}-details`,o.appendChild(function(e){const t=document.createDocumentFragment();return e.forEach(e=>{if("string"==typeof e)t.appendChild(document.createTextNode(e));else if(void 0!==e.code){const n=document.createElement("code");n.textContent=e.code,t.appendChild(n)}else if(void 0!==e.strike){const n=document.createElement("s");n.textContent=e.strike,t.appendChild(n)}}),t}(i)),o.style.color="inherit",o.style.marginLeft="4px",u.appendChild(o),!a.alwaysOpen){o.style.display="none";const t=()=>{0===document.querySelectorAll(`.${e}-toggle:checked`).length&&(o.style.display="inline")},n=()=>{0===document.querySelectorAll(`.${e}-toggle:checked`).length&&(o.style.display="none")};u.addEventListener("focus",t),u.addEventListener("mouseover",t),u.addEventListener("blur",n),u.addEventListener("mouseout",n)}}if(a.onClick&&u.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),a.onClick()}),s&&a.withToggle){u.appendChild(document.createTextNode(" — alle Details anzeigen"));const t=document.createElement("input");t.type="checkbox",t.className=`${e}-toggle`,t.style.margin="0 0 0 4px",t.style.verticalAlign="baseline",t.addEventListener("change",function(){document.querySelectorAll(`.${e}-details`).forEach(e=>{e.style.display=this.checked?"inline":"none"})}),u.appendChild(t)}return s&&(document.querySelectorAll(`.${e}-global`).forEach(e=>e.remove()),u.className+=` ${e}-global`),"absolute"===a.position?document.body.appendChild(u):(a.insertInto||o.parentNode).appendChild(u),u}function d(e,t){const n=t.getAttribute(e);if(!n)return null;const o=n.split(" ").map(e=>e.trim()).filter(Boolean),l=[];return o.forEach(n=>{const o=document.getElementById(n);if(!o)return;u(o,"warning",[`Referenziert von [${e}="`,{code:t.id||"…"},'"]'],{icon:"⚠️",position:"absolute"});const r=o.textContent.trim();r&&l.push(r)}),l.length?l.join(" "):null}!function t(){c(`.${e}`,document,e=>e.remove());const n=i(),l=new Map,r={ok:0,error:0,warning:0,info:0,excluded:0,total:0};c("a[alt], button[alt], label[alt]",document,e=>{u(e,"error",[`<${e.tagName.toLowerCase()}> mit ungültigem `,{code:`alt="${e.getAttribute("alt")}"`}],{icon:"✖",position:"absolute"})}),c('img, [role="img"]',document,e=>{r.total+=1;const i=function(e,t){const n=function(e){if("IMG"===e.tagName)return e.currentSrc||e.src||null;const t=e.closest?e.closest("a[href]"):null;if(t&&t.href)return`role-img:${t.href}`;const n=e.getAttribute("aria-label");return n?`role-img:${n}`:e.className?`role-img:class:${e.className}`:null}(e);if(null===n)return null;const o=t.get(n)||0;return t.set(n,o+1),`${n}#${o}`}(e,l);if(function(e,t){return null!==e&&t.includes(e)}(i,n))return r.excluded+=1,void u(e,"excluded",["Ausgeschlossen (manuell als dekorativ markiert)"],{icon:"⦸",position:"absolute",onClick:()=>{a(i),t()}});const c=e.hasAttribute("alt"),f=c?e.getAttribute("alt"):null,g=e.hasAttribute("aria-label"),m=d("aria-describedby",e),p=d("aria-labelledby",e),h=e.hasAttribute("title"),b=e.hasAttribute("longdesc"),y="true"===e.getAttribute("aria-hidden"),x=g||null!==m||null!==p,$=s(e)?"Bild in Link: ":"",A=[];let w,E;if(h&&A.push(" ",{code:`title="${e.getAttribute("title")}"`}),b&&A.push(" ",{code:`longdesc="${e.getAttribute("longdesc")}"`}),c){const e=0===f.trim().length;w=[$,{code:`alt="${f}"`},...A],E=e?"warning":"success"}else if(y&&!x)w=[$,{code:'aria-hidden="true"'},...A],E="info";else if(x){w=[h?"":$,{strike:"alt"}," fehlt, aber ARIA-Name vorhanden: ",{code:g?e.getAttribute("aria-label"):p||m},...A],E="warning"}else w=[$,{strike:"alt"}," fehlt",...A],E="error";r["success"===E?"ok":E]+=1;u(e,E,w,{icon:"success"===E?"✔":"error"===E?"✖":"info"===E?"ℹ️":"⚠️",position:"absolute",onClick:o[E]?()=>{a(i),t()}:void 0})});const f=r.error>0?"error":r.warning>0?"warning":"success",g=r.total?`Bilder: ${r.total} · ✔ ${r.ok} OK · ✖ ${r.error} Fehler · ⚠️ ${r.warning} Warnung · ℹ️ ${r.info} Hinweis · ⦸ ${r.excluded} ausgeschlossen`:"Keine Bilder auf dieser Seite gefunden.";u(document.body,r.total?f:"info",g,{global:!0,withToggle:!!r.total,extraStyle:{position:"fixed",top:"0",left:"0"}})}()}(); \ No newline at end of file diff --git a/dist/bookmarklet.txt b/dist/bookmarklet.txt index e780411..425dcad 100644 --- a/dist/bookmarklet.txt +++ b/dist/bookmarklet.txt @@ -1 +1 @@ -javascript:!function()%7B%22use%20strict%22%3Bconst%20e%3D%22atc%22%2Ct%3D%7Bsuccess%3A%7Bbg%3A%22lime%22%2Coutline%3A%22%23000%22%2Ctext%3A%22%23000%22%7D%2Cerror%3A%7Bbg%3A%22%23EB0000%22%2Coutline%3A%22%23fff%22%2Ctext%3A%22%23fff%22%7D%2Cwarning%3A%7Bbg%3A%22orange%22%2Coutline%3A%22%23000%22%2Ctext%3A%22%23000%22%7D%2Cexcluded%3A%7Bbg%3A%22%23e0e0e0%22%2Coutline%3A%22%23666%22%2Ctext%3A%22%23333%22%7D%2Cinfo%3A%7Bbg%3A%22yellow%22%2Coutline%3A%22%23000%22%2Ctext%3A%22%23000%22%7D%7D%2Cn%3D%7Bsuccess%3A%22OK%22%2Cerror%3A%22FEHLER%22%2Cwarning%3A%22WARNUNG%22%2Cexcluded%3A%22AUSGESCHLOSSEN%22%2Cinfo%3A%22INFO%22%7D%2Co%3D%7B%22font-family%22%3A%22sans-serif%22%2C%22font-size%22%3A%22small%22%2Cpadding%3A%225px%208px%22%2Coutline%3A%222px%20dotted%20%23000%22%2C%22outline-offset%22%3A%22-3px%22%2Cborder%3A%220%22%2Ccursor%3A%22default%22%2C%22z-index%22%3A%222147483647%22%7D%3Bfunction%20l()%7Breturn%22alt-text-checker%3Aexcluded%3A%22%2Blocation.href%7Dfunction%20r()%7Btry%7Bconst%20e%3DlocalStorage.getItem(l())%3Breturn%20e%3FJSON.parse(e)%3A%5B%5D%7Dcatch(e)%7Breturn%5B%5D%7D%7Dfunction%20i(e)%7Bif(null%3D%3D%3De)return%3Bconst%20t%3Dr()%2Cn%3Dt.indexOf(e)%3B-1%3D%3D%3Dn%3Ft.push(e)%3At.splice(n%2C1)%2Cfunction(e)%7Btry%7BlocalStorage.setItem(l()%2CJSON.stringify(e))%7Dcatch(e)%7B%7D%7D(t)%7Dfunction%20a(e%2Ct%2Cn%2Co%2Cl)%7Bif(t%3Dt%7C%7Cdocument%2Co%3Do%7C%7Cnew%20Set%2Cl%3Dl%7C%7Cnew%20Set%2Co.has(t))return%200%3Bo.add(t)%3Blet%20r%3D0%3Breturn%20Array.from(t.querySelectorAll(e)).forEach(e%3D%3E%7Bl.has(e)%7C%7C(l.add(e)%2Cn(e)%2Cr%2B%3D1)%7D)%2CArray.from(t.querySelectorAll(%22*%22)).forEach(t%3D%3E%7Bt.shadowRoot%26%26(r%2B%3Da(e%2Ct.shadowRoot%2Cn%2Co%2Cl))%7D)%2Cr%7Dfunction%20c(e)%7Breturn!(!e.parentNode%7C%7C%22A%22!%3D%3De.parentNode.tagName%26%26!c(e.parentNode))%7Dfunction%20s(l%2Cr%2Ci%2Ca)%7Bconst%20c%3Dt%5Br%5D%2Cs%3D!!(a%3Da%7C%7C%7B%7D).global%2Cu%3Ddocument.createElement(s%3F%22label%22%3A%22button%22)%3Bu.className%3D%60%24%7Be%7D%20%24%7Be%7D-%24%7Br%7D%60.trim()%3Bconst%20d%3DObject.assign(%7B%7D%2Co%2C%7B%22background-color%22%3Ac.bg%2C%22outline-color%22%3Ac.outline%2Ccolor%3Ac.text%7D)%3Bif(%22absolute%22%3D%3D%3Da.position)%7Bconst%20e%3Dl.getBoundingClientRect()%3Bd.position%3D%22absolute%22%2Cd.left%3D%60%24%7Be.left%2Bwindow.scrollX%7Dpx%60%2Cd.top%3D%60%24%7Be.top%2Bwindow.scrollY%7Dpx%60%7Dvar%20g%3Ba.extraStyle%26%26Object.assign(d%2Ca.extraStyle)%2Cu.setAttribute(%22style%22%2C(g%3Dd%2CObject.keys(g).map(e%3D%3E%60%24%7Be%7D%3A%24%7Bg%5Be%5D%7D%60).join(%22%3B%22)))%3Bconst%20f%3Da.icon%7C%7C%22%22%3Bif(s)u.textContent%3Df%3F%60%24%7Bf%7D%20%24%7Bi%7D%60%3Ai%3Belse%7Bu.appendChild(document.createTextNode(f))%3Bconst%20t%3Ddocument.createElement(%22span%22)%3Bt.className%3D%60%24%7Be%7D-badge%60%2Ct.textContent%3Dn%5Br%5D%7C%7C%22%22%2Ct.style.marginLeft%3D%224px%22%2Ct.style.fontWeight%3D%22700%22%2Cu.appendChild(t)%3Bconst%20o%3Ddocument.createElement(%22span%22)%3Bif(o.className%3D%60%24%7Be%7D-details%60%2Co.appendChild(function(e)%7Bconst%20t%3Ddocument.createDocumentFragment()%3Breturn%20e.forEach(e%3D%3E%7Bif(%22string%22%3D%3Dtypeof%20e)t.appendChild(document.createTextNode(e))%3Belse%20if(void%200!%3D%3De.code)%7Bconst%20n%3Ddocument.createElement(%22code%22)%3Bn.textContent%3De.code%2Ct.appendChild(n)%7Delse%20if(void%200!%3D%3De.strike)%7Bconst%20n%3Ddocument.createElement(%22s%22)%3Bn.textContent%3De.strike%2Ct.appendChild(n)%7D%7D)%2Ct%7D(i))%2Co.style.color%3D%22inherit%22%2Co.style.marginLeft%3D%224px%22%2Cu.appendChild(o)%2C!a.alwaysOpen)%7Bo.style.display%3D%22none%22%3Bconst%20t%3D()%3D%3E%7B0%3D%3D%3Ddocument.querySelectorAll(%60.%24%7Be%7D-toggle%3Achecked%60).length%26%26(o.style.display%3D%22inline%22)%7D%2Cn%3D()%3D%3E%7B0%3D%3D%3Ddocument.querySelectorAll(%60.%24%7Be%7D-toggle%3Achecked%60).length%26%26(o.style.display%3D%22none%22)%7D%3Bu.addEventListener(%22focus%22%2Ct)%2Cu.addEventListener(%22mouseover%22%2Ct)%2Cu.addEventListener(%22blur%22%2Cn)%2Cu.addEventListener(%22mouseout%22%2Cn)%7D%7Dif(a.onClick%26%26u.addEventListener(%22click%22%2Ce%3D%3E%7Be.preventDefault()%2Ce.stopPropagation()%2Ca.onClick()%7D)%2Cs%26%26a.withToggle)%7Bu.appendChild(document.createTextNode(%22%20%E2%80%94%20alle%20Details%20anzeigen%22))%3Bconst%20t%3Ddocument.createElement(%22input%22)%3Bt.type%3D%22checkbox%22%2Ct.className%3D%60%24%7Be%7D-toggle%60%2Ct.style.margin%3D%220%200%200%204px%22%2Ct.style.verticalAlign%3D%22baseline%22%2Ct.addEventListener(%22change%22%2Cfunction()%7Bdocument.querySelectorAll(%60.%24%7Be%7D-details%60).forEach(e%3D%3E%7Be.style.display%3Dthis.checked%3F%22inline%22%3A%22none%22%7D)%7D)%2Cu.appendChild(t)%7Dreturn%20s%26%26(document.querySelectorAll(%60.%24%7Be%7D-global%60).forEach(e%3D%3Ee.remove())%2Cu.className%2B%3D%60%20%24%7Be%7D-global%60)%2C%22absolute%22%3D%3D%3Da.position%3Fdocument.body.appendChild(u)%3A(a.insertInto%7C%7Cl.parentNode).appendChild(u)%2Cu%7Dfunction%20u(e%2Ct)%7Bconst%20n%3Dt.getAttribute(e)%3Bif(!n)return%20null%3Bconst%20o%3Dn.split(%22%20%22).map(e%3D%3Ee.trim()).filter(Boolean)%2Cl%3D%5B%5D%3Breturn%20o.forEach(n%3D%3E%7Bconst%20o%3Ddocument.getElementById(n)%3Bif(!o)return%3Bs(o%2C%22warning%22%2C%5B%60Referenziert%20von%20%5B%24%7Be%7D%3D%22%60%2C%7Bcode%3At.id%7C%7C%22%E2%80%A6%22%7D%2C'%22%5D'%5D%2C%7Bicon%3A%22%E2%9A%A0%EF%B8%8F%22%2Cposition%3A%22absolute%22%7D)%3Bconst%20r%3Do.textContent.trim()%3Br%26%26l.push(r)%7D)%2Cl.length%3Fl.join(%22%20%22)%3Anull%7D!function%20t()%7Ba(%60.%24%7Be%7D%60%2Cdocument%2Ce%3D%3Ee.remove())%3Bconst%20n%3Dr()%2Co%3Dnew%20Map%2Cl%3D%7Bok%3A0%2Cerror%3A0%2Cwarning%3A0%2Cexcluded%3A0%2Ctotal%3A0%7D%3Ba(%22a%5Balt%5D%2C%20button%5Balt%5D%2C%20label%5Balt%5D%22%2Cdocument%2Ce%3D%3E%7Bs(e%2C%22error%22%2C%5B%60%3C%24%7Be.tagName.toLowerCase()%7D%3E%20mit%20ung%C3%BCltigem%20%60%2C%7Bcode%3A%60alt%3D%22%24%7Be.getAttribute(%22alt%22)%7D%22%60%7D%5D%2C%7Bicon%3A%22%E2%9C%96%22%2Cposition%3A%22absolute%22%7D)%7D)%2Ca('img%2C%20%5Brole%3D%22img%22%5D'%2Cdocument%2Ce%3D%3E%7Bl.total%2B%3D1%3Bconst%20r%3Dfunction(e%2Ct)%7Bconst%20n%3Dfunction(e)%7Bif(%22IMG%22%3D%3D%3De.tagName)return%20e.currentSrc%7C%7Ce.src%7C%7Cnull%3Bconst%20t%3De.closest%3Fe.closest(%22a%5Bhref%5D%22)%3Anull%3Bif(t%26%26t.href)return%60role-img%3A%24%7Bt.href%7D%60%3Bconst%20n%3De.getAttribute(%22aria-label%22)%3Breturn%20n%3F%60role-img%3A%24%7Bn%7D%60%3Ae.className%3F%60role-img%3Aclass%3A%24%7Be.className%7D%60%3Anull%7D(e)%3Bif(null%3D%3D%3Dn)return%20null%3Bconst%20o%3Dt.get(n)%7C%7C0%3Breturn%20t.set(n%2Co%2B1)%2C%60%24%7Bn%7D%23%24%7Bo%7D%60%7D(e%2Co)%3Bif(function(e%2Ct)%7Breturn%20null!%3D%3De%26%26t.includes(e)%7D(r%2Cn))return%20l.excluded%2B%3D1%2Cvoid%20s(e%2C%22excluded%22%2C%5B%22Ausgeschlossen%20(manuell%20als%20dekorativ%20markiert)%22%5D%2C%7Bicon%3A%22%E2%A6%B8%22%2Cposition%3A%22absolute%22%2ConClick%3A()%3D%3E%7Bi(r)%2Ct()%7D%7D)%3Bconst%20a%3De.hasAttribute(%22alt%22)%2Cd%3Da%3Fe.getAttribute(%22alt%22)%3Anull%2Cg%3De.hasAttribute(%22aria-label%22)%2Cf%3Du(%22aria-describedby%22%2Ce)%2Cm%3Du(%22aria-labelledby%22%2Ce)%2Cp%3De.hasAttribute(%22title%22)%2Ch%3De.hasAttribute(%22longdesc%22)%2Cb%3D%22true%22%3D%3D%3De.getAttribute(%22aria-hidden%22)%2Cy%3Dg%7C%7Cnull!%3D%3Df%7C%7Cnull!%3D%3Dm%2Cx%3Dc(e)%3F%22Bild%20in%20Link%3A%20%22%3A%22%22%2C%24%3D%5B%5D%3Blet%20A%2Cw%3Bif(p%26%26%24.push(%22%20%22%2C%7Bcode%3A%60title%3D%22%24%7Be.getAttribute(%22title%22)%7D%22%60%7D)%2Ch%26%26%24.push(%22%20%22%2C%7Bcode%3A%60longdesc%3D%22%24%7Be.getAttribute(%22longdesc%22)%7D%22%60%7D)%2Ca)%7Bconst%20e%3D0%3D%3D%3Dd.trim().length%3BA%3D%5Bx%2C%7Bcode%3A%60alt%3D%22%24%7Bd%7D%22%60%7D%2C...%24%5D%2Cw%3De%3F%22warning%22%3A%22success%22%7Delse%20if(b%26%26!y)A%3D%5Bx%2C%7Bcode%3A'aria-hidden%3D%22true%22'%7D%2C...%24%5D%2Cw%3D%22warning%22%3Belse%20if(y)%7BA%3D%5Bp%3F%22%22%3Ax%2C%7Bstrike%3A%22alt%22%7D%2C%22%20fehlt%2C%20aber%20ARIA-Name%20vorhanden%3A%20%22%2C%7Bcode%3Ag%3Fe.getAttribute(%22aria-label%22)%3Am%7C%7Cf%7D%2C...%24%5D%2Cw%3D%22warning%22%7Delse%20A%3D%5Bx%2C%7Bstrike%3A%22alt%22%7D%2C%22%20fehlt%22%2C...%24%5D%2Cw%3D%22error%22%3Bl%5B%22success%22%3D%3D%3Dw%3F%22ok%22%3Aw%5D%2B%3D1%2Cs(e%2Cw%2CA%2C%7Bicon%3A%22success%22%3D%3D%3Dw%3F%22%E2%9C%94%22%3A%22error%22%3D%3D%3Dw%3F%22%E2%9C%96%22%3A%22%E2%9A%A0%EF%B8%8F%22%2Cposition%3A%22absolute%22%2ConClick%3A()%3D%3E%7Bi(r)%2Ct()%7D%7D)%7D)%3Bconst%20d%3Dl.error%3E0%3F%22error%22%3Al.warning%3E0%3F%22warning%22%3A%22success%22%2Cg%3Dl.total%3F%60Bilder%3A%20%24%7Bl.total%7D%20%C2%B7%20%E2%9C%94%20%24%7Bl.ok%7D%20OK%20%C2%B7%20%E2%9C%96%20%24%7Bl.error%7D%20Fehler%20%C2%B7%20%E2%9A%A0%EF%B8%8F%20%24%7Bl.warning%7D%20Warnung%20%C2%B7%20%E2%A6%B8%20%24%7Bl.excluded%7D%20ausgeschlossen%60%3A%22Keine%20Bilder%20auf%20dieser%20Seite%20gefunden.%22%3Bs(document.body%2Cl.total%3Fd%3A%22info%22%2Cg%2C%7Bglobal%3A!0%2CwithToggle%3A!!l.total%2CextraStyle%3A%7Bposition%3A%22fixed%22%2Ctop%3A%220%22%2Cleft%3A%220%22%7D%7D)%7D()%7D()%3B \ No newline at end of file +javascript:!function()%7B%22use%20strict%22%3Bconst%20e%3D%22atc%22%2Ct%3D%7Bsuccess%3A%7Bbg%3A%22lime%22%2Coutline%3A%22%23000%22%2Ctext%3A%22%23000%22%7D%2Cerror%3A%7Bbg%3A%22%23EB0000%22%2Coutline%3A%22%23fff%22%2Ctext%3A%22%23fff%22%7D%2Cwarning%3A%7Bbg%3A%22orange%22%2Coutline%3A%22%23000%22%2Ctext%3A%22%23000%22%7D%2Cexcluded%3A%7Bbg%3A%22%23e0e0e0%22%2Coutline%3A%22%23666%22%2Ctext%3A%22%23333%22%7D%2Cinfo%3A%7Bbg%3A%22yellow%22%2Coutline%3A%22%23000%22%2Ctext%3A%22%23000%22%7D%7D%2Cn%3D%7Bsuccess%3A%22OK%22%2Cerror%3A%22FEHLER%22%2Cwarning%3A%22WARNUNG%22%2Cexcluded%3A%22AUSGESCHLOSSEN%22%2Cinfo%3A%22HINWEIS%22%7D%2Co%3D%7Berror%3A!0%2Cwarning%3A!0%7D%2Cl%3D%7B%22font-family%22%3A%22sans-serif%22%2C%22font-size%22%3A%22small%22%2Cpadding%3A%225px%208px%22%2Coutline%3A%222px%20dotted%20%23000%22%2C%22outline-offset%22%3A%22-3px%22%2Cborder%3A%220%22%2Ccursor%3A%22default%22%2C%22z-index%22%3A%222147483647%22%7D%3Bfunction%20r()%7Breturn%22alt-text-checker%3Aexcluded%3A%22%2Blocation.href%7Dfunction%20i()%7Btry%7Bconst%20e%3DlocalStorage.getItem(r())%3Breturn%20e%3FJSON.parse(e)%3A%5B%5D%7Dcatch(e)%7Breturn%5B%5D%7D%7Dfunction%20a(e)%7Bif(null%3D%3D%3De)return%3Bconst%20t%3Di()%2Cn%3Dt.indexOf(e)%3B-1%3D%3D%3Dn%3Ft.push(e)%3At.splice(n%2C1)%2Cfunction(e)%7Btry%7BlocalStorage.setItem(r()%2CJSON.stringify(e))%7Dcatch(e)%7B%7D%7D(t)%7Dfunction%20c(e%2Ct%2Cn%2Co%2Cl)%7Bif(t%3Dt%7C%7Cdocument%2Co%3Do%7C%7Cnew%20Set%2Cl%3Dl%7C%7Cnew%20Set%2Co.has(t))return%200%3Bo.add(t)%3Blet%20r%3D0%3Breturn%20Array.from(t.querySelectorAll(e)).forEach(e%3D%3E%7Bl.has(e)%7C%7C(l.add(e)%2Cn(e)%2Cr%2B%3D1)%7D)%2CArray.from(t.querySelectorAll(%22*%22)).forEach(t%3D%3E%7Bt.shadowRoot%26%26(r%2B%3Dc(e%2Ct.shadowRoot%2Cn%2Co%2Cl))%7D)%2Cr%7Dfunction%20s(e)%7Breturn!(!e.parentNode%7C%7C%22A%22!%3D%3De.parentNode.tagName%26%26!s(e.parentNode))%7Dfunction%20u(o%2Cr%2Ci%2Ca)%7Bconst%20c%3Dt%5Br%5D%2Cs%3D!!(a%3Da%7C%7C%7B%7D).global%2Cu%3Ddocument.createElement(s%3F%22label%22%3A%22button%22)%3Bu.className%3D%60%24%7Be%7D%20%24%7Be%7D-%24%7Br%7D%60.trim()%3Bconst%20d%3DObject.assign(%7B%7D%2Cl%2C%7B%22background-color%22%3Ac.bg%2C%22outline-color%22%3Ac.outline%2Ccolor%3Ac.text%7D)%3Bif(%22absolute%22%3D%3D%3Da.position)%7Bconst%20e%3Do.getBoundingClientRect()%3Bd.position%3D%22absolute%22%2Cd.left%3D%60%24%7Be.left%2Bwindow.scrollX%7Dpx%60%2Cd.top%3D%60%24%7Be.top%2Bwindow.scrollY%7Dpx%60%7Dvar%20f%3Ba.extraStyle%26%26Object.assign(d%2Ca.extraStyle)%2Cu.setAttribute(%22style%22%2C(f%3Dd%2CObject.keys(f).map(e%3D%3E%60%24%7Be%7D%3A%24%7Bf%5Be%5D%7D%60).join(%22%3B%22)))%3Bconst%20g%3Da.icon%7C%7C%22%22%3Bif(s)u.textContent%3Dg%3F%60%24%7Bg%7D%20%24%7Bi%7D%60%3Ai%3Belse%7Bu.appendChild(document.createTextNode(g))%3Bconst%20t%3Ddocument.createElement(%22span%22)%3Bt.className%3D%60%24%7Be%7D-badge%60%2Ct.textContent%3Dn%5Br%5D%7C%7C%22%22%2Ct.style.marginLeft%3D%224px%22%2Ct.style.fontWeight%3D%22700%22%2Cu.appendChild(t)%3Bconst%20o%3Ddocument.createElement(%22span%22)%3Bif(o.className%3D%60%24%7Be%7D-details%60%2Co.appendChild(function(e)%7Bconst%20t%3Ddocument.createDocumentFragment()%3Breturn%20e.forEach(e%3D%3E%7Bif(%22string%22%3D%3Dtypeof%20e)t.appendChild(document.createTextNode(e))%3Belse%20if(void%200!%3D%3De.code)%7Bconst%20n%3Ddocument.createElement(%22code%22)%3Bn.textContent%3De.code%2Ct.appendChild(n)%7Delse%20if(void%200!%3D%3De.strike)%7Bconst%20n%3Ddocument.createElement(%22s%22)%3Bn.textContent%3De.strike%2Ct.appendChild(n)%7D%7D)%2Ct%7D(i))%2Co.style.color%3D%22inherit%22%2Co.style.marginLeft%3D%224px%22%2Cu.appendChild(o)%2C!a.alwaysOpen)%7Bo.style.display%3D%22none%22%3Bconst%20t%3D()%3D%3E%7B0%3D%3D%3Ddocument.querySelectorAll(%60.%24%7Be%7D-toggle%3Achecked%60).length%26%26(o.style.display%3D%22inline%22)%7D%2Cn%3D()%3D%3E%7B0%3D%3D%3Ddocument.querySelectorAll(%60.%24%7Be%7D-toggle%3Achecked%60).length%26%26(o.style.display%3D%22none%22)%7D%3Bu.addEventListener(%22focus%22%2Ct)%2Cu.addEventListener(%22mouseover%22%2Ct)%2Cu.addEventListener(%22blur%22%2Cn)%2Cu.addEventListener(%22mouseout%22%2Cn)%7D%7Dif(a.onClick%26%26u.addEventListener(%22click%22%2Ce%3D%3E%7Be.preventDefault()%2Ce.stopPropagation()%2Ca.onClick()%7D)%2Cs%26%26a.withToggle)%7Bu.appendChild(document.createTextNode(%22%20%E2%80%94%20alle%20Details%20anzeigen%22))%3Bconst%20t%3Ddocument.createElement(%22input%22)%3Bt.type%3D%22checkbox%22%2Ct.className%3D%60%24%7Be%7D-toggle%60%2Ct.style.margin%3D%220%200%200%204px%22%2Ct.style.verticalAlign%3D%22baseline%22%2Ct.addEventListener(%22change%22%2Cfunction()%7Bdocument.querySelectorAll(%60.%24%7Be%7D-details%60).forEach(e%3D%3E%7Be.style.display%3Dthis.checked%3F%22inline%22%3A%22none%22%7D)%7D)%2Cu.appendChild(t)%7Dreturn%20s%26%26(document.querySelectorAll(%60.%24%7Be%7D-global%60).forEach(e%3D%3Ee.remove())%2Cu.className%2B%3D%60%20%24%7Be%7D-global%60)%2C%22absolute%22%3D%3D%3Da.position%3Fdocument.body.appendChild(u)%3A(a.insertInto%7C%7Co.parentNode).appendChild(u)%2Cu%7Dfunction%20d(e%2Ct)%7Bconst%20n%3Dt.getAttribute(e)%3Bif(!n)return%20null%3Bconst%20o%3Dn.split(%22%20%22).map(e%3D%3Ee.trim()).filter(Boolean)%2Cl%3D%5B%5D%3Breturn%20o.forEach(n%3D%3E%7Bconst%20o%3Ddocument.getElementById(n)%3Bif(!o)return%3Bu(o%2C%22warning%22%2C%5B%60Referenziert%20von%20%5B%24%7Be%7D%3D%22%60%2C%7Bcode%3At.id%7C%7C%22%E2%80%A6%22%7D%2C'%22%5D'%5D%2C%7Bicon%3A%22%E2%9A%A0%EF%B8%8F%22%2Cposition%3A%22absolute%22%7D)%3Bconst%20r%3Do.textContent.trim()%3Br%26%26l.push(r)%7D)%2Cl.length%3Fl.join(%22%20%22)%3Anull%7D!function%20t()%7Bc(%60.%24%7Be%7D%60%2Cdocument%2Ce%3D%3Ee.remove())%3Bconst%20n%3Di()%2Cl%3Dnew%20Map%2Cr%3D%7Bok%3A0%2Cerror%3A0%2Cwarning%3A0%2Cinfo%3A0%2Cexcluded%3A0%2Ctotal%3A0%7D%3Bc(%22a%5Balt%5D%2C%20button%5Balt%5D%2C%20label%5Balt%5D%22%2Cdocument%2Ce%3D%3E%7Bu(e%2C%22error%22%2C%5B%60%3C%24%7Be.tagName.toLowerCase()%7D%3E%20mit%20ung%C3%BCltigem%20%60%2C%7Bcode%3A%60alt%3D%22%24%7Be.getAttribute(%22alt%22)%7D%22%60%7D%5D%2C%7Bicon%3A%22%E2%9C%96%22%2Cposition%3A%22absolute%22%7D)%7D)%2Cc('img%2C%20%5Brole%3D%22img%22%5D'%2Cdocument%2Ce%3D%3E%7Br.total%2B%3D1%3Bconst%20i%3Dfunction(e%2Ct)%7Bconst%20n%3Dfunction(e)%7Bif(%22IMG%22%3D%3D%3De.tagName)return%20e.currentSrc%7C%7Ce.src%7C%7Cnull%3Bconst%20t%3De.closest%3Fe.closest(%22a%5Bhref%5D%22)%3Anull%3Bif(t%26%26t.href)return%60role-img%3A%24%7Bt.href%7D%60%3Bconst%20n%3De.getAttribute(%22aria-label%22)%3Breturn%20n%3F%60role-img%3A%24%7Bn%7D%60%3Ae.className%3F%60role-img%3Aclass%3A%24%7Be.className%7D%60%3Anull%7D(e)%3Bif(null%3D%3D%3Dn)return%20null%3Bconst%20o%3Dt.get(n)%7C%7C0%3Breturn%20t.set(n%2Co%2B1)%2C%60%24%7Bn%7D%23%24%7Bo%7D%60%7D(e%2Cl)%3Bif(function(e%2Ct)%7Breturn%20null!%3D%3De%26%26t.includes(e)%7D(i%2Cn))return%20r.excluded%2B%3D1%2Cvoid%20u(e%2C%22excluded%22%2C%5B%22Ausgeschlossen%20(manuell%20als%20dekorativ%20markiert)%22%5D%2C%7Bicon%3A%22%E2%A6%B8%22%2Cposition%3A%22absolute%22%2ConClick%3A()%3D%3E%7Ba(i)%2Ct()%7D%7D)%3Bconst%20c%3De.hasAttribute(%22alt%22)%2Cf%3Dc%3Fe.getAttribute(%22alt%22)%3Anull%2Cg%3De.hasAttribute(%22aria-label%22)%2Cm%3Dd(%22aria-describedby%22%2Ce)%2Cp%3Dd(%22aria-labelledby%22%2Ce)%2Ch%3De.hasAttribute(%22title%22)%2Cb%3De.hasAttribute(%22longdesc%22)%2Cy%3D%22true%22%3D%3D%3De.getAttribute(%22aria-hidden%22)%2Cx%3Dg%7C%7Cnull!%3D%3Dm%7C%7Cnull!%3D%3Dp%2C%24%3Ds(e)%3F%22Bild%20in%20Link%3A%20%22%3A%22%22%2CA%3D%5B%5D%3Blet%20w%2CE%3Bif(h%26%26A.push(%22%20%22%2C%7Bcode%3A%60title%3D%22%24%7Be.getAttribute(%22title%22)%7D%22%60%7D)%2Cb%26%26A.push(%22%20%22%2C%7Bcode%3A%60longdesc%3D%22%24%7Be.getAttribute(%22longdesc%22)%7D%22%60%7D)%2Cc)%7Bconst%20e%3D0%3D%3D%3Df.trim().length%3Bw%3D%5B%24%2C%7Bcode%3A%60alt%3D%22%24%7Bf%7D%22%60%7D%2C...A%5D%2CE%3De%3F%22warning%22%3A%22success%22%7Delse%20if(y%26%26!x)w%3D%5B%24%2C%7Bcode%3A'aria-hidden%3D%22true%22'%7D%2C...A%5D%2CE%3D%22info%22%3Belse%20if(x)%7Bw%3D%5Bh%3F%22%22%3A%24%2C%7Bstrike%3A%22alt%22%7D%2C%22%20fehlt%2C%20aber%20ARIA-Name%20vorhanden%3A%20%22%2C%7Bcode%3Ag%3Fe.getAttribute(%22aria-label%22)%3Ap%7C%7Cm%7D%2C...A%5D%2CE%3D%22warning%22%7Delse%20w%3D%5B%24%2C%7Bstrike%3A%22alt%22%7D%2C%22%20fehlt%22%2C...A%5D%2CE%3D%22error%22%3Br%5B%22success%22%3D%3D%3DE%3F%22ok%22%3AE%5D%2B%3D1%3Bu(e%2CE%2Cw%2C%7Bicon%3A%22success%22%3D%3D%3DE%3F%22%E2%9C%94%22%3A%22error%22%3D%3D%3DE%3F%22%E2%9C%96%22%3A%22info%22%3D%3D%3DE%3F%22%E2%84%B9%EF%B8%8F%22%3A%22%E2%9A%A0%EF%B8%8F%22%2Cposition%3A%22absolute%22%2ConClick%3Ao%5BE%5D%3F()%3D%3E%7Ba(i)%2Ct()%7D%3Avoid%200%7D)%7D)%3Bconst%20f%3Dr.error%3E0%3F%22error%22%3Ar.warning%3E0%3F%22warning%22%3A%22success%22%2Cg%3Dr.total%3F%60Bilder%3A%20%24%7Br.total%7D%20%C2%B7%20%E2%9C%94%20%24%7Br.ok%7D%20OK%20%C2%B7%20%E2%9C%96%20%24%7Br.error%7D%20Fehler%20%C2%B7%20%E2%9A%A0%EF%B8%8F%20%24%7Br.warning%7D%20Warnung%20%C2%B7%20%E2%84%B9%EF%B8%8F%20%24%7Br.info%7D%20Hinweis%20%C2%B7%20%E2%A6%B8%20%24%7Br.excluded%7D%20ausgeschlossen%60%3A%22Keine%20Bilder%20auf%20dieser%20Seite%20gefunden.%22%3Bu(document.body%2Cr.total%3Ff%3A%22info%22%2Cg%2C%7Bglobal%3A!0%2CwithToggle%3A!!r.total%2CextraStyle%3A%7Bposition%3A%22fixed%22%2Ctop%3A%220%22%2Cleft%3A%220%22%7D%7D)%7D()%7D()%3B \ No newline at end of file diff --git a/src/alt-text-checker.js b/src/alt-text-checker.js index 5071c57..2d1fd3a 100644 --- a/src/alt-text-checker.js +++ b/src/alt-text-checker.js @@ -28,9 +28,15 @@ error: 'FEHLER', warning: 'WARNUNG', excluded: 'AUSGESCHLOSSEN', - info: 'INFO' + info: 'HINWEIS' }; + // Nur bei diesen Status ergibt ein manueller Ausschluss Sinn (echte Probleme, + // die man als "geprüft und bewusst so gelassen" markieren will). "success" + // ist bereits in Ordnung, "info" (z.B. aria-hidden="true") ist bereits + // korrekt für Screenreader ausgeblendet – beide brauchen keinen Ausschluss-Klick. + const EXCLUDABLE_KINDS = { error: true, warning: true }; + const BASE_LABEL_STYLE = { 'font-family': 'sans-serif', 'font-size': 'small', @@ -327,7 +333,7 @@ removePreviousRun(); const exclusions = loadExclusions(); const occurrenceCounts = new Map(); - const stats = { ok: 0, error: 0, warning: 0, excluded: 0, total: 0 }; + const stats = { ok: 0, error: 0, warning: 0, info: 0, excluded: 0, total: 0 }; // Fehlerhafte Verwendung von alt auf Nicht--Elementen deepQueryAll('a[alt], button[alt], label[alt]', document, (el) => { @@ -381,11 +387,11 @@ } 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--Elementen), daher - // hier keine Fehlermeldung, sondern dieselbe Einstufung wie alt="". + // Bild. Das ist bereits der gewünschte Zustand (kein Fehler, keine + // Warnung), daher nur ein Hinweis zur Information – und nicht + // ausschließbar, da es nichts zu "beheben" gibt. segments = [linkPrefix, { code: 'aria-hidden="true"' }, ...extras]; - kind = 'warning'; + kind = 'info'; } else if (hasAccessibleName) { const resolvedName = hasAriaLabel ? img.getAttribute('aria-label') : (labelledBy || describedBy); segments = [ @@ -403,19 +409,22 @@ stats[kind === 'success' ? 'ok' : kind] += 1; + const icon = kind === 'success' ? '✔' : kind === 'error' ? '✖' : kind === 'info' ? 'ℹ️' : '⚠️'; createLabel(img, kind, segments, { - icon: kind === 'success' ? '✔' : kind === 'error' ? '✖' : '⚠️', + icon, position: 'absolute', - onClick: () => { - toggleExclusion(id); - run(); - } + onClick: EXCLUDABLE_KINDS[kind] + ? () => { + toggleExclusion(id); + run(); + } + : undefined }); }); const summaryKind = stats.error > 0 ? 'error' : stats.warning > 0 ? 'warning' : 'success'; const summaryText = stats.total - ? `Bilder: ${stats.total} · ✔ ${stats.ok} OK · ✖ ${stats.error} Fehler · ⚠️ ${stats.warning} Warnung · ⦸ ${stats.excluded} ausgeschlossen` + ? `Bilder: ${stats.total} · ✔ ${stats.ok} OK · ✖ ${stats.error} Fehler · ⚠️ ${stats.warning} Warnung · ℹ️ ${stats.info} Hinweis · ⦸ ${stats.excluded} ausgeschlossen` : 'Keine Bilder auf dieser Seite gefunden.'; createLabel(document.body, stats.total ? summaryKind : 'info', summaryText, {