fix: autofill login first then password, continuous re-fill for SPA re-renders

This commit is contained in:
2026-05-05 11:05:09 +00:00
parent f994674327
commit 2edb804660
+25 -18
View File
@@ -30,8 +30,6 @@ _lock = threading.Lock()
_AUTOFILL_CONTENT_JS = r""" _AUTOFILL_CONTENT_JS = r"""
(function() { (function() {
const CREDS = __CREDS__; const CREDS = __CREDS__;
let userFilled = false;
let passFilled = false;
console.log('[PortalAutofill] loaded for', location.href); console.log('[PortalAutofill] loaded for', location.href);
function isVisible(el) { function isVisible(el) {
@@ -112,23 +110,27 @@ _AUTOFILL_CONTENT_JS = r"""
} }
function tryFill() { function tryFill() {
if (userFilled && passFilled) return;
const p = findPassField(); const p = findPassField();
const u = findUserField(p); const u = findUserField(p);
if (CREDS.password && p && !passFilled) { // Fill login FIRST so password-triggered re-render doesn't clear it
if (setNativeValue(p, CREDS.password)) { if (CREDS.login && u) {
passFilled = true;
console.log('[PortalAutofill] password filled');
}
}
if (CREDS.login && u && !userFilled) {
if (setNativeValue(u, CREDS.login)) { if (setNativeValue(u, CREDS.login)) {
userFilled = true;
console.log('[PortalAutofill] user filled'); console.log('[PortalAutofill] user filled');
} }
} }
if (!CREDS.login) userFilled = true; if (CREDS.password && p) {
if (!CREDS.password) passFilled = true; if (setNativeValue(p, CREDS.password)) {
console.log('[PortalAutofill] password filled');
}
}
}
// Watch for SPA re-renders clearing the fields and re-fill continuously
let _filling = false;
function scheduleFill() {
if (_filling) return;
_filling = true;
requestAnimationFrame(() => { tryFill(); _filling = false; });
} }
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
@@ -137,17 +139,22 @@ _AUTOFILL_CONTENT_JS = r"""
tryFill(); tryFill();
} }
const obs = new MutationObserver(() => { // Periodic check for first 30s in case of async SPA resets
if (!(userFilled && passFilled)) tryFill(); let _checks = 0;
}); const _interval = setInterval(() => {
tryFill();
if (++_checks >= 30) clearInterval(_interval);
}, 1000);
const obs = new MutationObserver(scheduleFill);
if (document.documentElement) { if (document.documentElement) {
obs.observe(document.documentElement, { childList: true, subtree: true }); obs.observe(document.documentElement, { childList: true, subtree: true });
} }
const resetAndRefill = () => { const resetAndRefill = () => {
userFilled = !CREDS.login; _checks = 0;
passFilled = !CREDS.password;
setTimeout(tryFill, 150); setTimeout(tryFill, 150);
setTimeout(tryFill, 600);
}; };
['pushState', 'replaceState'].forEach(fn => { ['pushState', 'replaceState'].forEach(fn => {
const orig = history[fn]; const orig = history[fn];