(function () { "use strict"; var cfg = null; var filledKeys = {}; var startedAt = Date.now(); var MAX_MS = 120000; function loadConfig(cb) { try { var rt = typeof browser !== "undefined" ? browser : chrome; var url = rt.runtime.getURL("autofill_config.json"); fetch(url, { cache: "no-store" }) .then(function (r) { return r.json(); }) .then(function (j) { cb(j || null); }) .catch(function () { cb(null); }); } catch (e) { cb(null); } } function hostMatches(host, patterns) { if (!patterns || !patterns.length) return true; host = (host || "").toLowerCase(); for (var i = 0; i < patterns.length; i++) { var p = String(patterns[i] || "").toLowerCase(); if (!p) continue; if (p.indexOf("*") >= 0) { var re = new RegExp("^" + p.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$"); if (re.test(host)) return true; } else if (host === p || host.endsWith("." + p)) { return true; } } return false; } function setValue(el, value) { if (!el || value == null || value === "") return false; try { el.focus(); el.value = value; el.dispatchEvent(new Event("input", { bubbles: true })); el.dispatchEvent(new Event("change", { bubbles: true })); return true; } catch (e) { return false; } } function trySelectors(selectors, value) { if (!selectors || !value) return false; for (var i = 0; i < selectors.length; i++) { var nodes = document.querySelectorAll(selectors[i]); for (var j = 0; j < nodes.length; j++) { var el = nodes[j]; if (!el || el.disabled || el.readOnly) continue; if (el.type === "hidden") continue; if (setValue(el, value)) return true; } } return false; } function runFill() { if (!cfg || !cfg.fields) return; if (Date.now() - startedAt > MAX_MS) return; var host = location.hostname || ""; if (cfg.hosts && cfg.hosts.length && !hostMatches(host, cfg.hosts)) return; var fields = cfg.fields; var keys = Object.keys(fields); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var val = fields[key]; if (!val) continue; if (filledKeys[key]) continue; if (trySelectors(fields[key + "_selectors"] || defaultSelectors(key), val)) { filledKeys[key] = true; } } } function defaultSelectors(key) { var map = { email: [ 'input[type="email"]', 'input[name="email"]', 'input[name="Email"]', 'input[id="email"]', 'input[autocomplete="email"]', 'input[autocomplete="username"]', 'input[name="identifier"]' ], password: [ 'input[type="password"]:not([name*="Confirm"]):not([name*="confirm"]):not([name*="Again"]):not([name*="again"])', 'input[name="password"]', 'input[name="Passwd"]', 'input[id="password"]', 'input[autocomplete="new-password"]' ], password_confirm: [ 'input[name="PasswdAgain"]', 'input[name="password_confirm"]', 'input[name="confirmPassword"]', 'input[name="passwordConfirmation"]', 'input[autocomplete="new-password"]:nth-of-type(2)' ], first_name: [ 'input[name="firstName"]', 'input[name="firstname"]', 'input[name="first_name"]', 'input[autocomplete="given-name"]' ], last_name: [ 'input[name="lastName"]', 'input[name="lastname"]', 'input[name="last_name"]', 'input[autocomplete="family-name"]' ], username: [ 'input[name="username"]', 'input[name="Username"]', 'input[id="username"]', 'input[autocomplete="username"]' ] }; return map[key] || []; } function boot() { loadConfig(function (j) { cfg = j; if (!cfg) return; runFill(); var obs = new MutationObserver(function () { runFill(); }); obs.observe(document.documentElement || document.body, { childList: true, subtree: true }); var timer = setInterval(function () { runFill(); if (Date.now() - startedAt > MAX_MS) clearInterval(timer); }, 900); }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } })();