From 312e627eeacb2c9839de10a189983509f4625299 Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Wed, 2 Sep 2026 09:18:52 -0700 Subject: [PATCH] Filter linked CSS to rendered selectors Flatten linked stylesheet grouping rules and collect only selector rules that target the live DOM, preventing unused grouped and selector-less patterns from leaking into URL findings. AI assistance disclosure: Implemented and verified with Codex under maintainer direction. --- cli/engine/browser/injected/index.mjs | 68 +++++++++++++++---- cli/engine/detect-antipatterns-browser.js | 68 +++++++++++++++---- tests/detect-antipatterns-browser.test.mjs | 14 +++- .../antipatterns/linked-url-patterns.css | 25 ++++--- 4 files changed, 136 insertions(+), 39 deletions(-) diff --git a/cli/engine/browser/injected/index.mjs b/cli/engine/browser/injected/index.mjs index a9b9fd18a..91c5370b7 100644 --- a/cli/engine/browser/injected/index.mjs +++ b/cli/engine/browser/injected/index.mjs @@ -1277,23 +1277,67 @@ if (IS_BROWSER) { else groupMap.set(el, [...kept]); } + function selectorNodesForLiveDom(root, selector) { + const raw = String(selector || '').trim(); + if (!raw) return null; + try { + const exact = Array.from(root.querySelectorAll(raw)); + if (exact.length > 0) return exact; + } catch { /* Dynamic/unsupported pseudos get the fallback below. */ } + const fallback = raw + .replace(/::?[a-zA-Z-]+(\([^)]*\))?/g, '') + .trim() + .replace(/,\s*(?=,|$)/g, ''); + if (!fallback || /^[,\s]*$/.test(fallback)) return null; + try { return Array.from(root.querySelectorAll(fallback)); } + catch { return null; } + } + // Read CSS that is absent from document.outerHTML. Inline