// filler.js — Script executed on the active tab to auto-fill form fields. (function() { // Retrieve the profile data passed from the popup/scripting context const profile = window.__autofillProfileData; if (!profile) { console.error("Autofill profile data not found."); return "Error: Profile data not found"; } console.log("Starting auto-fill with profile:", profile); // Helper to find associated label text for an input function getLabelText(input) { let labelText = ""; // 1. Check aria-label or placeholder if (input.getAttribute("aria-label")) { labelText += " " + input.getAttribute("aria-label"); } if (input.getAttribute("placeholder")) { labelText += " " + input.getAttribute("placeholder"); } if (input.getAttribute("id")) { const label = document.querySelector(`label[for="${input.getAttribute("id")}"]`); if (label) { labelText += " " + label.innerText; } } // 2. Check parent label let parent = input.parentElement; while (parent && parent !== document.body) { if (parent.tagName === "LABEL") { labelText += " " + parent.innerText; break; } parent = parent.parentElement; } // 3. Check name or id attributes if (input.name) labelText += " " + input.name; if (input.id) labelText += " " + input.id; return labelText.toLowerCase(); } // Find all input, textarea, and select elements const inputs = document.querySelectorAll("input, textarea, select"); let filledCount = 0; inputs.forEach(input => { // Skip hidden or read-only elements if (input.type === "hidden" || input.disabled || input.readOnly) return; const label = getLabelText(input); let valToSet = null; // Matching logic based on common field names if (label.includes("email") || label.includes("mail")) { valToSet = profile.email; } else if (label.includes("phone") || label.includes("tel") || label.includes("mobile") || label.includes("contact")) { valToSet = profile.phone; } else if (label.includes("linkedin")) { valToSet = profile.linkedin; } else if (label.includes("github")) { valToSet = profile.github; } else if (label.includes("first name") || label.includes("firstname")) { valToSet = profile.firstName; } else if (label.includes("last name") || label.includes("lastname")) { valToSet = profile.lastName; } else if (label.includes("full name") || label.includes("fullname") || (label.includes("name") && !label.includes("company") && !label.includes("school") && !label.includes("employer"))) { valToSet = profile.fullName; } else if (label.includes("website") || label.includes("portfolio") || label.includes("personal link")) { valToSet = profile.portfolio || profile.linkedin; } else if (label.includes("cover letter") || label.includes("describe") || label.includes("introduce yourself")) { valToSet = profile.summary || ""; } if (valToSet !== null && valToSet !== undefined) { // Set the value input.value = valToSet; // Highlight the filled field briefly const originalBg = input.style.backgroundColor; input.style.backgroundColor = "rgba(0, 214, 126, 0.2)"; input.style.transition = "background-color 0.5s ease"; setTimeout(() => { input.style.backgroundColor = originalBg; }, 1500); // Trigger change/input events so any framework (React/Angular/Vue) registers the value input.dispatchEvent(new Event("input", { bubbles: true })); input.dispatchEvent(new Event("change", { bubbles: true })); filledCount++; } }); return `Filled ${filledCount} fields successfully!`; })();