Fix exclusion grouping duplicate images together
Exclusions were keyed only by content identifier (src / role-img label), so multiple identical images (or repeated icons) shared one key and excluding one silently excluded all of them. Each occurrence now gets a per-run instance number appended to the identifier, so duplicates can be excluded individually while staying stable across reloads. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
1cef0eddca
commit
c6a92ea26c
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -80,13 +80,24 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isExcluded(img, exclusions) {
|
// Mehrere Bilder können dieselbe imageIdentifier() haben (z.B. dasselbe Icon
|
||||||
const id = imageIdentifier(img);
|
// mehrfach auf der Seite). Ohne Zusatz würde ein Ausschluss dann alle gleich
|
||||||
|
// aussehenden Bilder treffen. Der Zähler hängt daher pro Lauf eine laufende
|
||||||
|
// Nummer an, sodass jedes Vorkommen einzeln aus-/eingeschlossen werden kann –
|
||||||
|
// stabil über Neuladen, solange Reihenfolge und Anzahl der Duplikate gleich bleiben.
|
||||||
|
function instanceIdentifier(img, occurrenceCounts) {
|
||||||
|
const base = imageIdentifier(img);
|
||||||
|
if (base === null) return null;
|
||||||
|
const n = occurrenceCounts.get(base) || 0;
|
||||||
|
occurrenceCounts.set(base, n + 1);
|
||||||
|
return `${base}#${n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExcluded(id, exclusions) {
|
||||||
return id !== null && exclusions.includes(id);
|
return id !== null && exclusions.includes(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleExclusion(img) {
|
function toggleExclusion(id) {
|
||||||
const id = imageIdentifier(img);
|
|
||||||
if (id === null) return;
|
if (id === null) return;
|
||||||
const exclusions = loadExclusions();
|
const exclusions = loadExclusions();
|
||||||
const idx = exclusions.indexOf(id);
|
const idx = exclusions.indexOf(id);
|
||||||
|
|
@ -288,6 +299,7 @@
|
||||||
function run() {
|
function run() {
|
||||||
removePreviousRun();
|
removePreviousRun();
|
||||||
const exclusions = loadExclusions();
|
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, excluded: 0, total: 0 };
|
||||||
|
|
||||||
// Fehlerhafte Verwendung von alt auf Nicht-<img>-Elementen
|
// Fehlerhafte Verwendung von alt auf Nicht-<img>-Elementen
|
||||||
|
|
@ -302,14 +314,15 @@
|
||||||
|
|
||||||
deepQueryAll('img, [role="img"]', document, (img) => {
|
deepQueryAll('img, [role="img"]', document, (img) => {
|
||||||
stats.total += 1;
|
stats.total += 1;
|
||||||
|
const id = instanceIdentifier(img, occurrenceCounts);
|
||||||
|
|
||||||
if (isExcluded(img, exclusions)) {
|
if (isExcluded(id, exclusions)) {
|
||||||
stats.excluded += 1;
|
stats.excluded += 1;
|
||||||
createLabel(img, 'excluded', ['Ausgeschlossen (manuell als dekorativ markiert)'], {
|
createLabel(img, 'excluded', ['Ausgeschlossen (manuell als dekorativ markiert)'], {
|
||||||
icon: '⦸',
|
icon: '⦸',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleExclusion(img);
|
toggleExclusion(id);
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -358,7 +371,7 @@
|
||||||
icon: kind === 'success' ? '✔' : kind === 'error' ? '✖' : '⚠️',
|
icon: kind === 'success' ? '✔' : kind === 'error' ? '✖' : '⚠️',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleExclusion(img);
|
toggleExclusion(id);
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -36,5 +36,12 @@
|
||||||
|
|
||||||
<p>8. Bild mit potenziell gefährlichem alt-Text (XSS-Test):</p>
|
<p>8. Bild mit potenziell gefährlichem alt-Text (XSS-Test):</p>
|
||||||
<img src="https://via.placeholder.com/100x80/000000/ffffff?text=8" alt="<img src=x onerror=alert('XSS')>">
|
<img src="https://via.placeholder.com/100x80/000000/ffffff?text=8" alt="<img src=x onerror=alert('XSS')>">
|
||||||
|
|
||||||
|
<p>9a. Dasselbe Bild dreimal ohne alt (Duplikat-Test – nur dieses eine ausschließen):</p>
|
||||||
|
<img src="https://via.placeholder.com/100x80/999999/ffffff?text=9">
|
||||||
|
<p>9b. Zweites Vorkommen desselben Bildes:</p>
|
||||||
|
<img src="https://via.placeholder.com/100x80/999999/ffffff?text=9">
|
||||||
|
<p>9c. Drittes Vorkommen desselben Bildes:</p>
|
||||||
|
<img src="https://via.placeholder.com/100x80/999999/ffffff?text=9">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue