mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-14 23:26:39 +03:00
Fix linked CSS selector filtering
Resolve pseudo-element selectors to live hosts, reject unresolvable linked CSS findings, and make the regression assertions independent. Also ignore comment delimiters when recovering CSS rule selectors. AI assistance disclosure: This commit was prepared with Codex under maintainer direction.
This commit is contained in:
@@ -1287,8 +1287,18 @@ if (IS_BROWSER) {
|
||||
const exact = Array.from(root.querySelectorAll(raw));
|
||||
if (exact.length > 0) return exact;
|
||||
} catch { /* Dynamic/unsupported pseudos get the fallback below. */ }
|
||||
|
||||
// Resolve pseudo-elements to their originating live elements. An attached
|
||||
// pseudo-element (`.card::before`) belongs to the element before it, while
|
||||
// a hostless pseudo-element after a combinator (`main > ::before`) belongs
|
||||
// to a matching element at that position (`main > *`). Replacing every
|
||||
// pseudo indiscriminately with an empty string leaves the latter as the
|
||||
// invalid selector `main >` and makes absent hosts indistinguishable from
|
||||
// selectors the DOM API cannot parse.
|
||||
const fallback = raw
|
||||
.replace(/::?[a-zA-Z-]+(\([^)]*\))?/g, '')
|
||||
.replace(/(^|[\s>+~,])::[a-zA-Z-]+(\([^)]*\))?/g, '$1*')
|
||||
.replace(/::[a-zA-Z-]+(\([^)]*\))?/g, '')
|
||||
.replace(/:[a-zA-Z-]+(\([^)]*\))?/g, '')
|
||||
.trim()
|
||||
.replace(/,\s*(?=,|$)/g, '');
|
||||
if (!fallback || /^[,\s]*$/.test(fallback)) return null;
|
||||
@@ -1333,11 +1343,10 @@ if (IS_BROWSER) {
|
||||
const cssText = rule.cssText || '';
|
||||
if (rule.selectorText) {
|
||||
const matches = selectorNodesForLiveDom(document, rule.selectorText);
|
||||
// A null result means the DOM selector API cannot resolve the CSSOM
|
||||
// selector (commonly a hostless pseudo-element), not that it is
|
||||
// unused. Keep those valid stylesheet rules; only a definitive empty
|
||||
// result proves that no live element can receive the declaration.
|
||||
if (matches === null || matches.length > 0) parts.push(cssText);
|
||||
// Only declarations with a resolvable live host enter the corpus.
|
||||
// Unresolvable selectors are uncertain, not evidence that a pattern
|
||||
// rendered, and retaining them would leak unused CSS into findings.
|
||||
if (matches?.length > 0) parts.push(cssText);
|
||||
continue;
|
||||
}
|
||||
let nested = [];
|
||||
@@ -1758,7 +1767,7 @@ if (IS_BROWSER) {
|
||||
const scopedHtmlFindings = checkHtmlPatterns(html, corpora).filter(f => {
|
||||
if (!f.selector) return true;
|
||||
const matches = selectorNodesForLiveDom(document, f.selector);
|
||||
if (!matches) return true;
|
||||
if (!matches) return false;
|
||||
if (matches.length === 0) return false;
|
||||
return matches.some(el => !scopedIgnoreActive(el, f.id));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user