102 lines
3.7 KiB
JavaScript
102 lines
3.7 KiB
JavaScript
// 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!`;
|
|
})();
|