/** * Anti-Pattern Browser Detector for Impeccable * Copyright (c) 2026 Paul Bakaus * * GENERATED -- do not edit. Source: crates/core/src/browser (rules, WASM) + * browser-bundle/*.js (DOM probe, overlay UI). * Rebuild: cargo xtask bundle * * Usage: * Re-scan: window.impeccableScan() */ (function () { if (typeof window === 'undefined') return; // --- browser-bundle/10-probe.js --- // The DOM probe the WASM rule core calls back into. Pure measurement: one // function per DOM API the rules read (see crates/core/src/browser/dom.rs for // the contract). Elements travel as handles (indexes into a registry; 0 is // null). Nothing in here decides anything about a design. const __els = [null]; let __ids = new WeakMap(); const __csCache = [null]; // Drop every handle (a new scan re-interns what it touches; JS keeps // Elements, never handles, across calls). function __resetRegistry() { __els.length = 1; __csCache.length = 1; __ids = new WeakMap(); } function __intern(el) { if (!el) return 0; let id = __ids.get(el); if (id === undefined) { id = __els.length; __els.push(el); __csCache.push(null); __ids.set(el, id); } return id; } function __el(id) { return __els[id] || null; } function __cs(id) { let cs = __csCache[id]; if (!cs) { cs = getComputedStyle(__els[id]); __csCache[id] = cs; } return cs; } function __ids_of(list) { const out = new Array(list.length); for (let i = 0; i < list.length; i++) out[i] = __intern(list[i]); return out; } const __SEL_ERR = 0xFFFFFFFF; function __rectArray(r) { return [r.x, r.y, r.width, r.height, r.top, r.right, r.bottom, r.left]; } const __impeccableDom = { document_element() { return __intern(document.documentElement); }, body() { return __intern(document.body); }, query_all(root, selector) { try { const scope = root ? __el(root) : document; return __ids_of(scope.querySelectorAll(selector)); } catch { return [__SEL_ERR]; } }, query_one(root, selector) { try { const scope = root ? __el(root) : document; return __intern(scope.querySelector(selector)); } catch { return __SEL_ERR; } }, inner_width() { return window.innerWidth; }, inner_height() { return window.innerHeight; }, scroll_x() { return window.scrollX; }, scroll_y() { return window.scrollY; }, hostname() { return location.hostname; }, element_from_point(x, y) { return __intern(document.elementFromPoint(x, y)); }, elements_from_point(x, y) { return typeof document.elementsFromPoint === 'function' ? __ids_of(document.elementsFromPoint(x, y)) : []; }, css_escape(s) { return CSS.escape(s); }, // JSON `[[["prop","value"],...], ...]` of the first @keyframes rule named // `name` (document.styleSheets order, nested rules walked breadth-first // exactly like keyframesToggleVisibilityDOM); undefined when none. keyframes(name) { if (!name) return undefined; for (const sheet of document.styleSheets) { let rules; try { rules = sheet.cssRules || sheet.rules; } catch { continue; } if (!rules) continue; const stack = [...rules]; while (stack.length) { const rule = stack.shift(); if (rule.cssRules && rule.type !== 7) { stack.push(...rule.cssRules); continue; } if (rule.type !== 7 || rule.name !== name) continue; const frames = []; for (const frame of rule.cssRules || []) { const fs = frame.style; if (!fs) continue; const decls = []; for (let i = 0; i < fs.length; i++) { const prop = fs[i]; decls.push([prop, fs.getPropertyValue(prop)]); } frames.push(decls); } return JSON.stringify(frames); } } return undefined; }, linked_stylesheet_text() { // The CSSOM walk lives in 15-snapshot.js so the standalone snapshot // producer carries it too; both routes read the same corpus. return __snapLinkedStylesheetText(); }, document_html_for_patterns() { const docClone = document.documentElement.cloneNode(true); for (const node of docClone.querySelectorAll('[id^="impeccable-live-"]')) node.remove(); return docClone.outerHTML; }, tag_name(el) { return __el(el).tagName; }, namespace_uri(el) { return __el(el).namespaceURI || ''; }, parent(el) { return __intern(__el(el).parentElement); }, children(el) { return __ids_of(__el(el).children); }, previous_element_sibling(el) { return __intern(__el(el).previousElementSibling); }, next_element_sibling(el) { return __intern(__el(el).nextElementSibling); }, contains(a, b) { return __el(a).contains(__el(b)); }, matches(el, selector) { try { return __el(el).matches(selector) ? 1 : 0; } catch { return __SEL_ERR; } }, closest(el, selector) { try { return __intern(__el(el).closest(selector)); } catch { return __SEL_ERR; } }, attr(el, name) { const v = __el(el).getAttribute(name); return v == null ? undefined : v; }, id_prop(el) { const v = __el(el).id; return typeof v === 'string' ? v : undefined; }, class_name_prop(el) { const v = __el(el).className; return typeof v === 'string' ? v : undefined; }, text_content(el) { return __el(el).textContent || ''; }, inner_text(el) { const v = __el(el).innerText; return typeof v === 'string' && v ? v : undefined; }, direct_text_nodes(el) { const out = []; for (const n of __el(el).childNodes) { if (n.nodeType === 3) out.push(n.textContent || ''); } return out; }, is_content_editable(el) { return !!__el(el).isContentEditable; }, hidden_prop(el) { return !!__el(el).hidden; }, style(el, prop) { const v = __cs(el)[prop]; return v == null ? '' : String(v); }, pseudo_style(el, pseudo, prop) { let ps; try { ps = getComputedStyle(__el(el), pseudo); } catch { return undefined; } if (!ps) return undefined; const v = ps[prop]; return v == null ? '' : String(v); }, rect(el) { const node = __el(el); if (typeof node.getBoundingClientRect !== 'function') return []; return __rectArray(node.getBoundingClientRect()); }, client_width(el) { return __el(el).clientWidth; }, client_height(el) { return __el(el).clientHeight; }, client_left(el) { return __el(el).clientLeft; }, scroll_width(el) { return __el(el).scrollWidth; }, scroll_left(el) { return __el(el).scrollLeft; }, offset_width(el) { return __el(el).offsetWidth; }, offset_height(el) { return __el(el).offsetHeight; }, check_visibility(el) { const node = __el(el); if (typeof node.checkVisibility !== 'function') return -1; return node.checkVisibility({ checkOpacity: false, checkVisibilityCSS: true }) ? 1 : 0; }, // getDirectTextRect(el) from the JS driver: union of the client rects of // the element's non-blank direct text nodes. direct_text_rect(el) { const node = __el(el); const rects = []; for (const child of node.childNodes) { if (child.nodeType !== 3 || !(child.textContent || '').trim()) continue; const range = document.createRange(); range.selectNodeContents(child); for (const rect of range.getClientRects()) { if (rect.width >= 1 && rect.height >= 1) rects.push(rect); } range.detach?.(); } if (rects.length === 0) return []; const left = Math.min(...rects.map(r => r.left)); const top = Math.min(...rects.map(r => r.top)); const right = Math.max(...rects.map(r => r.right)); const bottom = Math.max(...rects.map(r => r.bottom)); return [left, top, right - left, bottom - top, top, right, bottom, left]; }, }; // --- browser-bundle/15-snapshot.js --- // The page snapshot producer and the live-page IO the rules cannot do from // a snapshot. Pure measurement: what the probe in 10-probe.js reads on // demand, this reads once and serializes, so the WASM core can run where // the page's Content-Security-Policy keeps WebAssembly out (the extension's // offscreen document; see crates/core/src/browser/snapshot.rs for the // consumer and the field contract). Nothing in here decides anything about // a design: no thresholds, no rule names, no snippet strings. // // Exposed as `__impeccableSnapshot`: // capture(options) -> { json, elements, stats } | { error } // answer(needs, elements) -> facts for the core (`hitTests` -> `hits`) // idOf(el, elements) -> the element's snapshot id (0 when absent) // visualIO(elements) -> the IO half of the visual-contrast pass // (image loads, canvas pixel reads) over live // Elements, keyed by snapshot id // STYLE_PROPS / PSEUDO_PROPS / STATE_PSEUDOS (the capture contract) // Computed-style properties the rules read. Mirrors STYLE_PROPS in // crates/core/src/browser/snapshot.rs (cargo xtask bundle checks the two // lists agree). const __SNAP_STYLE_PROPS = [ "animationIterationCount", "animationName", "animationTimingFunction", "backdropFilter", "background", "backgroundClip", "backgroundColor", "backgroundImage", "backgroundPosition", "backgroundSize", "blockSize", "borderBottomColor", "borderBottomWidth", "borderBottomStyle", "borderLeftColor", "borderLeftWidth", "borderLeftStyle", "borderRadius", "borderRightColor", "borderRightWidth", "borderRightStyle", "borderTopColor", "borderTopWidth", "borderTopStyle", "bottom", "boxShadow", "clip", "clip-path", "clipPath", "color", "content", "contentVisibility", "cssFloat", "display", "filter", "float", "fontFamily", "fontSize", "fontStyle", "fontVariant", "fontVariantCaps", "fontWeight", "height", "hyphens", "inlineSize", "inset", "insetBlock", "insetBlockEnd", "insetBlockStart", "insetInline", "insetInlineEnd", "insetInlineStart", "left", "letterSpacing", "lineHeight", "marginBottom", "marginLeft", "marginRight", "marginTop", "maxHeight", "maxWidth", "minHeight", "minWidth", "mixBlendMode", "objectFit", "objectPosition", "opacity", "outline", "outlineColor", "outlineOffset", "outlineStyle", "outlineWidth", "overflow", "overflowX", "overflowY", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "pointerEvents", "position", "right", "textAlign", "textDecoration", "textDecorationLine", "textIndent", "textOverflow", "textShadow", "textTransform", "top", "transform", "transitionDuration", "transitionProperty", "transitionTimingFunction", "verticalAlign", "visibility", "webkitBackgroundClip", "webkitClipPath", "webkitHyphens", "webkitTextFillColor", "whiteSpace", "width", "wordBreak", "zIndex", ]; // `::before` / `::after` properties, recorded where `content` is set. const __SNAP_PSEUDO_PROPS = [ "content", "position", "opacity", "display", "width", "height", "top", "right", "bottom", "left", "backgroundColor", "backgroundImage", "background", "borderRadius", "transform", "visibility", ]; // Pseudo-class states recorded per element (`el.matches(':name')`), so the // snapshot selector engine can answer `:checked` / `:disabled` / ... the way // the live DOM would. Mirrors STATE_PSEUDOS in crates/core/src/browser/selector.rs. const __SNAP_STATE_PSEUDOS = [ "hover", "active", "focus", "focus-within", "focus-visible", "target", "target-within", "checked", "indeterminate", "disabled", "required", "invalid", "user-invalid", "user-valid", "in-range", "out-of-range", "placeholder-shown", "default", "open", "autofill", "-webkit-autofill", "popover-open", "modal", "fullscreen", "-webkit-full-screen", "picture-in-picture", "playing", "buffering", "seeking", "muted", "volume-locked", ]; const __SNAP_NS = { "http://www.w3.org/1999/xhtml": 0, "http://www.w3.org/2000/svg": 1, "http://www.w3.org/1998/Math/MathML": 2 }; const __SNAP_DEFAULT_MAX_ELEMENTS = 30000; const __SNAP_DEFAULT_MAX_BYTES = 48 * 1024 * 1024; function __snapRect4(r) { return [r.x, r.y, r.width, r.height]; } function __snapNum(v) { return typeof v === 'number' ? v : null; } // getDirectTextRect(el): union of the client rects of the element's // non-blank direct text nodes (same measure as 10-probe.js). function __snapDirectTextRect(node) { const rects = []; for (const child of node.childNodes) { if (child.nodeType !== 3 || !(child.textContent || '').trim()) continue; const range = document.createRange(); range.selectNodeContents(child); for (const rect of range.getClientRects()) { if (rect.width >= 1 && rect.height >= 1) rects.push(rect); } range.detach?.(); } if (rects.length === 0) return null; const left = Math.min(...rects.map(r => r.left)); const top = Math.min(...rects.map(r => r.top)); const right = Math.max(...rects.map(r => r.right)); const bottom = Math.max(...rects.map(r => r.bottom)); return [left, top, right - left, bottom - top]; } // ─── Linked stylesheet corpus (JS: injected/index.mjs #709) ──────────────── // JS: injected/index.mjs#pseudoElementHostSelector function __snapPseudoElementHostSelector(selector) { const raw = String(selector || ''); const legacyNames = new Set(['before', 'after', 'first-letter', 'first-line']); const isNameChar = char => /[a-zA-Z0-9_-]/.test(char || ''); const consumeFunction = (start) => { let depth = 0; let quote = ''; for (let i = start; i < raw.length; i += 1) { const char = raw[i]; if (char === '\\') { i += 1; continue; } if (quote) { if (char === quote) quote = ''; continue; } if (char === '"' || char === "'") { quote = char; continue; } if (char === '(') depth += 1; if (char === ')' && --depth === 0) return i + 1; } return raw.length; }; let output = ''; let found = false; for (let i = 0; i < raw.length;) { const char = raw[i]; if (char === '\\') { output += raw.slice(i, Math.min(raw.length, i + 2)); i += 2; continue; } if (char === '"' || char === "'") { const quote = char; const start = i; i += 1; while (i < raw.length) { if (raw[i] === '\\') { i += 2; continue; } const value = raw[i]; i += 1; if (value === quote) break; } output += raw.slice(start, i); continue; } if (char !== ':') { output += char; i += 1; continue; } let end = i + 1; let isPseudoElement = false; if (raw[end] === ':') { end += 1; const nameStart = end; while (isNameChar(raw[end])) end += 1; isPseudoElement = end > nameStart; } else { const nameStart = end; while (isNameChar(raw[end])) end += 1; isPseudoElement = legacyNames.has(raw.slice(nameStart, end).toLowerCase()); } if (!isPseudoElement) { output += char; i += 1; continue; } if (raw[end] === '(') end = consumeFunction(end); found = true; if (!output || /[\s>+~,]/.test(output[output.length - 1])) output += '*'; i = end; } if (!found) return null; return output.trim().replace(/,\s*(?=,|$)/g, ''); } // JS: injected/index.mjs#selectorNodesForLiveDom function __snapSelectorNodesForLiveDom(root, selector) { const raw = String(selector || '').trim(); if (!raw) return null; const fallback = __snapPseudoElementHostSelector(raw); if (fallback == null) { // An empty result from a valid full selector is authoritative. In // particular, do not broaden inactive :hover/:focus/:not() rules to // their host element by stripping pseudo-classes. try { return Array.from(root.querySelectorAll(raw)); } catch { return null; } } // 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 > *`). if (!fallback || /^[,\s]*$/.test(fallback)) return null; try { return Array.from(root.querySelectorAll(fallback)); } catch { return null; } } let __snapContainerProbeSequence = 0; function __snapIsContainerCssRule(rule) { return rule?.constructor?.name === 'CSSContainerRule' || /^\s*@container\b/i.test(rule?.cssText || ''); } function __snapStyleRuleAppliesToLiveMatches(rule, matches) { const style = rule?.style; if (!style || !matches?.length || typeof getComputedStyle !== 'function') return false; const sequence = ++__snapContainerProbeSequence; const property = `--impeccable-container-probe-${sequence}-${Math.random().toString(36).slice(2)}`; const value = `impeccable-container-active-${sequence}`; const previousValue = style.getPropertyValue(property); const previousPriority = style.getPropertyPriority(property); try { style.setProperty(property, value, 'important'); } catch { return false; } const pseudoElements = [...new Set( String(rule.selectorText || '').match(/::[a-zA-Z-]+(?:\([^)]*\))?/g) || [], )]; try { return matches.some(el => [null, ...pseudoElements].some(pseudo => { try { const computed = pseudo ? getComputedStyle(el, pseudo) : getComputedStyle(el); return computed.getPropertyValue(property).trim() === value; } catch { return false; } })); } finally { if (previousValue) style.setProperty(property, previousValue, previousPriority); else style.removeProperty(property); } } function __snapConditionalCssRuleIsActive(rule) { const type = Number(rule?.type); const constructorName = rule?.constructor?.name || ''; if (constructorName === 'CSSMediaRule' || type === 4) { const condition = rule.conditionText || rule.media?.mediaText || ''; if (!condition || typeof window.matchMedia !== 'function') return true; try { return window.matchMedia(condition).matches; } catch { return true; } } if (constructorName === 'CSSSupportsRule' || type === 12) { const condition = rule.conditionText || ''; if (!condition || typeof CSS === 'undefined' || typeof CSS.supports !== 'function') return true; try { return CSS.supports(condition); } catch { return true; } } return true; } function __snapSplitCssCommaList(value) { const parts = []; let current = ''; let quote = ''; let escaped = false; for (const char of String(value || '')) { if (escaped) { current += char; escaped = false; continue; } if (char === '\\') { current += char; escaped = true; continue; } if (quote) { current += char; if (char === quote) quote = ''; continue; } if (char === '"' || char === "'") { quote = char; current += char; continue; } if (char === ',') { parts.push(current); current = ''; continue; } current += char; } parts.push(current); return parts; } function __snapNormalizeAnimationName(value) { const name = String(value || '').trim(); if (name.length >= 2 && name[0] === name[name.length - 1] && (name[0] === '"' || name[0] === "'")) { return name.slice(1, -1); } return name; } function __snapAnimationNamesDeclaredByRule(rule) { const style = rule?.style; if (!style) return []; let value = ''; try { value = style.animationName || style.getPropertyValue?.('animation-name') || style.webkitAnimationName || style.getPropertyValue?.('-webkit-animation-name') || ''; } catch { return []; } return __snapSplitCssCommaList(value) .map(__snapNormalizeAnimationName) .filter(name => name && name.toLowerCase() !== 'none'); } function __snapKeyframesRuleName(rule, cssText) { const constructorName = rule?.constructor?.name || ''; const type = Number(rule?.type); const isKeyframes = constructorName === 'CSSKeyframesRule' || constructorName === 'WebKitCSSKeyframesRule' || type === 7 || /^\s*@(?:-webkit-)?keyframes\b/i.test(cssText); if (!isKeyframes) return ''; const match = String(cssText || '').match(/^\s*@(?:-webkit-)?keyframes\s+([^\s{]+)/i); return __snapNormalizeAnimationName(rule?.name || match?.[1] || ''); } function __snapCssPropertyName(property) { if (property.startsWith('--')) return property; return property.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`); } function __snapResolvedAnimationKeyframes(candidateNames) { if (typeof document.getAnimations !== 'function') return null; let animations; try { animations = document.getAnimations(); } catch { return null; } const resolved = new Map(); const metadata = new Set(['offset', 'computedOffset', 'easing', 'composite']); for (const animation of animations) { const name = __snapNormalizeAnimationName(animation?.animationName || ''); if (!name || !candidateNames.has(name) || resolved.has(name)) continue; let frames; try { frames = animation.effect?.getKeyframes?.() || []; } catch { continue; } const blocks = []; for (const frame of frames) { const rawOffset = Number.isFinite(frame.computedOffset) ? frame.computedOffset : frame.offset; if (!Number.isFinite(rawOffset)) continue; const offset = Math.round(rawOffset * 1000000) / 10000; const declarations = Object.entries(frame) .filter(([property, value]) => !metadata.has(property) && value != null && value !== '') .map(([property, value]) => `${__snapCssPropertyName(property)}: ${value};`); const easing = String(frame.easing || '').trim(); if (easing && easing.toLowerCase() !== 'linear') { declarations.push(`animation-timing-function: ${easing};`); } if (declarations.length === 0) continue; blocks.push(`${offset}% { ${declarations.join(' ')} }`); } if (blocks.length > 0) resolved.set(name, `@keyframes ${name} { ${blocks.join(' ')} }`); } return resolved; } // Read CSS that is absent from document.outerHTML. Inline