
INTERACTIVE_ROLES = {
    "button", "checkbox", "combobox", "link", "listbox", "menuitem", 
    "menuitemcheckbox", "menuitemradio", "option", "radio", "searchbox", 
    "slider", "spinbutton", "switch", "tab", "textbox", "treeitem"
}

CONTENT_ROLES = {
    "heading", "main", "navigation", "region", "search"
}

LANDMARKS = {"main", "navigation", "region", "search", "form", "heading"}

JS_A11Y_EXTRACTOR = """
() => {
    const INTERACTIVE_ROLES = new Set([
      "button", "link", "checkbox", "menuitem", "option", "radio", "switch", "tab", 
      "treeitem", "textbox", "searchbox", "spinbutton", "combobox", "listbox", "slider"
    ]);
    const results = [];
    
    const isVisible = (el) => {
        if (!el.getClientRects().length) return false;
        const style = window.getComputedStyle(el);
        if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false;
        if (style.pointerEvents === 'none') return false;
        return true;
    };

    const walk = (node) => {
        if (node.nodeType !== 1 || !isVisible(node)) return;

        const rect = node.getBoundingClientRect();
        if (rect.width < 2 || rect.height < 2) return;

        const style = window.getComputedStyle(node);
        const tagName = node.tagName;
        const role = (node.getAttribute('role') || '').toLowerCase();
        const isInput = ['INPUT', 'TEXTAREA', 'SELECT'].includes(tagName);
        const isButtonOrLink = tagName === 'BUTTON' || tagName === 'A' || style.cursor === 'pointer';
        const isInteractive = INTERACTIVE_ROLES.has(role) || isInput || isButtonOrLink;
        
        if (isInteractive) {
            const innerText = node.innerText || "";
            const name = node.getAttribute('aria-label') || node.placeholder || innerText.substring(0, 50).trim() || node.value || tagName;
            results.push({
                tagName: tagName,
                role: role || tagName.toLowerCase(),
                name: (name || "").substring(0, 100).trim(),
                placeholder: node.placeholder || '',
                rect: {
                    x: Math.round(rect.x), y: Math.round(rect.y),
                    width: Math.round(rect.width), height: Math.round(rect.height)
                }
            });
        }
        
        for (const child of node.children) walk(child);
    };
    walk(document.body);
    return results;
}
"""
