// Content Script for Smart Survey Filler // Injects the Floating Bubble UI and handles page analysis and auto-filling (function() { // Prevent multiple injections if (window.ssfInjected) return; window.ssfInjected = true; console.log('Smart Survey Filler content script active'); // --- UI CONSTRUCTION --- const bubble = document.createElement('div'); bubble.id = 'ssf-floating-bubble'; bubble.title = "Smart Survey Filler"; bubble.innerHTML = `
🤖
`; const style = document.createElement('style'); style.textContent = ` #ssf-floating-bubble { position: fixed; bottom: 30px; right: 30px; width: 60px; height: 60px; background: linear-gradient(135deg, #4A90E2, #357ABD); border-radius: 50%; box-shadow: 0 4px 15px rgba(0,0,0,0.3); cursor: pointer; z-index: 2147483647; display: flex; align-items: center; justify-content: center; transition: transform 0.2s; user-select: none; color: white; font-size: 30px; } #ssf-floating-bubble:hover { transform: scale(1.05); } .ssf-menu { position: absolute; bottom: 75px; right: 0; width: 260px; background: white; border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); padding: 15px; display: flex; flex-direction: column; gap: 8px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; cursor: default; text-align: left; color: #333; font-size: 14px; border: 1px solid #eee; } .ssf-menu-header { font-weight: bold; border-bottom: 1px solid #eee; padding-bottom: 8px; margin-bottom: 5px; display: flex; justify-content: space-between; align-items: center; font-size: 16px; } .ssf-close-btn { cursor: pointer; color: #999; font-size: 20px; line-height: 1; } .ssf-close-btn:hover { color: #333; } #ssf-persona-select { width: 100%; padding: 8px; border-radius: 6px; border: 1px solid #ddd; background: #fafafa; } #ssf-btn-fill { background: #4A90E2; color: white; border: none; padding: 10px; border-radius: 6px; cursor: pointer; font-weight: 600; margin-top: 5px; transition: background 0.2s; } #ssf-btn-fill:hover { background: #357ABD; } #ssf-btn-fill:disabled { background: #ccc; cursor: not-allowed; } #ssf-status { font-size: 12px; margin-top: 5px; color: #666; text-align: center; min-height: 1.2em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } `; document.head.appendChild(style); document.body.appendChild(bubble); // --- EVENT HANDLERS --- const menu = bubble.querySelector('.ssf-menu'); const closeBtn = bubble.querySelector('.ssf-close-btn'); const select = document.getElementById('ssf-persona-select'); const fillBtn = document.getElementById('ssf-btn-fill'); const status = document.getElementById('ssf-status'); // Toggle Menu bubble.addEventListener('click', (e) => { if (e.target.closest('.ssf-menu')) return; // Don't close if clicking inside menu // Only toggle if not dragging if (!isDragging) { const isHidden = menu.style.display === 'none'; menu.style.display = isHidden ? 'flex' : 'none'; if (isHidden) loadPersonas(); } }); closeBtn.addEventListener('click', (e) => { e.stopPropagation(); menu.style.display = 'none'; }); // Load Personas function loadPersonas() { status.innerText = 'Loading profiles...'; select.innerHTML = ''; select.disabled = true; fillBtn.disabled = true; chrome.runtime.sendMessage({ type: 'FETCH_PERSONAS' }, (response) => { select.disabled = false; fillBtn.disabled = false; if (chrome.runtime.lastError) { status.innerText = 'Error: Check Extension Settings'; select.innerHTML = ''; return; } if (response && response.success && response.data && response.data.length > 0) { status.innerText = 'Ready'; select.innerHTML = response.data.map(p => ``).join(''); } else if (response && !response.success) { status.innerText = response.error || 'Connection Error'; select.innerHTML = ''; } else { status.innerText = 'No profiles found'; select.innerHTML = ''; } }); } // Fill Button Logic fillBtn.addEventListener('click', async (e) => { e.stopPropagation(); const personaId = select.value; if (!personaId) { status.innerText = 'Please select a persona first!'; return; } status.innerText = 'Scanning page...'; fillBtn.disabled = true; // 1. Map Inputs to Questions const fields = []; // Expanded selector for more input types const inputs = document.querySelectorAll('input:not([type="hidden"]):not([type="submit"]):not([type="button"]), textarea, select'); inputs.forEach((input, i) => { // Logic to find label: // 1. Explicit