Some frameworks (e.g. Salesforce LWC) expose a .shadowRoot on elements
whose content is actually the same light-DOM subtree rather than a
real encapsulated tree. deepQueryAll's recursive shadow traversal
revisited that subtree once per nested "shadow" ancestor, so a single
image could get processed and labeled multiple times (observed: one
footer logo produced 5 identical OK badges). deepQueryAll now tracks
visited roots and elements so each is only ever processed once.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
imageIdentifier() only checked currentSrc/src, which don't exist on
inline <svg role="img"> icons (common for social-media links). The
exclude click therefore silently no-op'd for those. Fall back to the
surrounding link's href or the element's aria-label as the identity.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>