(function () { var mask = document.getElementById("loginDialog"); if (!mask) return; var form = mask.querySelector("[data-login-dialog-form]"); var accountInput = mask.querySelector("[data-login-account]"); var passwordInput = mask.querySelector("[data-login-password]"); var submitBtn = mask.querySelector("[data-login-submit]"); var defaultSubmitText = (submitBtn && submitBtn.textContent) || "登录"; function setSubmitting(loading) { if (!submitBtn) return; submitBtn.disabled = !!loading; submitBtn.classList.toggle("is-loading", !!loading); submitBtn.setAttribute("aria-busy", loading ? "true" : "false"); submitBtn.textContent = loading ? "登录中..." : defaultSubmitText; } function getField(name) { return mask.querySelector('[data-login-field="' + name + '"]'); } function setFieldError(name, message) { var field = getField(name); if (!field) return; var control = field.querySelector("[data-login-control]"); var error = field.querySelector("[data-login-error]"); if (control) control.classList.add("is-error"); if (error) { error.textContent = message; error.hidden = false; } } function clearFieldError(name) { var field = getField(name); if (!field) return; var control = field.querySelector("[data-login-control]"); var error = field.querySelector("[data-login-error]"); if (control) control.classList.remove("is-error"); if (error) error.hidden = true; } function clearAllErrors() { clearFieldError("account"); clearFieldError("password"); } function isValidLength(value) { return value.length >= 4 && value.length <= 16; } function validateForm() { var account = (accountInput && accountInput.value.trim()) || ""; var password = (passwordInput && passwordInput.value) || ""; var valid = true; clearAllErrors(); if (!account) { setFieldError("account", "账号格式不正确,请输入有效账号"); valid = false; } else if (!window.AuthAPI || !AuthAPI.isValidLoginAccount(account)) { setFieldError("account", "账号格式不正确,请输入有效账号"); valid = false; } if (!password) { setFieldError("password", "密码错误,请检查后重新输入"); valid = false; } else if (!isValidLength(password)) { setFieldError("password", "密码错误,请检查后重新输入"); valid = false; } if (!valid) return null; return { account: account, password: password }; } function mapServerError(err) { var tip = (err && err.message) || "登录失败,请稍后重试"; if (/密码|password/i.test(tip)) { setFieldError("password", tip); return; } if (/账号|账户|用户|邮箱|account|email|不存在|错误/i.test(tip)) { setFieldError("account", tip); return; } if (window.AuthAPI) AuthAPI.toast(tip, "error"); else if (typeof showToast === "function") showToast(tip, "error"); } function openDialog(event) { if (event) event.preventDefault(); if (typeof window.closeRegisterDialog === "function") { window.closeRegisterDialog(); } clearAllErrors(); mask.classList.add("is-open"); document.body.style.overflow = "hidden"; return true; } function closeDialog() { mask.classList.remove("is-open"); clearAllErrors(); if (!document.getElementById("registerDialog") || !document.getElementById("registerDialog").classList.contains("is-open")) { document.body.style.overflow = ""; } } function setLoginErrors(errors) { clearAllErrors(); if (!errors) return; if (errors.account) setFieldError("account", errors.account); if (errors.password) setFieldError("password", errors.password); } if (form) { form.addEventListener("submit", function (event) { event.preventDefault(); if (submitBtn && submitBtn.classList.contains("is-loading")) return; var payload = validateForm(); if (!payload) return; if (!window.AuthAPI || !window.HttpRequest) { return; } setSubmitting(true); AuthAPI.login(payload) .then(function () { AuthAPI.toast("登录成功", "success"); closeDialog(); setTimeout(function () { goAfterAuth(); }, 400); }) .catch(function (err) { setSubmitting(false); mapServerError(err); }); }); } function isSafeRedirect(path) { return typeof path === "string" && path.charAt(0) === "/" && path.charAt(1) !== "/"; } function goAfterAuth() { var bodyRedirect = document.body && document.body.getAttribute("data-auth-redirect"); if (isSafeRedirect(bodyRedirect)) { window.location.href = bodyRedirect; return; } var params = new URLSearchParams(window.location.search); var redirect = params.get("redirect"); if (isSafeRedirect(redirect)) { window.location.href = redirect; return; } window.location.reload(); } function consumeAuthQuery(kind) { var params = new URLSearchParams(window.location.search); if (params.get("auth") !== kind) return false; params.delete("auth"); var qs = params.toString(); var next = window.location.pathname + (qs ? "?" + qs : "") + window.location.hash; window.history.replaceState(null, "", next); return true; } if (accountInput) { accountInput.addEventListener("input", function () { clearFieldError("account"); }); } if (passwordInput) { passwordInput.addEventListener("input", function () { clearFieldError("password"); }); } document.addEventListener("click", function (event) { var openEl = event.target.closest("[data-login-dialog-open]"); if (openEl) { openDialog(event); return; } var loginLink = event.target.closest('a[href="/login/"], a[href="#login"]'); if (loginLink) { openDialog(event); return; } if (event.target.closest("[data-login-dialog-close]")) { closeDialog(); return; } if (event.target.closest("[data-login-dialog-eye]")) { var btn = event.target.closest("[data-login-dialog-eye]"); var input = document.getElementById("loginDialogPassword"); var img = btn.querySelector("img"); if (!input || !img) return; var show = input.type === "password"; input.type = show ? "text" : "password"; img.src = show ? "/static/images/eye_open.svg" : "/static/images/eye_close.svg"; btn.setAttribute("aria-label", show ? "隐藏密码" : "显示密码"); return; } if (event.target === mask) { closeDialog(); } }); document.addEventListener("keydown", function (event) { if (event.key === "Escape" && mask.classList.contains("is-open")) { closeDialog(); } }); window.openLoginDialog = openDialog; window.closeLoginDialog = closeDialog; window.setLoginDialogErrors = setLoginErrors; if ((document.body && document.body.getAttribute("data-auth-mode") === "login") || consumeAuthQuery("login")) { openDialog(); } })();