// 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