From ae477583665674b73d55caf4ce3aa72d8594486d Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Tue, 17 Mar 2026 16:04:12 -0700 Subject: [PATCH] =?UTF-8?q?Fix=20browser=20nested=20card=20dedup=20?= =?UTF-8?q?=E2=80=94=20use=20WeakSet=20like=20CLI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same bug as the CLI had: Set with tag-name key ('DIV:DIV') deduped all nested divs to one finding. Now uses WeakSet on actual elements so each nested card instance gets its own outline. Co-Authored-By: Claude Opus 4.6 (1M context) --- public/js/detect-antipatterns-browser.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/public/js/detect-antipatterns-browser.js b/public/js/detect-antipatterns-browser.js index 64c729973..b6d31f9aa 100644 --- a/public/js/detect-antipatterns-browser.js +++ b/public/js/detect-antipatterns-browser.js @@ -291,16 +291,13 @@ const findings = []; // --- Nested cards --- - const flaggedPairs = new Set(); + const flaggedEls = new WeakSet(); for (const el of document.querySelectorAll('*')) { - if (!isCardLike(el)) continue; - const tag = el.tagName.toLowerCase(); + if (!isCardLike(el) || flaggedEls.has(el)) continue; const cls = el.getAttribute('class') || ''; const style = getComputedStyle(el); - // Exclude dropdowns, modals, tooltips if (style.position === 'absolute' || style.position === 'fixed') continue; if (/\b(?:dropdown|popover|tooltip|menu|modal|dialog)\b/i.test(cls)) continue; - // Exclude tiny elements (badges, chips) if ((el.textContent?.trim().length || 0) < 20) continue; const rect = el.getBoundingClientRect(); if (rect.width < 50 || rect.height < 30) continue; @@ -308,11 +305,8 @@ let parent = el.parentElement; while (parent) { if (isCardLike(parent)) { - const key = el.tagName + ':' + parent.tagName; - if (!flaggedPairs.has(key)) { - flaggedPairs.add(key); - findings.push({ type: 'nested-cards', detail: `Card inside card`, el }); - } + flaggedEls.add(el); + findings.push({ type: 'nested-cards', detail: `Card inside card`, el }); break; } parent = parent.parentElement;