feat(auth): rebuild the sign-in surfaces on the shared sign-card contract
The login/register page and the auth modal had drifted into a parallel system: floating-input fields, a sign-page-card shell and a bespoke jio-auth-modal wrapper that none of the theme's own sign CSS targeted. The reference card rules (.sign, .sign-img, .sign-content, .line-form-input, .scale-placeholder, .social_loginbar, .title-h-left, #u_sign .modal-dialog, .qrcode-signin-container) have been in main.css all along, so the fix is to render the reference DOM instead of re-styling a second one. auth-content.php now emits one .sign.jio-panel.blur-bg.relative card with a .tab-content of #tab-sign-in / #tab-sign-up / #tab-resetpassword / #tab-qrcode-signin / #tab-bind panes. Each pane opens with a .title-h-left.fa-2x heading plus a .muted-color.px12 link, fields are .relative.line-form.mb10 > .line-form-input + .scale-placeholder + .line-form-line, the verification trigger is the .yztx.abs-right captchsubmit button, and submits are .but.radius.jb-blue|jb-green.padding-lg.btn-block. Social entries come from the shared render_social_buttons() separator + .social_loginbar, and the OAuth bind pane uses the oauth-data-box avatar card. The modal shell is #u_sign.modal > .modal-dialog > .sign-content > .sign-img.absolute.hide-sm + .sign, and the page shell is the reference .container.sign-page > .row.sign-row.gutters-5 > .col-md-6(.col-md-offset-6/ .col-md-offset-3).sign-col with a .fixed.lazyload background and a blurred fixed footer. auth.js drives .in instead of .is-open, toggles the new password/signin-mode/invite-gate controls and no longer touches the retired markup. The page also drops two footer-hook removals that targeted functions which no longer exist, and opts out of the fixed-nav offset. The sign page's custom theme setting now actually applies: Router answers jio_forced_theme_mode, jioData.themeForced wins over the stored cookie in theme.js, theme-toggle positions are suppressed, and the page marks html/body dark or white accordingly. sign.css shrinks from ~114 lines of bespoke component styling to a thin positioning layer, and the retired classes are gone rather than kept. Verification: php -l on every changed PHP file, node --check on both JS files, node --test across widget-system, navigation and front-submit (873 passing), and tools/audit-psr4-paths.php / audit-admin-contracts.php both at 0 errors. assets/js/runtime/main.min.js was rebuilt because theme.js gained the forced theme branch.
This commit is contained in:
1 parent
d40906b4a3
commit
41366e7fc4
15 files changed
+664
-281
No files matched your search
+136
-102
@@ -1,114 +1,148 @@
|
||||
/* Shared authentication contract: modal and /sign/. */
|
||||
.sign {
|
||||
max-width: 330px;
|
||||
margin: auto;
|
||||
padding: 30px 0;
|
||||
color: var(--main-color, #4e5358);
|
||||
/* Authentication surfaces: modal (#u_sign) and the /sign/ page.
|
||||
*
|
||||
* Card, line inputs, tab panes, social bar and title rules come from the shared
|
||||
* theme stylesheet; this file only positions the shells around them.
|
||||
*/
|
||||
#u_sign.jio-auth-modal {
|
||||
z-index: 100050;
|
||||
}
|
||||
|
||||
.sign [hidden] { display: none !important; }
|
||||
.sign button { font: inherit; }
|
||||
.sign-logo { margin-bottom: 24px; text-align: center; }
|
||||
.sign-logo img { max-width: 180px; max-height: 70px; }
|
||||
.sign-logo .sign-logo-dark { display: none; }
|
||||
.dark-theme .sign-logo .sign-logo-light { display: none; }
|
||||
.dark-theme .sign-logo .sign-logo-dark { display: inline-block; }
|
||||
.sign-logo__text { font-size: 22px; font-weight: 700; color: inherit; }
|
||||
.sign-panel { animation: auth-panel-in .24s ease both; }
|
||||
|
||||
@keyframes auth-panel-in {
|
||||
from { opacity: 0; transform: translateY(5px); }
|
||||
to { opacity: 1; transform: none; }
|
||||
#u_sign.jio-auth-modal.in {
|
||||
display: block;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.sign-header { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 23px; }
|
||||
.sign-header h2 { margin: 0; font-size: 22px; line-height: 1.4; color: var(--key-color, #333); }
|
||||
.sign-header span { font-size: 12px; color: var(--muted-2-color, #999); }
|
||||
.sign-header button,
|
||||
.sign-options button,
|
||||
.sign-mode-switch { padding: 0; border: 0; background: none; color: var(--focus-color, #f04494); cursor: pointer; }
|
||||
.sign-form { display: grid; gap: 17px; }
|
||||
#u_sign.jio-auth-modal .modal-dialog {
|
||||
opacity: 0;
|
||||
transform: translateY(-12px);
|
||||
transition: opacity 0.2s ease, transform 0.25s ease;
|
||||
}
|
||||
|
||||
.floating-input { position: relative; min-height: 42px; border-bottom: 1px solid var(--main-border-color, rgba(50, 50, 50, .12)); }
|
||||
.floating-input::after { content: ""; position: absolute; right: 0; bottom: -1px; left: 0; height: 2px; background: var(--focus-color, #f04494); transform: scaleX(0); transition: transform .25s; }
|
||||
.floating-input:focus-within::after { transform: scaleX(1); }
|
||||
.floating-input input { width: 100%; height: 42px; padding: 13px 4px 2px; border: 0; outline: 0; background: transparent; color: inherit; font-size: 14px; box-shadow: none !important; }
|
||||
.floating-input label { position: absolute; top: 12px; left: 4px; color: var(--muted-color, #777); font-size: 14px; font-weight: 400; pointer-events: none; transition: all .18s; }
|
||||
.floating-input input:focus + label,
|
||||
.floating-input input:not(:placeholder-shown) + label,
|
||||
.floating-input.is-filled label { top: 0; font-size: 10px; color: var(--focus-color, #f04494); }
|
||||
.floating-input.has-action input { padding-right: 94px; }
|
||||
.floating-input .password-show,
|
||||
.floating-input .send-code { position: absolute; right: 0; bottom: 6px; z-index: 2; border: 0; background: none; color: var(--muted-2-color, #999); cursor: pointer; }
|
||||
.floating-input .send-code { color: var(--focus-color, #f04494); font-size: 12px; }
|
||||
.floating-input .send-code:disabled { color: var(--muted-2-color, #999); cursor: default; }
|
||||
#u_sign.jio-auth-modal.in .modal-dialog {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.sign-options { display: flex; align-items: center; justify-content: space-between; color: var(--muted-2-color, #999); font-size: 12px; }
|
||||
.sign-options label { margin: 0; font-weight: 400; }
|
||||
.sign-submit { width: 100%; min-height: 42px; padding: 10px 16px; border: 0; border-radius: 5px; color: #fff; cursor: pointer; transition: opacity .2s, transform .2s; }
|
||||
.sign-submit:hover { opacity: .88; transform: translateY(-1px); }
|
||||
.sign-submit:disabled { opacity: .55; cursor: wait; transform: none; }
|
||||
.sign-submit.jb-blue { background: linear-gradient(135deg, #59c3ff, #2b70ff); }
|
||||
.sign-submit.jb-green { background: linear-gradient(135deg, #50e3a4, #16a085); }
|
||||
.sign-mode-switch { justify-self: center; font-size: 12px; }
|
||||
.sign-notice { margin-bottom: 16px; padding: 10px 12px; border-radius: 5px; background: rgba(255, 86, 86, .08); color: #e55353; font-size: 12px; }
|
||||
.sign-hint { margin-top: -10px; color: var(--muted-2-color, #999); font-size: 11px; }
|
||||
.sign-agreement { display: flex; align-items: flex-start; gap: 6px; margin: 0; color: var(--muted-2-color, #999); font-size: 11px; font-weight: 400; }
|
||||
.sign-agreement a { color: var(--focus-color, #f04494); }
|
||||
.sign-agreement-implicit { justify-content: center; text-align: center; }
|
||||
#u_sign .sign-img {
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.social-login { margin-top: 24px; text-align: center; }
|
||||
.social-login > span { display: flex; align-items: center; gap: 10px; color: var(--muted-2-color, #999); font-size: 11px; }
|
||||
.social-login > span::before,
|
||||
.social-login > span::after { content: ""; flex: 1; height: 1px; background: var(--main-border-color, rgba(50, 50, 50, .08)); }
|
||||
.social-login-buttons { display: flex; flex-wrap: wrap; justify-content: center; gap: 13px; margin-top: 14px; }
|
||||
.social-login-item { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50px; background: var(--body-bg-color, #f5f6f7); color: #fff; text-decoration: none; cursor: pointer; }
|
||||
.social-login-item:hover { transform: translateY(-2px); color: var(--focus-color, #f04494); }
|
||||
.oauth-button-lg .social-login-item { width: auto; padding: 0 14px; }
|
||||
.oauth-button-lg .social-login-item i,
|
||||
.oauth-button-lg .social-login-item svg { margin-right: 6px; font-size: 1.2em; }
|
||||
.social-login-item.weibo { background: #ea5d5c; }
|
||||
.social-login-item.weixingzh,
|
||||
.social-login-item.weixin { background: #24b76a; }
|
||||
.social-login-item.qq { background: #1296db; }
|
||||
.social-login-item.github { background: #505050; }
|
||||
.social-login-item.gitee { background: #c2292f; }
|
||||
.social-login-item.google { background: var(--main-shadow, rgba(116, 116, 116, .08)); color: var(--main-color, #4e5358); }
|
||||
.auth-qrcode { display: grid; place-items: center; width: 180px; min-height: 180px; margin: 20px auto; background: #fff; color: #38b766; text-align: center; }
|
||||
.auth-qrcode [data-auth-qr-content] { display: grid; place-items: center; width: 100%; min-height: 180px; }
|
||||
.auth-qrcode i { font-size: 46px; }
|
||||
.auth-qrcode span { color: #777; font-size: 12px; }
|
||||
#u_sign .sign-img img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: var(--main-radius);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.jio-auth-modal { position: fixed; inset: 0; z-index: 100050; display: none; place-items: center; padding: 18px; }
|
||||
.jio-auth-modal.is-open { display: grid; }
|
||||
.auth-modal-backdrop { position: absolute; inset: 0; background: rgba(14, 18, 24, .62); backdrop-filter: blur(2px); }
|
||||
#u_sign .modal-dialog { position: relative; z-index: 1; width: 400px; max-width: calc(100vw - 30px); margin: 0; }
|
||||
#u_sign.has-sign-img .modal-dialog { width: 800px; }
|
||||
#u_sign .modal-content { position: relative; min-height: 300px; max-height: calc(100vh - 36px); overflow-x: hidden; overflow-y: auto; border: 0; border-radius: 8px; background: var(--main-bg-color, #fff); box-shadow: 0 12px 50px rgba(0, 0, 0, .22); }
|
||||
.auth-modal-close { position: absolute; top: 13px; right: 15px; z-index: 4; width: 30px; height: 30px; border: 0; border-radius: 50%; background: rgba(0, 0, 0, .04); color: var(--muted-color, #777); cursor: pointer; }
|
||||
#u_sign .sign-img { position: absolute; inset: 0 45% 0 0; overflow: hidden; padding: 0; }
|
||||
#u_sign .sign-img img { display: block; width: 100%; height: 100%; border-radius: 8px 0 0 8px; object-fit: cover; }
|
||||
#u_sign .sign-img + .sign { max-width: unset; margin-left: 55%; padding: 34px 44px; }
|
||||
#u_sign .sign > .close {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 15px;
|
||||
z-index: 3;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.page-template-user-sign { min-height: 100vh; background: var(--body-bg-color, #f5f6f7); }
|
||||
.sign-page-background { position: fixed; inset: 0; z-index: 0; background-position: center; background-size: cover; }
|
||||
.sign-topbar { position: fixed; top: 0; right: 0; left: 0; z-index: 3; display: flex; justify-content: space-between; padding: 15px 24px; background: rgba(255, 255, 255, .75); backdrop-filter: blur(12px); }
|
||||
.sign-page { position: relative; z-index: 1; display: flex; align-items: center; min-height: 100vh; padding: 76px max(5vw, 20px) 56px; }
|
||||
.sign-page.sign-card-position-left { justify-content: flex-start; }
|
||||
.sign-page.sign-card-position-center { justify-content: center; }
|
||||
.sign-page.sign-card-position-right { justify-content: flex-end; }
|
||||
.sign-page-card { width: 400px; max-width: 100%; padding: 0 35px; border-radius: 8px; background: var(--main-bg-color, #fff); box-shadow: 0 10px 40px rgba(0, 0, 0, .12); }
|
||||
.sign-page-footer { position: fixed; right: 0; bottom: 12px; left: 0; z-index: 2; text-align: center; color: var(--muted-2-color, #999); font-size: 12px; }
|
||||
.white-theme { --main-bg-color: #fff; --body-bg-color: #f5f6f7; --main-color: #4e5358; --key-color: #333; }
|
||||
.dark-theme { --main-bg-color: #24272b; --body-bg-color: #17191c; --main-color: #d7d9dc; --key-color: #fff; --main-border-color: rgba(255, 255, 255, .12); }
|
||||
body.auth-modal-open { overflow: hidden; }
|
||||
body.auth-modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ---- /sign/ page shell ---- */
|
||||
.page-template-user-sign {
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
.page-template-user-sign > .fixed {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.sign-page {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 500px;
|
||||
padding-top: 70px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.sign-row {
|
||||
min-height: calc(100vh - 130px);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sign-page .sign {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.sign-col {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sign-page-footer {
|
||||
top: auto;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.sign .sign-passw {
|
||||
border: 0;
|
||||
background: none;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sign .oauth-data-box .muted-box {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sign .oauth-data-box .avatar-img {
|
||||
--this-size: 60px;
|
||||
}
|
||||
|
||||
.sign [data-auth-qr-content] {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 180px;
|
||||
}
|
||||
|
||||
.sign .qrcode-signin-container button[data-auth-refresh-qr] {
|
||||
border: 0;
|
||||
background: none;
|
||||
padding: 10px;
|
||||
color: var(--focus-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sign [data-invite-feedback].is-error {
|
||||
color: #ff5473;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
#u_sign .modal-dialog,
|
||||
#u_sign.has-sign-img .modal-dialog {
|
||||
width: auto;
|
||||
margin: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
#u_sign .modal-dialog,
|
||||
#u_sign.has-sign-img .modal-dialog { width: 400px; }
|
||||
#u_sign .sign-img { display: none; }
|
||||
#u_sign .sign-img + .sign { max-width: 340px; margin-left: auto; padding: 30px 0; }
|
||||
#u_sign .modal-content { padding: 0 24px; }
|
||||
.sign-page { justify-content: center !important; padding-right: 14px; padding-left: 14px; }
|
||||
.sign-page-card { padding: 0 24px; }
|
||||
.sign-page {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.sign-row {
|
||||
min-height: calc(100vh - 110px);
|
||||
}
|
||||
|
||||
.sign-page .sign {
|
||||
width: 340px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
+58
-26
@@ -156,7 +156,7 @@
|
||||
function isRootActive(root) {
|
||||
if (!root || root.dataset.activeTab !== 'oauth' || document.visibilityState !== 'visible') return false;
|
||||
if (root.dataset.surface !== 'modal') return document.documentElement.contains(root);
|
||||
return !!modal && modal.classList.contains('is-open') && modal.contains(root);
|
||||
return !!modal && modal.classList.contains('in') && modal.contains(root);
|
||||
}
|
||||
|
||||
function stopQr(root) {
|
||||
@@ -329,6 +329,8 @@
|
||||
root.querySelectorAll('[data-auth-panel]').forEach(function (item) {
|
||||
var active = item === panel;
|
||||
item.hidden = !active;
|
||||
item.classList.toggle('active', active);
|
||||
item.classList.toggle('in', active);
|
||||
item.setAttribute('aria-hidden', active ? 'false' : 'true');
|
||||
});
|
||||
root.querySelectorAll('[data-auth-tab]').forEach(function (item) {
|
||||
@@ -340,8 +342,12 @@
|
||||
url.searchParams.set('tab', tab);
|
||||
window.history.replaceState({}, '', url.toString());
|
||||
}
|
||||
var focus = panel.querySelector('input:not([type="hidden"]), button, a[href], [tabindex]:not([tabindex="-1"])');
|
||||
if (focus) window.setTimeout(function () { focus.focus(); }, 30);
|
||||
// Only prompt for input on a real user switch; the initial boot should not
|
||||
// steal focus (and scroll) on the modal or the full page.
|
||||
if (updateUrl) {
|
||||
var focus = panel.querySelector('input:not([type="hidden"]), button, a[href], [tabindex]:not([tabindex="-1"])');
|
||||
if (focus) window.setTimeout(function () { focus.focus(); }, 30);
|
||||
}
|
||||
if (tab === 'oauth') loadQr(root, false);
|
||||
}
|
||||
|
||||
@@ -369,11 +375,13 @@
|
||||
}
|
||||
|
||||
function setBusy(form, busy) {
|
||||
var button = form.querySelector('.sign-submit');
|
||||
var button = form.querySelector('button[type="submit"]');
|
||||
if (!button) return;
|
||||
button.disabled = busy;
|
||||
var spinner = button.querySelector('.fa-spinner');
|
||||
if (spinner) spinner.hidden = !busy;
|
||||
var label = button.querySelector('[data-submit-label]');
|
||||
if (label) label.hidden = busy;
|
||||
}
|
||||
|
||||
function startCountdown(button, seconds) {
|
||||
@@ -483,14 +491,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
function toggleLoginMode(root, button) {
|
||||
var password = root.querySelector('[data-auth-password-fields]');
|
||||
var code = root.querySelector('[data-auth-code-fields]');
|
||||
if (!password || !code) return;
|
||||
var showCode = code.hidden;
|
||||
code.hidden = !showCode;
|
||||
password.hidden = showCode;
|
||||
button.textContent = showCode ? '使用账号密码登录' : '使用验证码登录';
|
||||
function switchSigninMode(root, mode) {
|
||||
root.querySelectorAll('[data-signin-panel]').forEach(function (panel) {
|
||||
var active = panel.dataset.signinPanel === mode;
|
||||
panel.hidden = !active;
|
||||
panel.classList.toggle('active', active);
|
||||
panel.classList.toggle('in', active);
|
||||
});
|
||||
}
|
||||
|
||||
function setOAuthRedirect(root, redirect) {
|
||||
@@ -538,9 +545,6 @@
|
||||
}
|
||||
|
||||
function initRoot(root) {
|
||||
root.querySelectorAll('input').forEach(function (input) {
|
||||
if (!input.hasAttribute('placeholder')) input.setAttribute('placeholder', ' ');
|
||||
});
|
||||
root.querySelectorAll('form').forEach(function (form) { form.noValidate = true; });
|
||||
root.querySelectorAll('[data-auth-tab]').forEach(function (tab) {
|
||||
tab.setAttribute('role', 'tab');
|
||||
@@ -556,7 +560,7 @@
|
||||
var initial = root.dataset.initialTab || 'signin';
|
||||
if (initial === 'oauth' && window.matchMedia && window.matchMedia('(max-width: 767px)').matches) initial = 'signin';
|
||||
var mayActivateQr = initial !== 'oauth' || document.visibilityState === 'visible';
|
||||
if (root.dataset.surface === 'modal' && (!modal || !modal.classList.contains('is-open'))) mayActivateQr = false;
|
||||
if (root.dataset.surface === 'modal' && (!modal || !modal.classList.contains('in'))) mayActivateQr = false;
|
||||
if (!mayActivateQr) initial = 'signin';
|
||||
activate(root, initial, false);
|
||||
root.addEventListener('click', function (event) {
|
||||
@@ -568,12 +572,15 @@
|
||||
}
|
||||
var password = event.target.closest('[data-password-show]');
|
||||
if (password) {
|
||||
var input = password.closest('.floating-input').querySelector('input');
|
||||
var field = password.closest('.line-form') || password.parentElement;
|
||||
var input = field ? field.querySelector('input') : null;
|
||||
if (!input) return;
|
||||
var visible = input.type === 'password';
|
||||
input.type = visible ? 'text' : 'password';
|
||||
password.setAttribute('aria-label', visible ? '隐藏密码' : '显示密码');
|
||||
password.setAttribute('aria-pressed', visible ? 'true' : 'false');
|
||||
password.querySelector('i').className = visible ? 'fa fas fa-eye-slash' : 'fa fas fa-eye';
|
||||
var glyph = password.querySelector('i');
|
||||
if (glyph) glyph.className = visible ? 'fa fas fa-eye-slash' : 'fa fas fa-eye';
|
||||
return;
|
||||
}
|
||||
var send = event.target.closest('[data-send-code]');
|
||||
@@ -582,10 +589,33 @@
|
||||
sendCode(send);
|
||||
return;
|
||||
}
|
||||
var mode = event.target.closest('[data-login-mode]');
|
||||
var mode = event.target.closest('[data-signin-mode]');
|
||||
if (mode) {
|
||||
event.preventDefault();
|
||||
toggleLoginMode(root, mode);
|
||||
switchSigninMode(root, mode.dataset.signinMode);
|
||||
return;
|
||||
}
|
||||
var inviteGate = event.target.closest('[data-invite-gate]');
|
||||
if (inviteGate) {
|
||||
event.preventDefault();
|
||||
var gateInput = root.querySelector('[data-invite-gate-input]');
|
||||
var gatePanel = root.querySelector('[data-invite-gate-panel]');
|
||||
var formPanel = root.querySelector('[data-invite-form-panel]');
|
||||
if (!gateInput || !formPanel) return;
|
||||
var code = gateInput.value.trim();
|
||||
if (!code) {
|
||||
gateInput.setAttribute('aria-invalid', 'true');
|
||||
notify('请输入邀请码', 'warning');
|
||||
return;
|
||||
}
|
||||
gateInput.setAttribute('aria-invalid', 'false');
|
||||
var hiddenInvite = formPanel.querySelector('[data-invite-value]');
|
||||
if (hiddenInvite) hiddenInvite.value = code;
|
||||
if (gatePanel) { gatePanel.hidden = true; gatePanel.classList.remove('active', 'in'); }
|
||||
formPanel.hidden = false;
|
||||
formPanel.classList.add('active', 'in');
|
||||
var focus = formPanel.querySelector('input:not([type="hidden"])');
|
||||
if (focus) window.setTimeout(function () { focus.focus(); }, 30);
|
||||
return;
|
||||
}
|
||||
var refreshQr = event.target.closest('[data-auth-refresh-qr]');
|
||||
@@ -639,9 +669,10 @@
|
||||
return;
|
||||
}
|
||||
lastModalTrigger = trigger || document.activeElement;
|
||||
modal.classList.add('is-open');
|
||||
modal.style.display = 'block';
|
||||
modal.classList.add('in');
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
document.body.classList.add('auth-modal-open');
|
||||
document.body.classList.add('auth-modal-open', 'modal-open');
|
||||
var root = modal.querySelector('[data-jio-auth]');
|
||||
if (root) {
|
||||
var targetRedirect = redirect || window.location.href;
|
||||
@@ -654,12 +685,13 @@
|
||||
}
|
||||
|
||||
function closeModal(storeDismissal) {
|
||||
if (!modal || !modal.classList.contains('is-open')) return;
|
||||
if (!modal || !modal.classList.contains('in')) return;
|
||||
var root = modal.querySelector('[data-jio-auth]');
|
||||
if (root) stopQr(root);
|
||||
modal.classList.remove('is-open');
|
||||
modal.classList.remove('in');
|
||||
modal.style.display = '';
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
document.body.classList.remove('auth-modal-open');
|
||||
document.body.classList.remove('auth-modal-open', 'modal-open');
|
||||
if (storeDismissal && Number(modal.dataset.autoExpires) > 0) {
|
||||
var until = Date.now() + Number(modal.dataset.autoExpires) * 3600000;
|
||||
window.localStorage.setItem('jioAuthAutoUntil', String(until));
|
||||
@@ -670,7 +702,7 @@
|
||||
}
|
||||
|
||||
function handleModalKeydown(event) {
|
||||
if (!modal || !modal.classList.contains('is-open')) return;
|
||||
if (!modal || !modal.classList.contains('in')) return;
|
||||
if (event.key === 'Escape') {
|
||||
event.preventDefault();
|
||||
closeModal(true);
|
||||
|
||||
@@ -165,9 +165,14 @@
|
||||
if (themeInitialized) return;
|
||||
themeInitialized = true;
|
||||
|
||||
var forced = window.jioData && window.jioData.themeForced;
|
||||
var stored = getStoredTheme();
|
||||
var configuredMode = (window.jioData && window.jioData.themeMode) || "light";
|
||||
if (stored === "dark" || stored === "light") {
|
||||
if (forced === "dark" || forced === "light") {
|
||||
// A surface can pin the theme (the sign page's custom theme mode); a
|
||||
// stored preference must not override it.
|
||||
applyTheme(forced);
|
||||
} else if (stored === "dark" || stored === "light") {
|
||||
applyTheme(stored);
|
||||
} else {
|
||||
applyTheme(resolveConfiguredTheme(configuredMode));
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
(function($,window2,document2){"use strict";function closeNotyf($element){$element.addClass("notyn-out"),window2.setTimeout(function(){$element.remove()},1e3)}function notyf2(message,type,time,id){var $body=jQuery(document2.body);jQuery(".notyn").length||$body.append('<div class="notyn"></div>'),type=type||"success",type==="error"&&(type="danger"),time=time||5e3,time=time<100?time*1e3:time;var idAttribute=id?' id="'+id+'"':"",$notification=jQuery('<div class="noty1"'+idAttribute+'><div class="notyf '+type+'">'+message+"</div></div>"),shouldClose=!id;id&&jQuery("#"+id).length?(jQuery("#"+id).find(".notyf").removeClass().addClass("notyf "+type).html(message),$notification=jQuery("#"+id),shouldClose=!0):jQuery(".notyn").append($notification),shouldClose&&window2.setTimeout(function(){closeNotyf($notification)},time)}jQuery(document2.body).on("click",".noty1",function(){closeNotyf(jQuery(this))}),window2.notyf=notyf2})(jQuery,window,document),(function(window2){"use strict";var allowedKinds={identity:!0,badges:!0,orders:!0,vip:!0},allowedEvents={click:!0,shell:!0,"first-content":!0,ready:!0,"action-start":!0,"action-end":!0,unauthorized:!0,error:!0},sessions=Object.create(null),sequence=0,maxSessions=100;function normalize(value,fallback){var normalized=String(value||fallback||"").toLowerCase().replace(/[^a-z0-9-]/g,"");return normalized||fallback}function now(){return window2.performance&&typeof window2.performance.now=="function"?window2.performance.now():0}function markName(session,event){return"jio-modal-"+session.kind+"-"+session.id+"-"+event}function emit(session,event){if(!(!window2.performance||typeof window2.performance.mark!="function")){var name=markName(session,event);if(window2.performance.mark(name),session.marks[event]=name,typeof window2.performance.measure=="function"&&session.marks.click&&event!=="click")try{window2.performance.measure("jio-modal-"+session.kind+"-"+session.id+"-click-to-"+event,session.marks.click,name)}catch{}}}function start(kind){var safeKind=normalize(kind,"unknown");allowedKinds[safeKind]||(safeKind="unknown"),sequence+=1;var id=String(sequence),session={id,kind:safeKind,startedAt:now(),marks:Object.create(null)};sessions[id]=session,emit(session,"click");for(var ids=Object.keys(sessions);ids.length>maxSessions;)delete sessions[ids.shift()];return id}function mark(id,event){var session=sessions[String(id||"")],safeEvent=normalize(event,"error");!session||!allowedEvents[safeEvent]||emit(session,safeEvent)}function finish(id){mark(id,"ready")}function fail(id){mark(id,"error")}window2.JioModalTelemetry={start,mark,finish,error:fail}})(window),(function(window2){"use strict";function data(){return window2.jioData||window2.jio||{}}function createIdempotencyKey(){if(window2.crypto&&typeof window2.crypto.randomUUID=="function")return window2.crypto.randomUUID();if(!window2.crypto||typeof window2.crypto.getRandomValues!="function")throw new Error("当前浏览器无法生成安全的操作标识");var bytes=new Uint8Array(16);window2.crypto.getRandomValues(bytes),bytes[6]=bytes[6]&15|64,bytes[8]=bytes[8]&63|128;var hex=Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,"0")}).join("");return hex.slice(0,8)+"-"+hex.slice(8,12)+"-"+hex.slice(12,16)+"-"+hex.slice(16,20)+"-"+hex.slice(20)}function restBase(){var config=data(),raw=config.restUrl||config.apiUrl||config.rest_url||"",siteUrl=config.siteUrl||config.homeUrl||window2.location.origin+"/";return window2.location.protocol==="https:"&&siteUrl.substring(0,5)==="http:"&&(siteUrl="https:"+siteUrl.substring(5)),raw?String(raw).replace(/\/$/,""):String(siteUrl).replace(/\/$/,"")+"/index.php?rest_route=/jio/v1"}function appendQuery(url2,query){if(!query)return url2;var parts=[];return typeof query=="string"?parts=query.replace(/^\?/,"").split("&").filter(Boolean):typeof query=="object"&&Object.keys(query).forEach(function(key){query[key]===void 0||query[key]===null||parts.push(encodeURIComponent(key)+"="+encodeURIComponent(String(query[key])))}),parts.length?url2+(url2.indexOf("?")>=0?"&":"?")+parts.join("&"):url2}function url(path,query){path=String(path||"");var inlineQuery="",queryIndex=path.indexOf("?");if(queryIndex>=0&&(inlineQuery=path.slice(queryIndex+1),path=path.slice(0,queryIndex)),/^https?:\/\//i.test(path))return appendQuery(path,query||inlineQuery);path.charAt(0)!=="/"&&(path="/"+path);var base=restBase(),result=(base.indexOf("rest_route=")>=0,base+path);return appendQuery(result,query||inlineQuery)}function headers(options){var config=data(),source=options&&options.headers||{},result={},nonce=config.restNonce||config.nonce||"";return Object.keys(source).forEach(function(key){result[key]=source[key]}),result.Accept||(result.Accept="application/json, text/html;q=0.9, */*;q=0.8"),nonce&&!result["X-WP-Nonce"]&&(result["X-WP-Nonce"]=nonce),options&&options.body!==void 0&&options.body!==null&&!(window2.FormData&&options.body instanceof window2.FormData)&&!result["Content-Type"]&&(result["CoLine truncated
|
||||
(function($,window2,document2){"use strict";function closeNotyf($element){$element.addClass("notyn-out"),window2.setTimeout(function(){$element.remove()},1e3)}function notyf2(message,type,time,id){var $body=jQuery(document2.body);jQuery(".notyn").length||$body.append('<div class="notyn"></div>'),type=type||"success",type==="error"&&(type="danger"),time=time||5e3,time=time<100?time*1e3:time;var idAttribute=id?' id="'+id+'"':"",$notification=jQuery('<div class="noty1"'+idAttribute+'><div class="notyf '+type+'">'+message+"</div></div>"),shouldClose=!id;id&&jQuery("#"+id).length?(jQuery("#"+id).find(".notyf").removeClass().addClass("notyf "+type).html(message),$notification=jQuery("#"+id),shouldClose=!0):jQuery(".notyn").append($notification),shouldClose&&window2.setTimeout(function(){closeNotyf($notification)},time)}jQuery(document2.body).on("click",".noty1",function(){closeNotyf(jQuery(this))}),window2.notyf=notyf2})(jQuery,window,document),(function(window2){"use strict";var allowedKinds={identity:!0,badges:!0,orders:!0,vip:!0},allowedEvents={click:!0,shell:!0,"first-content":!0,ready:!0,"action-start":!0,"action-end":!0,unauthorized:!0,error:!0},sessions=Object.create(null),sequence=0,maxSessions=100;function normalize(value,fallback){var normalized=String(value||fallback||"").toLowerCase().replace(/[^a-z0-9-]/g,"");return normalized||fallback}function now(){return window2.performance&&typeof window2.performance.now=="function"?window2.performance.now():0}function markName(session,event){return"jio-modal-"+session.kind+"-"+session.id+"-"+event}function emit(session,event){if(!(!window2.performance||typeof window2.performance.mark!="function")){var name=markName(session,event);if(window2.performance.mark(name),session.marks[event]=name,typeof window2.performance.measure=="function"&&session.marks.click&&event!=="click")try{window2.performance.measure("jio-modal-"+session.kind+"-"+session.id+"-click-to-"+event,session.marks.click,name)}catch{}}}function start(kind){var safeKind=normalize(kind,"unknown");allowedKinds[safeKind]||(safeKind="unknown"),sequence+=1;var id=String(sequence),session={id,kind:safeKind,startedAt:now(),marks:Object.create(null)};sessions[id]=session,emit(session,"click");for(var ids=Object.keys(sessions);ids.length>maxSessions;)delete sessions[ids.shift()];return id}function mark(id,event){var session=sessions[String(id||"")],safeEvent=normalize(event,"error");!session||!allowedEvents[safeEvent]||emit(session,safeEvent)}function finish(id){mark(id,"ready")}function fail(id){mark(id,"error")}window2.JioModalTelemetry={start,mark,finish,error:fail}})(window),(function(window2){"use strict";function data(){return window2.jioData||window2.jio||{}}function createIdempotencyKey(){if(window2.crypto&&typeof window2.crypto.randomUUID=="function")return window2.crypto.randomUUID();if(!window2.crypto||typeof window2.crypto.getRandomValues!="function")throw new Error("当前浏览器无法生成安全的操作标识");var bytes=new Uint8Array(16);window2.crypto.getRandomValues(bytes),bytes[6]=bytes[6]&15|64,bytes[8]=bytes[8]&63|128;var hex=Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,"0")}).join("");return hex.slice(0,8)+"-"+hex.slice(8,12)+"-"+hex.slice(12,16)+"-"+hex.slice(16,20)+"-"+hex.slice(20)}function restBase(){var config=data(),raw=config.restUrl||config.apiUrl||config.rest_url||"",siteUrl=config.siteUrl||config.homeUrl||window2.location.origin+"/";return window2.location.protocol==="https:"&&siteUrl.substring(0,5)==="http:"&&(siteUrl="https:"+siteUrl.substring(5)),raw?String(raw).replace(/\/$/,""):String(siteUrl).replace(/\/$/,"")+"/index.php?rest_route=/jio/v1"}function appendQuery(url2,query){if(!query)return url2;var parts=[];return typeof query=="string"?parts=query.replace(/^\?/,"").split("&").filter(Boolean):typeof query=="object"&&Object.keys(query).forEach(function(key){query[key]===void 0||query[key]===null||parts.push(encodeURIComponent(key)+"="+encodeURIComponent(String(query[key])))}),parts.length?url2+(url2.indexOf("?")>=0?"&":"?")+parts.join("&"):url2}function url(path,query){path=String(path||"");var inlineQuery="",queryIndex=path.indexOf("?");if(queryIndex>=0&&(inlineQuery=path.slice(queryIndex+1),path=path.slice(0,queryIndex)),/^https?:\/\//i.test(path))return appendQuery(path,query||inlineQuery);path.charAt(0)!=="/"&&(path="/"+path);var base=restBase(),result=(base.indexOf("rest_route=")>=0,base+path);return appendQuery(result,query||inlineQuery)}function headers(options){var config=data(),source=options&&options.headers||{},result={},nonce=config.restNonce||config.nonce||"";return Object.keys(source).forEach(function(key){result[key]=source[key]}),result.Accept||(result.Accept="application/json, text/html;q=0.9, */*;q=0.8"),nonce&&!result["X-WP-Nonce"]&&(result["X-WP-Nonce"]=nonce),options&&options.body!==void 0&&options.body!==null&&!(window2.FormData&&options.body instanceof window2.FormData)&&!result["Content-Type"]&&(result["CoLine truncated
|
||||
+6
-4
@@ -25,15 +25,17 @@ if (!in_array($jio_mobile_align, ['top', 'left', 'right'], true)) {
|
||||
|
||||
$jio_initial_theme_mode = '';
|
||||
if (class_exists('\Jio\Settings\Settings') && method_exists('\Jio\Settings\Settings', 'initial_theme_mode')) {
|
||||
$jio_initial_theme_mode = \Jio\Settings\Settings::initial_theme_mode();
|
||||
$jio_initial_theme_mode = (string) apply_filters('jio_initial_theme_mode', \Jio\Settings\Settings::initial_theme_mode());
|
||||
}
|
||||
$jio_has_initial_theme = in_array($jio_initial_theme_mode, ['dark', 'light'], true);
|
||||
|
||||
$jio_body_classes = [];
|
||||
// legacy: body.nav-fixed drives top padding + hero pull-under-nav.
|
||||
if (!isset($jio_header_settings['nav_fixed']) || !empty($jio_header_settings['nav_fixed'])) {
|
||||
// legacy: body.nav-fixed drives top padding + hero pull-under-nav. The sign
|
||||
// page lays out its own shell, so it opts out of the fixed-nav offset.
|
||||
$jio_is_sign_page = function_exists('jio_is_auth_page_request') && jio_is_auth_page_request();
|
||||
if (!$jio_is_sign_page && (!isset($jio_header_settings['nav_fixed']) || !empty($jio_header_settings['nav_fixed']))) {
|
||||
$jio_body_classes[] = 'nav-fixed';
|
||||
} else {
|
||||
} elseif (!$jio_is_sign_page) {
|
||||
$jio_body_classes[] = 'has-static-nav';
|
||||
}
|
||||
|
||||
|
||||
+11
-17
@@ -47,16 +47,18 @@ if (!function_exists('jio_get_auth_agreement_view')) {
|
||||
}
|
||||
$links = [];
|
||||
if ($enabled) {
|
||||
$links[] = $url !== '' ? sprintf('<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', esc_url($url), esc_html__('用户协议', 'jio')) : esc_html__('用户协议', 'jio');
|
||||
$links[] = $url !== '' ? sprintf('<a class="focus-color" href="%s" target="_blank" rel="noopener noreferrer">%s</a>', esc_url($url), esc_html__('用户协议', 'jio')) : esc_html__('用户协议', 'jio');
|
||||
}
|
||||
if ($privacy_enabled) {
|
||||
$links[] = $privacy_url !== '' ? sprintf('<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', esc_url($privacy_url), esc_html__('隐私协议', 'jio')) : esc_html__('隐私协议', 'jio');
|
||||
$links[] = $privacy_url !== '' ? sprintf('<a class="focus-color" href="%s" target="_blank" rel="noopener noreferrer">%s</a>', esc_url($privacy_url), esc_html__('隐私协议', 'jio')) : esc_html__('隐私协议', 'jio');
|
||||
}
|
||||
$links_html = implode(esc_html__('、', 'jio'), $links);
|
||||
$label_html = esc_html__('我已阅读并同意', 'jio') . implode(esc_html__('和', 'jio'), $links);
|
||||
|
||||
return [
|
||||
'enabled' => $enabled || $privacy_enabled,
|
||||
'required' => $required,
|
||||
'links_html' => $links_html,
|
||||
'label_html' => $label_html,
|
||||
'field_name' => 'agree_terms',
|
||||
];
|
||||
@@ -65,27 +67,19 @@ if (!function_exists('jio_get_auth_agreement_view')) {
|
||||
|
||||
if (!function_exists('jio_get_auth_sign_logo_html')) {
|
||||
/**
|
||||
* Shared logo block for full-page sign shell.
|
||||
* Shared logo block for the sign card (modal and /sign/).
|
||||
*/
|
||||
function jio_get_auth_sign_logo_html(): string {
|
||||
$logo_url = class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::user_logo_url() : '';
|
||||
$logo_dark_url = class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::user_logo_dark_url() : $logo_url;
|
||||
$logo_dark_url = class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::user_logo_dark_url() : $logo_url;
|
||||
$home = home_url('/');
|
||||
$name = get_bloginfo('name');
|
||||
if ($logo_url) {
|
||||
return sprintf(
|
||||
'<a href="%s"><img class="sign-logo-light" src="%s" alt="%s"><img class="sign-logo-dark" src="%s" alt="%s"></a>',
|
||||
esc_url($home),
|
||||
esc_url($logo_url),
|
||||
esc_attr($name),
|
||||
esc_url($logo_dark_url),
|
||||
esc_attr($name)
|
||||
);
|
||||
$img = function_exists('jio_get_adaptive_theme_img')
|
||||
? jio_get_adaptive_theme_img($logo_url, $logo_dark_url, $name)
|
||||
: '<img src="' . esc_url($logo_url) . '" alt="' . esc_attr($name) . '">';
|
||||
return '<div class="text-center"><div class="sign-logo box-body"><a href="' . esc_url($home) . '">' . $img . '</a></div></div>';
|
||||
}
|
||||
return sprintf(
|
||||
'<a href="%s" class="sign-logo__text">%s</a>',
|
||||
esc_url($home),
|
||||
esc_html(mb_substr((string) $name, 0, 2))
|
||||
);
|
||||
return '<div class="text-center"><div class="sign-logo box-body"><a href="' . esc_url($home) . '" class="sign-logo__text">' . esc_html(mb_substr((string) $name, 0, 2)) . '</a></div></div>';
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,8 @@ final class Router {
|
||||
add_action('init', [$this, 'register_rewrite_rules']);
|
||||
add_filter('template_include', [$this, 'handle_template_include'], 99);
|
||||
add_action('init', [$this, 'maybe_flush_rewrite_rules']);
|
||||
add_filter('jio_forced_theme_mode', [$this, 'filter_sign_theme_mode']);
|
||||
add_filter('jio_theme_mode_button_positions', [$this, 'filter_sign_theme_positions']);
|
||||
|
||||
add_filter('login_url', [$this, 'filter_login_url'], 10, 3);
|
||||
add_filter('lostpassword_url', [$this, 'filter_lostpassword_url'], 10, 2);
|
||||
@@ -75,6 +77,32 @@ final class Router {
|
||||
return $template;
|
||||
}
|
||||
|
||||
/** 登录页「自定义主题」:强制日间 / 夜间模式。 */
|
||||
public function filter_sign_theme_mode(string $mode): string {
|
||||
$override = $this->sign_theme_mode_override();
|
||||
return $override !== '' ? $override : $mode;
|
||||
}
|
||||
|
||||
/** 登录页强制主题时不显示主题切换按钮。 */
|
||||
public function filter_sign_theme_positions(array $positions): array {
|
||||
return $this->sign_theme_mode_override() !== '' ? [] : $positions;
|
||||
}
|
||||
|
||||
private function sign_theme_mode_override(): string {
|
||||
$is_sign = get_query_var('jio_sign') || (function_exists('jio_is_auth_page_request') && jio_is_auth_page_request());
|
||||
if (!$is_sign || !class_exists('\Jio\Settings\Settings')) {
|
||||
return '';
|
||||
}
|
||||
$mode = (string) (\Jio\Settings\Settings::sign_page_ui()['theme_mode'] ?? 'no');
|
||||
if ($mode === 'dark-theme') {
|
||||
return 'dark';
|
||||
}
|
||||
if ($mode === 'white-theme') {
|
||||
return 'light';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function maybe_flush_rewrite_rules(): void {
|
||||
$rewrite_version = JIO_VERSION . ':sign-router-v3-single-route';
|
||||
if (get_option('jio_auth_routes_flushed') !== $rewrite_version) {
|
||||
|
||||
@@ -463,6 +463,8 @@ trait ScriptsPart1c {
|
||||
'siteUrl' => home_url('/'),
|
||||
'themeUrl' => JIO_URI,
|
||||
'themeMode' => class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::theme_mode_js_value() : 'auto',
|
||||
// 登录页「自定义主题」:强制模式优先于用户保存的 cookie。
|
||||
'themeForced' => (string) apply_filters('jio_forced_theme_mode', ''),
|
||||
'debug' => defined('WP_DEBUG') && WP_DEBUG,
|
||||
'debugLog' => defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG,
|
||||
'postPaginationMode' => class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::get_post_pagination_mode() : 'load_more',
|
||||
|
||||
@@ -394,7 +394,8 @@ class Settings {
|
||||
|
||||
/** 主题模式 → JS 可消费的简化值 (light / dark / time-auto) */
|
||||
public static function theme_mode_js_value(): string {
|
||||
return ThemeSearch::theme_mode_js_value();
|
||||
$mode = (string) apply_filters('jio_theme_mode_js_value', ThemeSearch::theme_mode_js_value());
|
||||
return in_array($mode, ['light', 'dark', 'time-auto'], true) ? $mode : 'time-auto';
|
||||
}
|
||||
|
||||
|
||||
@@ -429,7 +430,9 @@ class Settings {
|
||||
|
||||
/** 获取主题切换按钮显示位置列表 */
|
||||
public static function get_theme_mode_button_positions(): array {
|
||||
return ThemeSearch::get_theme_mode_button_positions();
|
||||
$positions = ThemeSearch::get_theme_mode_button_positions();
|
||||
$filtered = apply_filters('jio_theme_mode_button_positions', $positions);
|
||||
return is_array($filtered) ? array_values(array_filter((array) $filtered)) : [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,14 +30,46 @@ if ($tab === 'signup' && class_exists('\Jio\Settings\Settings') && !\Jio\Setting
|
||||
$tab = 'signin';
|
||||
}
|
||||
|
||||
remove_action('wp_footer', 'jio_render_footer_tabbar', 20);
|
||||
remove_action('wp_footer', 'jio_render_float_buttons', 30);
|
||||
$ui = class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::sign_page_ui() : [];
|
||||
$images = $ui['background'] ?? [];
|
||||
$background_id = $images ? (int) $images[array_rand($images)] : 0;
|
||||
$background_url = $background_id > 0 ? (string) wp_get_attachment_image_url($background_id, 'full') : '';
|
||||
// 主题模式由 Router 通过 jio_initial_theme_mode / jio_theme_mode_js_value 统一注入。
|
||||
$theme_mode = (string) ($ui['theme_mode'] ?? 'no');
|
||||
$position = (string) ($ui['card_position'] ?? 'right');
|
||||
$show_header = !empty($ui['show_header']) && !$interim;
|
||||
|
||||
add_filter('document_title_parts', static function (array $parts): array {
|
||||
$parts['title'] = __('登录 / 注册', 'jio');
|
||||
unset($parts['tagline']);
|
||||
return $parts;
|
||||
});
|
||||
|
||||
$initial_theme_mode = '';
|
||||
if ($theme_mode !== 'no' && class_exists('\Jio\Settings\Settings')) {
|
||||
$initial_theme_mode = (string) apply_filters('jio_forced_theme_mode', '');
|
||||
}
|
||||
|
||||
remove_action('wp_footer', 'jio_float_right');
|
||||
|
||||
$body_classes = ['page-template-user-sign', 'site-layout-1'];
|
||||
if ($theme_mode !== 'no') {
|
||||
$body_classes[] = $theme_mode;
|
||||
}
|
||||
if ($initial_theme_mode === 'dark') {
|
||||
$body_classes[] = 'theme-dark';
|
||||
$body_classes[] = 'dark-theme';
|
||||
} elseif ($initial_theme_mode === 'light') {
|
||||
$body_classes[] = 'white-theme';
|
||||
}
|
||||
|
||||
$card_offset = ' col-md-offset-6';
|
||||
if ($position === 'left') {
|
||||
$card_offset = '';
|
||||
} elseif ($position === 'center') {
|
||||
$card_offset = ' col-md-offset-3';
|
||||
}
|
||||
|
||||
$jio_auth_context = [
|
||||
'surface' => 'page',
|
||||
'tab' => $tab,
|
||||
@@ -47,24 +79,33 @@ $jio_auth_context = [
|
||||
];
|
||||
?>
|
||||
<!doctype html>
|
||||
<html <?php language_attributes(); ?>>
|
||||
<html <?php language_attributes(); ?><?php echo $initial_theme_mode === 'dark' ? ' class="dark"' : ''; ?><?php echo $initial_theme_mode !== '' ? ' data-theme="' . esc_attr($initial_theme_mode) . '"' : ''; ?>>
|
||||
<head>
|
||||
<meta charset="<?php bloginfo('charset'); ?>">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title><?php echo esc_html__('登录 / 注册', 'jio') . ' - ' . esc_html(get_bloginfo('name')); ?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<?php wp_head(); ?>
|
||||
</head>
|
||||
<body <?php body_class('page-template-user-sign ' . ($theme_mode !== 'no' ? $theme_mode : '')); ?>>
|
||||
<body <?php body_class($body_classes); ?><?php echo $initial_theme_mode !== '' ? ' data-theme="' . esc_attr($initial_theme_mode) . '"' : ''; ?>>
|
||||
<?php wp_body_open(); ?>
|
||||
<?php if ($background_url !== '') : ?><div class="sign-page-background" style="background-image:url('<?php echo esc_url($background_url); ?>')"></div><?php endif; ?>
|
||||
<?php if (!empty($ui['show_header']) && !$interim) : ?><header class="sign-topbar"><a href="<?php echo esc_url(home_url('/')); ?>"><?php echo esc_html(get_bloginfo('name')); ?></a><a href="<?php echo esc_url(home_url('/')); ?>"><?php esc_html_e('返回首页', 'jio'); ?></a></header><?php endif; ?>
|
||||
<main class="sign-page sign-card-position-<?php echo esc_attr($position); ?>">
|
||||
<div class="sign-page-card">
|
||||
<?php require get_template_directory() . '/templates/parts/auth-content.php'; ?>
|
||||
<?php if ($background_url !== '') : ?>
|
||||
<div class="fixed lazyload" data-bg="<?php echo esc_url($background_url); ?>" style="background-repeat:no-repeat;background-size:cover;background-position:center;"></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_header && function_exists('jio_header')) { jio_header(); } ?>
|
||||
<main role="main" class="container sign-page">
|
||||
<div class="row sign-row gutters-5">
|
||||
<div class="col-md-6<?php echo esc_attr($card_offset); ?> sign-col">
|
||||
<div style="padding:20px 0 60px 0">
|
||||
<?php require get_template_directory() . '/templates/parts/auth-content.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<?php if (!$interim) : ?><footer class="sign-page-footer"><?php echo !empty($ui['footer']) ? wp_kses_post((string) $ui['footer']) : '© ' . esc_html(wp_date('Y')) . ' ' . esc_html(get_bloginfo('name')); ?></footer><?php endif; ?>
|
||||
<?php if (!$interim) : ?>
|
||||
<div class="sign-page-footer text-center blur-bg fixed px12 opacity8">
|
||||
<?php echo !empty($ui['footer']) ? wp_kses_post((string) $ui['footer']) : '© ' . esc_html(wp_date('Y')) . ' ' . esc_html(get_bloginfo('name')); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php wp_footer(); ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -29,7 +29,7 @@ $signup_type = $settings ? $settings::signup_verification_type() : 'email';
|
||||
$signup_type = $signup_verify ? $signup_type : 'email';
|
||||
$reset_type = $settings ? $settings::reset_password_verification_type() : 'email';
|
||||
$omit_confirm = $signup_verify && ($settings ? $settings::signup_omit_password_confirmation() : false);
|
||||
$agreement = function_exists('jio_get_auth_agreement_view') ? jio_get_auth_agreement_view() : ['enabled' => false, 'required' => false, 'label_html' => '', 'field_name' => 'agree_terms'];
|
||||
$agreement = function_exists('jio_get_auth_agreement_view') ? jio_get_auth_agreement_view() : ['enabled' => false, 'required' => false, 'links_html' => '', 'label_html' => '', 'field_name' => 'agree_terms'];
|
||||
$referral = $settings ? $settings::get_referral_registration_settings() : ['enabled' => false, 'register_field' => 'hidden'];
|
||||
$ref_mode = !empty($referral['enabled']) ? (string) ($referral['register_field'] ?? 'hidden') : 'hidden';
|
||||
$ref_hint = $ref_mode === 'required' ? (string) ($referral['required_desc'] ?? '') : (string) ($referral['open_desc'] ?? '');
|
||||
@@ -46,106 +46,342 @@ foreach ($oauth_providers as $provider) {
|
||||
}
|
||||
}
|
||||
$show_logo = !empty($jio_auth_context['show_logo']);
|
||||
$oauth_large = $settings ? (bool) $settings::get_value('oauth_button_lg', false) : false;
|
||||
$redirect_to = esc_url_raw((string) ($jio_auth_context['redirect_to'] ?? home_url('/')));
|
||||
$unique = $is_modal ? 'modal' : 'page';
|
||||
$oauth_user_data = $is_oauth_bind && !empty($oauth_bind_data['user_data']) && is_array($oauth_bind_data['user_data']) ? $oauth_bind_data['user_data'] : [];
|
||||
$oauth_name = sanitize_user((string) ($oauth_user_data['name'] ?? $oauth_user_data['nickname'] ?? $oauth_user_data['login'] ?? ''), true);
|
||||
$oauth_email = sanitize_email((string) ($oauth_user_data['email'] ?? ''));
|
||||
$oauth_avatar = esc_url_raw((string) ($oauth_user_data['avatar'] ?? ''));
|
||||
if ($oauth_avatar === '' && function_exists('jio_get_default_avatar_url')) {
|
||||
$oauth_avatar = jio_get_default_avatar_url();
|
||||
}
|
||||
$oauth_provider_name = $is_oauth_bind ? \Jio\Auth\Service::get_oauth_provider_name((string) ($oauth_bind_data['provider'] ?? '')) : '';
|
||||
$oauth_intent = sanitize_key((string) ($jio_auth_context['oauth_intent'] ?? ($_GET['oauth_intent'] ?? 'login')));
|
||||
$oauth_intent = $oauth_intent === 'bind' ? 'bind' : 'login';
|
||||
$oauth_bind_pass = $oauth_intent === 'bind'
|
||||
? sanitize_text_field((string) ($jio_auth_context['bind_pass'] ?? ($_GET['bind_pass'] ?? '')))
|
||||
: '';
|
||||
|
||||
$initial_tab = $auth_tab;
|
||||
if ($initial_tab === 'signin' && $close_signin && $registration_open) {
|
||||
$initial_tab = 'signup';
|
||||
}
|
||||
if ($initial_tab === 'signup' && !$registration_open) {
|
||||
$initial_tab = 'signin';
|
||||
}
|
||||
if ($initial_tab === 'oauth' && !$wechat_qr) {
|
||||
$initial_tab = 'signin';
|
||||
}
|
||||
if ($initial_tab === 'bind' && !$is_oauth_bind) {
|
||||
$initial_tab = 'signin';
|
||||
}
|
||||
|
||||
$show_nopas = $passwordless;
|
||||
$show_pas = !$passwordless || $passwordless_mode !== 'only_nopas';
|
||||
$nopas_active = $show_nopas && $passwordless_mode !== 'pas';
|
||||
$signin_user_hint = ($passwordless || $signin_phone) ? __('用户名/手机号/邮箱', 'jio') : __('用户名或邮箱', 'jio');
|
||||
$social_html = '';
|
||||
if (!$is_oauth_bind && !$close_signin && !empty($oauth_providers) && class_exists('\Jio\Auth\OAuth')) {
|
||||
$social_html = \Jio\Auth\OAuth::get_instance()->render_social_buttons(__('社交账号登录', 'jio'));
|
||||
}
|
||||
$ref_tooltip = $ref_hint !== '' ? wp_strip_all_tags($ref_hint) : '';
|
||||
$invite_tooltip = ($invite_mode === 'optional' && $invite_hint !== '') ? wp_strip_all_tags($invite_hint) : '';
|
||||
?>
|
||||
<div class="sign jio-auth<?php echo $oauth_large ? ' oauth-button-lg' : ''; ?>" data-jio-auth data-surface="<?php echo esc_attr($unique); ?>" data-initial-tab="<?php echo esc_attr($auth_tab); ?>" data-passwordless-mode="<?php echo esc_attr($passwordless_mode); ?>" data-redirect-to="<?php echo esc_attr($redirect_to); ?>" data-oauth-intent="<?php echo esc_attr($oauth_intent); ?>" data-bind-pass="<?php echo esc_attr($oauth_bind_pass); ?>">
|
||||
<?php if ($show_logo) : ?>
|
||||
<div class="sign-logo"><?php echo function_exists('jio_get_auth_sign_logo_html') ? jio_get_auth_sign_logo_html() : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||||
<div class="sign jio-panel blur-bg relative jio-auth" data-jio-auth data-surface="<?php echo esc_attr($unique); ?>" data-initial-tab="<?php echo esc_attr($initial_tab); ?>" data-redirect-to="<?php echo esc_attr($redirect_to); ?>" data-oauth-intent="<?php echo esc_attr($oauth_intent); ?>" data-bind-pass="<?php echo esc_attr($oauth_bind_pass); ?>">
|
||||
<?php if ($is_modal) : ?>
|
||||
<button type="button" class="close" data-auth-close aria-label="<?php esc_attr_e('关闭', 'jio'); ?>"><?php echo function_exists('jio_icon_markup') ? jio_icon_markup('jiosvg-close', 'ic-close') : '<i class="fa fas fa-times" aria-hidden="true"></i>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_logo && function_exists('jio_get_auth_sign_logo_html')) : ?>
|
||||
<?php echo jio_get_auth_sign_logo_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<section id="<?php echo esc_attr($unique); ?>-auth-panel-signin" class="sign-panel" role="tabpanel" data-auth-panel="signin" <?php echo $auth_tab !== 'signin' ? 'hidden' : ''; ?>>
|
||||
<div class="sign-header"><h2><?php esc_html_e('登录', 'jio'); ?></h2><?php if ($registration_open) : ?><span><?php esc_html_e('没有账号?', 'jio'); ?> <button type="button" data-auth-tab="signup"><?php esc_html_e('立即注册', 'jio'); ?></button></span><?php endif; ?></div>
|
||||
<div class="tab-content">
|
||||
<?php if (!$close_signin) : ?>
|
||||
<form class="sign-form" data-auth-form="login">
|
||||
<div class="floating-input"><input name="target" id="<?php echo esc_attr($unique); ?>-login-target" autocomplete="username" required><label for="<?php echo esc_attr($unique); ?>-login-target"><?php echo ($passwordless || $signin_phone) ? esc_html__('邮箱 / 手机号 / 用户名', 'jio') : esc_html__('邮箱 / 用户名', 'jio'); ?></label></div>
|
||||
<div data-auth-password-fields <?php echo $passwordless && $passwordless_mode !== 'pas' ? 'hidden' : ''; ?>>
|
||||
<div class="floating-input has-action"><input type="password" name="password" id="<?php echo esc_attr($unique); ?>-login-password" autocomplete="current-password"><label for="<?php echo esc_attr($unique); ?>-login-password"><?php esc_html_e('密码', 'jio'); ?></label><button type="button" class="password-show" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye"></i></button></div>
|
||||
<div class="tab-pane fade<?php echo $initial_tab === 'signin' ? ' active in' : ''; ?>" id="<?php echo esc_attr($unique); ?>-tab-sign-in" role="tabpanel" data-auth-panel="signin" <?php echo $initial_tab !== 'signin' ? 'hidden' : ''; ?>>
|
||||
<div class="box-body">
|
||||
<div class="title-h-left fa-2x"><?php esc_html_e('登录', 'jio'); ?></div>
|
||||
<?php if ($registration_open) : ?><a class="muted-color px12" href="#<?php echo esc_attr($unique); ?>-tab-sign-up" data-auth-tab="signup"><?php esc_html_e('没有账号?立即注册', 'jio'); ?><i class="em12 ml3 fa fas fa-angle-right" aria-hidden="true"></i></a><?php endif; ?>
|
||||
</div>
|
||||
<?php if ($passwordless) : ?>
|
||||
<div data-auth-code-fields <?php echo $passwordless_mode === 'pas' ? 'hidden' : ''; ?>>
|
||||
<div class="floating-input has-action"><input name="code" inputmode="numeric" maxlength="6" id="<?php echo esc_attr($unique); ?>-login-code"><label for="<?php echo esc_attr($unique); ?>-login-code"><?php esc_html_e('验证码', 'jio'); ?></label><button type="button" class="send-code" data-send-code="login"><?php esc_html_e('发送验证码', 'jio'); ?></button></div>
|
||||
<input type="hidden" name="channel" value="<?php echo esc_attr($passwordless_type === 'phone' ? 'phone' : ''); ?>">
|
||||
<div id="sign-in">
|
||||
<?php if ($show_nopas) : ?>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade<?php echo $nopas_active ? ' active in' : ''; ?>" id="<?php echo esc_attr($unique); ?>-tab-signin-nopas" data-signin-panel="nopas" <?php echo $nopas_active ? '' : 'hidden'; ?>>
|
||||
<form data-auth-form="login">
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="target" id="<?php echo esc_attr($unique); ?>-nopas-target" class="line-form-input" autocomplete="username" tabindex="1" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php echo $passwordless_type === 'phone' ? esc_html__('手机号', 'jio') : ($passwordless_type === 'email_phone' ? esc_html__('手机号或邮箱', 'jio') : esc_html__('邮箱', 'jio')); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('login'); } ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="code" id="<?php echo esc_attr($unique); ?>-nopas-code" class="line-form-input" inputmode="numeric" maxlength="6" autocomplete="one-time-code" tabindex="2" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('验证码', 'jio'); ?></div>
|
||||
<span class="yztx abs-right"><button type="button" form-action="login" class="but c-blue captchsubmit" data-send-code="login"><?php esc_html_e('发送验证码', 'jio'); ?></button></span>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<input type="hidden" name="channel" value="<?php echo esc_attr($passwordless_type === 'phone' ? 'phone' : ''); ?>">
|
||||
<div class="relative line-form mb10 em09">
|
||||
<span class="muted-color form-checkbox"><input type="checkbox" id="<?php echo esc_attr($unique); ?>-nopas-remember" name="rememberme" value="1" checked="checked"><label for="<?php echo esc_attr($unique); ?>-nopas-remember" class="ml3"><?php esc_html_e('记住登录', 'jio'); ?></label></span>
|
||||
<span class="pull-right muted-2-color">
|
||||
<?php if ($show_pas) : ?><a class="muted-2-color" href="#<?php echo esc_attr($unique); ?>-tab-signin-pas" data-signin-mode="pas"><?php esc_html_e('账号密码登录', 'jio'); ?></a><?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>">
|
||||
<button type="submit" class="but radius jb-blue padding-lg btn-block"><i class="fa fas fa-sign-in-alt mr10" aria-hidden="true"></i><span data-submit-label><?php esc_html_e('登录', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php if ($show_pas) : ?>
|
||||
<div class="tab-pane fade<?php echo $nopas_active ? '' : ' active in'; ?>" id="<?php echo esc_attr($unique); ?>-tab-signin-pas" data-signin-panel="pas" <?php echo $nopas_active ? 'hidden' : ''; ?>>
|
||||
<form data-auth-form="login">
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="target" id="<?php echo esc_attr($unique); ?>-login-target" class="line-form-input" autocomplete="username" tabindex="1" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php echo esc_html($signin_user_hint); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password" id="<?php echo esc_attr($unique); ?>-login-password" class="line-form-input" autocomplete="current-password" tabindex="2" placeholder="">
|
||||
<div class="scale-placeholder"><?php esc_html_e('登录密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('login'); } ?>
|
||||
<div class="relative line-form mb10 em09">
|
||||
<span class="muted-color form-checkbox"><input type="checkbox" id="<?php echo esc_attr($unique); ?>-remember" name="rememberme" value="1" checked="checked"><label for="<?php echo esc_attr($unique); ?>-remember" class="ml3"><?php esc_html_e('记住登录', 'jio'); ?></label></span>
|
||||
<span class="pull-right muted-2-color">
|
||||
<a class="muted-2-color" href="#<?php echo esc_attr($unique); ?>-tab-resetpassword" data-auth-tab="resetpassword"><?php esc_html_e('找回密码', 'jio'); ?></a>
|
||||
<?php if ($show_nopas) : ?><span class="opacity5"> | </span><a class="muted-2-color" href="#<?php echo esc_attr($unique); ?>-tab-signin-nopas" data-signin-mode="nopas"><?php esc_html_e('免密登录', 'jio'); ?></a><?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>">
|
||||
<button type="submit" class="but radius jb-blue padding-lg btn-block"><i class="fa fas fa-sign-in-alt mr10" aria-hidden="true"></i><span data-submit-label><?php esc_html_e('登录', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<form data-auth-form="login">
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="target" id="<?php echo esc_attr($unique); ?>-login-target" class="line-form-input" autocomplete="username" tabindex="1" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php echo esc_html($signin_user_hint); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password" id="<?php echo esc_attr($unique); ?>-login-password" class="line-form-input" autocomplete="current-password" tabindex="2" placeholder="">
|
||||
<div class="scale-placeholder"><?php esc_html_e('登录密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('login'); } ?>
|
||||
<div class="relative line-form mb10 em09">
|
||||
<span class="muted-color form-checkbox"><input type="checkbox" id="<?php echo esc_attr($unique); ?>-remember" name="rememberme" value="1" checked="checked"><label for="<?php echo esc_attr($unique); ?>-remember" class="ml3"><?php esc_html_e('记住登录', 'jio'); ?></label></span>
|
||||
<span class="pull-right muted-2-color"><a class="muted-2-color" href="#<?php echo esc_attr($unique); ?>-tab-resetpassword" data-auth-tab="resetpassword"><?php esc_html_e('找回密码', 'jio'); ?></a></span>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>">
|
||||
<button type="submit" class="but radius jb-blue padding-lg btn-block"><i class="fa fas fa-sign-in-alt mr10" aria-hidden="true"></i><span data-submit-label><?php esc_html_e('登录', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php echo $social_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php if ($social_html !== '' && !empty($agreement['enabled'])) : ?><div class="muted-color mt10 text-center px12 opacity8"><?php esc_html_e('使用社交账号登录即表示同意', 'jio'); ?><?php echo $agreement['links_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($registration_open) : ?>
|
||||
<div class="tab-pane fade<?php echo $initial_tab === 'signup' ? ' active in' : ''; ?>" id="<?php echo esc_attr($unique); ?>-tab-sign-up" role="tabpanel" data-auth-panel="signup" <?php echo $initial_tab !== 'signup' ? 'hidden' : ''; ?>>
|
||||
<div class="box-body">
|
||||
<div class="title-h-left fa-2x"><?php echo $is_oauth_bind ? esc_html__('创建新账号', 'jio') : esc_html__('注册', 'jio'); ?></div>
|
||||
<a class="muted-color px12" href="#<?php echo esc_attr($unique); ?>-tab-sign-in" data-auth-tab="<?php echo $is_oauth_bind ? 'bind' : 'signin'; ?>"><?php esc_html_e('已有账号,立即登录', 'jio'); ?><i class="em12 ml3 fa fas fa-angle-right" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
<?php
|
||||
$register_fields = function () use ($unique, $oauth_name, $oauth_email, $signup_type, $signup_verify, $omit_confirm, $ref_mode, $ref_value, $ref_tooltip, $invite_mode, $invite_tooltip, $agreement, $is_oauth_bind, $obk) {
|
||||
?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="user_login" id="<?php echo esc_attr($unique); ?>-register-name" class="line-form-input" value="<?php echo esc_attr($oauth_name); ?>" autocomplete="username" tabindex="1" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('设置用户名', 'jio'); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="target" id="<?php echo esc_attr($unique); ?>-register-target" class="line-form-input" value="<?php echo esc_attr($oauth_email); ?>" autocomplete="<?php echo $signup_type === 'phone' ? 'tel' : 'email'; ?>" tabindex="2" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php echo $signup_type === 'phone' ? esc_html__('手机号', 'jio') : ($signup_type === 'email_phone' ? esc_html__('手机号或邮箱', 'jio') : esc_html__('邮箱', 'jio')); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if ($signup_verify) : ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="code" id="<?php echo esc_attr($unique); ?>-register-code" class="line-form-input" inputmode="numeric" maxlength="6" autocomplete="one-time-code" tabindex="3" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('验证码', 'jio'); ?></div>
|
||||
<span class="yztx abs-right"><button type="button" form-action="register" class="but c-blue captchsubmit" data-send-code="register"><?php esc_html_e('发送验证码', 'jio'); ?></button></span>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password" id="<?php echo esc_attr($unique); ?>-register-password" class="line-form-input" autocomplete="new-password" minlength="6" tabindex="4" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('设置密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if (!$omit_confirm) : ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password_confirm" id="<?php echo esc_attr($unique); ?>-register-confirm" class="line-form-input" autocomplete="new-password" minlength="6" tabindex="5" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('重复密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($ref_mode !== 'hidden') : ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="ref" id="<?php echo esc_attr($unique); ?>-register-ref" class="line-form-input" value="<?php echo esc_attr($ref_value); ?>" tabindex="6" placeholder="" <?php echo $ref_mode === 'required' ? 'required' : ''; ?>>
|
||||
<div class="scale-placeholder"><?php echo $ref_mode === 'required' ? esc_html__('推广码', 'jio') : esc_html__('推广码(选填)', 'jio'); ?></div>
|
||||
<?php if ($ref_tooltip !== '') : ?><div class="abs-right muted-2-color" data-toggle="tooltip" title="<?php echo esc_attr($ref_tooltip); ?>"><i class="fa fas fa-question-circle" aria-hidden="true"></i></div><?php endif; ?>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($invite_mode === 'optional') : ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="invite_code" id="<?php echo esc_attr($unique); ?>-register-invite" class="line-form-input" data-invite-verify tabindex="7" placeholder="">
|
||||
<div class="scale-placeholder"><?php esc_html_e('邀请码(选填)', 'jio'); ?></div>
|
||||
<?php if ($invite_tooltip !== '') : ?><div class="abs-right muted-2-color" data-toggle="tooltip" title="<?php echo esc_attr($invite_tooltip); ?>"><i class="fa fas fa-question-circle" aria-hidden="true"></i></div><?php endif; ?>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<small class="muted-2-color px12" data-invite-feedback role="status" aria-live="polite" hidden></small>
|
||||
<?php elseif ($invite_mode === 'required') : ?>
|
||||
<input type="hidden" name="invite_code" value="" data-invite-value>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($agreement['enabled'])) : ?>
|
||||
<?php if (!empty($agreement['required'])) : ?>
|
||||
<div class="form-checkbox muted-color mt10 text-center px12 opacity8"><input type="checkbox" name="agree_terms" value="1" id="<?php echo esc_attr($unique); ?>-register-agree" required><label for="<?php echo esc_attr($unique); ?>-register-agree" class="px12 ml6" style="font-weight:normal;"><?php echo $agreement['label_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label></div>
|
||||
<?php else : ?>
|
||||
<div class="muted-color mt10 text-center px12 opacity8"><?php esc_html_e('注册即表示同意', 'jio'); ?><?php echo $agreement['links_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('register'); } ?>
|
||||
<input type="hidden" name="channel" value="<?php echo esc_attr($signup_type === 'phone' ? 'phone' : ''); ?>">
|
||||
<input type="hidden" name="user_email" value="">
|
||||
<?php if ($is_oauth_bind) : ?><input type="hidden" name="obk" value="<?php echo esc_attr($obk); ?>"><?php endif; ?>
|
||||
<div class="box-body">
|
||||
<button type="submit" class="but radius jb-green padding-lg btn-block"><?php echo function_exists('jio_icon_markup') ? jio_icon_markup('jiosvg-signup', 'icon mr10') : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?><span data-submit-label><?php echo $is_oauth_bind ? esc_html__('绑定注册', 'jio') : esc_html__('注册', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<?php
|
||||
};
|
||||
?>
|
||||
<?php if ($invite_mode === 'required') : ?>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade active in" data-invite-gate-panel>
|
||||
<div class="mb10 flex jc" style="min-height:72px;"><div class="text-center"><?php echo wp_kses_post($invite_hint); ?></div></div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="invite_code" id="<?php echo esc_attr($unique); ?>-invite-gate" class="line-form-input" data-invite-verify data-invite-gate-input autocomplete="off" tabindex="1" placeholder="">
|
||||
<div class="scale-placeholder"><?php esc_html_e('请填写邀请码', 'jio'); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<small class="muted-2-color px12" data-invite-feedback role="status" aria-live="polite" hidden></small>
|
||||
<div class="box-body"><button type="button" class="but radius jb-blue padding-lg btn-block" data-invite-gate><?php esc_html_e('继续', 'jio'); ?><i class="em12 ml3 fa fas fa-angle-right" aria-hidden="true"></i></button></div>
|
||||
</div>
|
||||
<div class="tab-pane fade" data-invite-form-panel hidden>
|
||||
<form id="sign-up" data-auth-form="register"><?php $register_fields(); ?></form>
|
||||
</div>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<form id="sign-up" data-auth-form="register"><?php $register_fields(); ?></form>
|
||||
<?php endif; ?>
|
||||
<div class="sign-options"><label><input type="checkbox" name="rememberme" value="1"> <?php esc_html_e('记住登录', 'jio'); ?></label><button type="button" data-auth-tab="resetpassword"><?php esc_html_e('忘记密码?', 'jio'); ?></button></div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('login'); } ?>
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>">
|
||||
<button type="submit" class="sign-submit jb-blue"><span><?php esc_html_e('登录', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden></i></button>
|
||||
<?php if ($passwordless && $passwordless_mode !== 'only_nopas') : ?><button type="button" class="sign-mode-switch" data-login-mode><?php echo $passwordless_mode === 'pas' ? esc_html__('使用验证码登录', 'jio') : esc_html__('使用账号密码登录', 'jio'); ?></button><?php endif; ?>
|
||||
</form>
|
||||
<?php else : ?><div class="sign-notice"><?php esc_html_e('当前已关闭账号密码登录,请使用第三方登录。', 'jio'); ?></div><?php endif; ?>
|
||||
</section>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($registration_open) : ?>
|
||||
<section id="<?php echo esc_attr($unique); ?>-auth-panel-signup" class="sign-panel" role="tabpanel" data-auth-panel="signup" <?php echo $auth_tab !== 'signup' ? 'hidden' : ''; ?>>
|
||||
<div class="sign-header"><h2><?php echo $is_oauth_bind ? esc_html__('注册并绑定', 'jio') : esc_html__('注册', 'jio'); ?></h2><span><?php esc_html_e('已有账号?', 'jio'); ?> <button type="button" data-auth-tab="<?php echo $is_oauth_bind ? 'bind' : 'signin'; ?>"><?php esc_html_e('立即登录', 'jio'); ?></button></span></div>
|
||||
<form class="sign-form" data-auth-form="register">
|
||||
<div class="floating-input"><input name="user_login" value="<?php echo esc_attr($oauth_name); ?>" id="<?php echo esc_attr($unique); ?>-register-name" autocomplete="username" required><label for="<?php echo esc_attr($unique); ?>-register-name"><?php esc_html_e('用户名', 'jio'); ?></label></div>
|
||||
<div class="floating-input"><input name="target" value="<?php echo esc_attr($oauth_email); ?>" id="<?php echo esc_attr($unique); ?>-register-target" autocomplete="<?php echo $signup_type === 'phone' ? 'tel' : 'email'; ?>" required><label for="<?php echo esc_attr($unique); ?>-register-target"><?php echo $signup_type === 'phone' ? esc_html__('手机号', 'jio') : ($signup_type === 'email_phone' ? esc_html__('邮箱 / 手机号', 'jio') : esc_html__('邮箱', 'jio')); ?></label></div>
|
||||
<?php if ($signup_verify) : ?><div class="floating-input has-action"><input name="code" inputmode="numeric" maxlength="6" id="<?php echo esc_attr($unique); ?>-register-code" required><label for="<?php echo esc_attr($unique); ?>-register-code"><?php esc_html_e('验证码', 'jio'); ?></label><button type="button" class="send-code" data-send-code="register"><?php esc_html_e('发送验证码', 'jio'); ?></button></div><?php endif; ?>
|
||||
<div class="floating-input has-action"><input type="password" name="password" id="<?php echo esc_attr($unique); ?>-register-password" autocomplete="new-password" minlength="6" required><label for="<?php echo esc_attr($unique); ?>-register-password"><?php esc_html_e('密码', 'jio'); ?></label><button type="button" class="password-show" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye"></i></button></div>
|
||||
<?php if (!$omit_confirm) : ?><div class="floating-input has-action"><input type="password" name="password_confirm" id="<?php echo esc_attr($unique); ?>-register-confirm" autocomplete="new-password" minlength="6" required><label for="<?php echo esc_attr($unique); ?>-register-confirm"><?php esc_html_e('重复密码', 'jio'); ?></label><button type="button" class="password-show" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye"></i></button></div><?php endif; ?>
|
||||
<?php if ($ref_mode !== 'hidden') : ?><div class="floating-input"><input name="ref" value="<?php echo esc_attr($ref_value); ?>" id="<?php echo esc_attr($unique); ?>-register-ref" <?php echo $ref_mode === 'required' ? 'required' : ''; ?>><label for="<?php echo esc_attr($unique); ?>-register-ref"><?php echo $ref_mode === 'required' ? esc_html__('推广码', 'jio') : esc_html__('推广码(选填)', 'jio'); ?></label></div><?php if ($ref_hint !== '') : ?><div class="sign-hint"><?php echo wp_kses_post($ref_hint); ?></div><?php endif; ?><?php endif; ?>
|
||||
<?php if ($invite_mode !== 'hidden') : ?><div class="floating-input"><input name="invite_code" id="<?php echo esc_attr($unique); ?>-register-invite" data-invite-verify <?php echo $invite_mode === 'required' ? 'required' : ''; ?>><label for="<?php echo esc_attr($unique); ?>-register-invite"><?php echo $invite_mode === 'required' ? esc_html__('邀请码', 'jio') : esc_html__('邀请码(选填)', 'jio'); ?></label></div><small class="sign-hint" data-invite-feedback role="status" aria-live="polite" hidden></small><?php if ($invite_hint !== '') : ?><div class="sign-hint"><?php echo wp_kses_post($invite_hint); ?></div><?php endif; ?><?php endif; ?>
|
||||
<?php if (!empty($agreement['enabled']) && !empty($agreement['required'])) : ?><label class="sign-agreement"><input type="checkbox" name="agree_terms" value="1" required><span><?php echo $agreement['label_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span></label><?php elseif (!empty($agreement['enabled'])) : ?><div class="sign-agreement sign-agreement-implicit"><?php esc_html_e('注册即表示', 'jio'); ?><?php echo $agreement['label_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div><?php endif; ?>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('register'); } ?>
|
||||
<input type="hidden" name="channel" value="<?php echo esc_attr($signup_type === 'phone' ? 'phone' : ''); ?>">
|
||||
<input type="hidden" name="user_email" value="">
|
||||
<?php if ($is_oauth_bind) : ?><input type="hidden" name="obk" value="<?php echo esc_attr($obk); ?>"><?php endif; ?>
|
||||
<button type="submit" class="sign-submit jb-green"><span><?php esc_html_e('注册', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden></i></button>
|
||||
</form>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
<div class="tab-pane fade<?php echo $initial_tab === 'resetpassword' ? ' active in' : ''; ?>" id="<?php echo esc_attr($unique); ?>-tab-resetpassword" role="tabpanel" data-auth-panel="resetpassword" <?php echo $initial_tab !== 'resetpassword' ? 'hidden' : ''; ?>>
|
||||
<div class="box-body">
|
||||
<div class="title-h-left fa-2x"><?php esc_html_e('找回密码', 'jio'); ?></div>
|
||||
<a class="muted-color px12" href="#<?php echo esc_attr($unique); ?>-tab-sign-in" data-auth-tab="signin"><?php esc_html_e('登录', 'jio'); ?></a><i class="icon-spot"></i><?php if ($registration_open) : ?><a class="muted-color px12" href="#<?php echo esc_attr($unique); ?>-tab-sign-up" data-auth-tab="signup"><?php esc_html_e('注册', 'jio'); ?></a><?php endif; ?>
|
||||
</div>
|
||||
<form data-auth-form="reset-password">
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="target" id="<?php echo esc_attr($unique); ?>-reset-target" class="line-form-input" autocomplete="username" tabindex="1" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php echo $reset_type === 'phone' ? esc_html__('手机号', 'jio') : ($reset_type === 'email_phone' ? esc_html__('手机号或邮箱', 'jio') : esc_html__('邮箱', 'jio')); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('lostpassword'); } ?>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="code" id="<?php echo esc_attr($unique); ?>-reset-code" class="line-form-input" inputmode="numeric" maxlength="6" autocomplete="one-time-code" tabindex="2" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('验证码', 'jio'); ?></div>
|
||||
<span class="yztx abs-right"><button type="button" form-action="resetpassword" class="but c-blue captchsubmit" data-send-code="resetpassword"><?php esc_html_e('发送验证码', 'jio'); ?></button></span>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password" id="<?php echo esc_attr($unique); ?>-reset-password" class="line-form-input" autocomplete="new-password" minlength="6" tabindex="3" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('设置新密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password_confirm" id="<?php echo esc_attr($unique); ?>-reset-confirm" class="line-form-input" autocomplete="new-password" minlength="6" tabindex="4" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('重复密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<input type="hidden" name="channel" value="<?php echo esc_attr($reset_type === 'phone' ? 'phone' : ''); ?>">
|
||||
<div class="box-body">
|
||||
<button type="submit" class="but radius jb-green padding-lg btn-block"><i class="fa fas fa-unlock-alt mr10" aria-hidden="true"></i><span data-submit-label><?php esc_html_e('确认提交', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<section id="<?php echo esc_attr($unique); ?>-auth-panel-resetpassword" class="sign-panel" role="tabpanel" data-auth-panel="resetpassword" <?php echo $auth_tab !== 'resetpassword' ? 'hidden' : ''; ?>>
|
||||
<div class="sign-header"><h2><?php esc_html_e('找回密码', 'jio'); ?></h2><span><button type="button" data-auth-tab="signin"><?php esc_html_e('返回登录', 'jio'); ?></button></span></div>
|
||||
<form class="sign-form" data-auth-form="reset-password">
|
||||
<div class="floating-input"><input name="target" id="<?php echo esc_attr($unique); ?>-reset-target" required><label for="<?php echo esc_attr($unique); ?>-reset-target"><?php echo $reset_type === 'phone' ? esc_html__('手机号', 'jio') : ($reset_type === 'email_phone' ? esc_html__('邮箱 / 手机号', 'jio') : esc_html__('邮箱', 'jio')); ?></label></div>
|
||||
<div class="floating-input has-action"><input name="code" inputmode="numeric" maxlength="6" id="<?php echo esc_attr($unique); ?>-reset-code" required><label for="<?php echo esc_attr($unique); ?>-reset-code"><?php esc_html_e('验证码', 'jio'); ?></label><button type="button" class="send-code" data-send-code="resetpassword"><?php esc_html_e('发送验证码', 'jio'); ?></button></div>
|
||||
<div class="floating-input has-action"><input type="password" name="password" id="<?php echo esc_attr($unique); ?>-reset-password" minlength="6" required><label for="<?php echo esc_attr($unique); ?>-reset-password"><?php esc_html_e('新密码', 'jio'); ?></label><button type="button" class="password-show" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye"></i></button></div>
|
||||
<div class="floating-input has-action"><input type="password" name="password_confirm" id="<?php echo esc_attr($unique); ?>-reset-confirm" minlength="6" required><label for="<?php echo esc_attr($unique); ?>-reset-confirm"><?php esc_html_e('重复新密码', 'jio'); ?></label><button type="button" class="password-show" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye"></i></button></div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('lostpassword'); } ?>
|
||||
<input type="hidden" name="channel" value="<?php echo esc_attr($reset_type === 'phone' ? 'phone' : ''); ?>">
|
||||
<button type="submit" class="sign-submit jb-blue"><span><?php esc_html_e('重置密码', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden></i></button>
|
||||
</form>
|
||||
</section>
|
||||
<?php if ($wechat_qr) : ?>
|
||||
<div class="tab-pane fade<?php echo $initial_tab === 'oauth' ? ' active in' : ''; ?>" id="<?php echo esc_attr($unique); ?>-tab-qrcode-signin" role="tabpanel" data-auth-panel="oauth" <?php echo $initial_tab !== 'oauth' ? 'hidden' : ''; ?>>
|
||||
<div class="box-body">
|
||||
<div class="title-h-left fa-2x"><?php esc_html_e('扫码登录', 'jio'); ?></div>
|
||||
<span class="muted-3-color px12"><?php esc_html_e('使用', 'jio'); ?><a class="muted-color" href="#<?php echo esc_attr($unique); ?>-tab-sign-in" data-auth-tab="signin"><?php esc_html_e('其它方式登录', 'jio'); ?></a><?php echo $registration_open ? esc_html__('或', 'jio') . '<a class="muted-color" href="#' . esc_attr($unique) . '-tab-sign-up" data-auth-tab="signup">' . esc_html__('注册', 'jio') . '</a>' : ''; ?></span>
|
||||
</div>
|
||||
<div class="qrcode-signin-container box-body text-center" data-auth-qrcode>
|
||||
<div data-auth-qr-content><p class="placeholder" style="height:180px;width:180px;margin:auto;"></p><p class="placeholder" style="height:27px;width:200px;margin:15px auto 0;"></p></div>
|
||||
<p class="screen-reader-text" data-auth-qr-status role="status" aria-live="polite" aria-atomic="true"><?php esc_html_e('正在获取二维码', 'jio'); ?></p>
|
||||
</div>
|
||||
<?php if (!empty($agreement['enabled'])) : ?><div class="muted-color mt10 text-center px12 opacity8"><?php esc_html_e('扫码登录即表示同意', 'jio'); ?><?php echo $agreement['links_html']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div><?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<section id="<?php echo esc_attr($unique); ?>-auth-panel-oauth" class="sign-panel" role="tabpanel" data-auth-panel="oauth" <?php echo $auth_tab !== 'oauth' ? 'hidden' : ''; ?>>
|
||||
<div class="sign-header"><h2><?php esc_html_e('社交登录', 'jio'); ?></h2><span><button type="button" data-auth-tab="signin"><?php esc_html_e('返回登录', 'jio'); ?></button></span></div>
|
||||
<?php if ($wechat_qr) : ?><div class="auth-qrcode" data-auth-qrcode><div data-auth-qr-content><i class="fa fab fa-weixin" aria-hidden="true"></i><span><?php esc_html_e('获取二维码中…', 'jio'); ?></span></div><p class="auth-qrcode-status screen-reader-text" data-auth-qr-status role="status" aria-live="polite" aria-atomic="true"><?php esc_html_e('正在获取二维码', 'jio'); ?></p></div><?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section id="<?php echo esc_attr($unique); ?>-auth-panel-bind" class="sign-panel" role="tabpanel" data-auth-panel="bind" <?php echo $auth_tab !== 'bind' ? 'hidden' : ''; ?>>
|
||||
<div class="sign-header"><h2><?php esc_html_e('绑定账号', 'jio'); ?></h2><?php if ($is_oauth_bind && $registration_open) : ?><span><?php esc_html_e('没有账号?', 'jio'); ?> <button type="button" data-auth-tab="signup"><?php esc_html_e('立即注册', 'jio'); ?></button></span><?php endif; ?></div>
|
||||
<?php if ($is_oauth_bind) : ?>
|
||||
<div class="sign-notice"><?php printf(esc_html__('通过 %s 登录,请绑定已有账号。', 'jio'), esc_html($oauth_provider_name)); ?></div>
|
||||
<form class="sign-form" data-auth-form="login">
|
||||
<div class="floating-input"><input name="target" id="<?php echo esc_attr($unique); ?>-bind-target" autocomplete="username" required><label for="<?php echo esc_attr($unique); ?>-bind-target"><?php echo $signin_phone ? esc_html__('邮箱 / 手机号 / 用户名', 'jio') : esc_html__('邮箱 / 用户名', 'jio'); ?></label></div>
|
||||
<div class="floating-input has-action"><input type="password" name="password" id="<?php echo esc_attr($unique); ?>-bind-password" autocomplete="current-password" required><label for="<?php echo esc_attr($unique); ?>-bind-password"><?php esc_html_e('密码', 'jio'); ?></label><button type="button" class="password-show" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye"></i></button></div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('bind'); } ?>
|
||||
<input type="hidden" name="obk" value="<?php echo esc_attr($obk); ?>">
|
||||
<input type="hidden" name="rememberme" value="1">
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>">
|
||||
<button type="submit" class="sign-submit jb-blue"><span><?php esc_html_e('登录并绑定', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden></i></button>
|
||||
</form>
|
||||
<?php else : ?><div class="sign-notice"><?php esc_html_e('绑定会话已过期,请重新使用第三方登录。', 'jio'); ?></div><?php endif; ?>
|
||||
</section>
|
||||
|
||||
<?php if (!empty($oauth_providers) && !$is_oauth_bind) : ?>
|
||||
<div class="social-login"><span><?php esc_html_e('其他登录方式', 'jio'); ?></span><div class="social-login-buttons">
|
||||
<?php foreach ($oauth_providers as $provider) : ?><?php if (($provider['name'] ?? '') === 'weixingzh') continue; ?><?php $provider_label = (string) ($provider['label'] ?? $provider['name'] ?? ''); ?><a class="social-login-item <?php echo esc_attr((string) ($provider['name'] ?? '')); ?>" href="<?php echo esc_url((string) ($provider['url'] ?? '#')); ?>" data-provider="<?php echo esc_attr((string) ($provider['name'] ?? '')); ?>" aria-label="<?php echo esc_attr(sprintf(__('%s登录', 'jio'), $provider_label)); ?>" title="<?php echo esc_attr($provider_label); ?>"><?php echo $provider['icon'] ?? ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?><?php if ($oauth_large) : ?><span><?php printf(esc_html__('%s登录', 'jio'), esc_html($provider_label)); ?></span><?php endif; ?></a><?php endforeach; ?>
|
||||
<?php if ($wechat_qr) : ?><button type="button" class="social-login-item weixingzh" data-auth-tab="oauth" aria-label="<?php esc_attr_e('微信扫码登录', 'jio'); ?>" title="<?php esc_attr_e('微信扫码登录', 'jio'); ?>"><i class="fa fab fa-weixin" aria-hidden="true"></i><?php if ($oauth_large) : ?><span><?php esc_html_e('微信登录', 'jio'); ?></span><?php endif; ?></button><?php endif; ?>
|
||||
</div></div>
|
||||
<?php endif; ?>
|
||||
<div class="tab-pane fade<?php echo $initial_tab === 'bind' ? ' active in' : ''; ?>" id="<?php echo esc_attr($unique); ?>-tab-bind" role="tabpanel" data-auth-panel="bind" <?php echo $initial_tab !== 'bind' ? 'hidden' : ''; ?>>
|
||||
<?php if ($is_oauth_bind) : ?>
|
||||
<div class="oauth-data-box">
|
||||
<div class="muted-box">
|
||||
<div class="user-info flex ac relative">
|
||||
<span class="avatar-img mr6"><img alt="<?php esc_attr_e('头像', 'jio'); ?>" src="<?php echo esc_url($oauth_avatar); ?>" class="avatar"></span>
|
||||
<div class="flex1 ml10"><b><?php printf(esc_html__('您好!%s', 'jio'), esc_html($oauth_name !== '' ? $oauth_name : $oauth_provider_name)); ?></b><div class="mt6 px12 muted-2-color"><?php printf(esc_html__('您首次使用此%1$s账号登录', 'jio'), '<b class="badg badg-sm c-blue">' . esc_html($oauth_provider_name) . '</b>'); ?><br><?php esc_html_e('请先绑定已有账号或创建新账号', 'jio'); ?></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="title-h-left em14"><?php esc_html_e('绑定账号', 'jio'); ?></div>
|
||||
<?php if ($registration_open) : ?><a class="muted-color px12" href="#<?php echo esc_attr($unique); ?>-tab-sign-up" data-auth-tab="signup"><?php esc_html_e('没有账号?创建新账号', 'jio'); ?><i class="em12 ml3 fa fas fa-angle-right" aria-hidden="true"></i></a><?php endif; ?>
|
||||
</div>
|
||||
<form data-auth-form="login">
|
||||
<div class="relative line-form mb10">
|
||||
<input type="text" name="target" id="<?php echo esc_attr($unique); ?>-bind-target" class="line-form-input" autocomplete="username" tabindex="1" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php echo esc_html($signin_user_hint); ?></div>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<div class="relative line-form mb10">
|
||||
<input type="password" name="password" id="<?php echo esc_attr($unique); ?>-bind-password" class="line-form-input" autocomplete="current-password" tabindex="2" placeholder="" required>
|
||||
<div class="scale-placeholder"><?php esc_html_e('登录密码', 'jio'); ?></div>
|
||||
<button type="button" class="abs-right sign-passw muted-2-color" data-password-show aria-label="<?php esc_attr_e('显示密码', 'jio'); ?>" aria-pressed="false"><i class="fa fas fa-eye" aria-hidden="true"></i></button>
|
||||
<i class="line-form-line"></i>
|
||||
</div>
|
||||
<?php if (function_exists('jio_render_captcha')) { jio_render_captcha('bind'); } ?>
|
||||
<input type="hidden" name="obk" value="<?php echo esc_attr($obk); ?>">
|
||||
<input type="hidden" name="rememberme" value="1">
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($redirect_to); ?>">
|
||||
<div class="box-body">
|
||||
<button type="submit" class="but radius jb-blue padding-lg btn-block"><i class="fa fas fa-sign-in-alt mr10" aria-hidden="true"></i><span data-submit-label><?php esc_html_e('绑定登录', 'jio'); ?></span><i class="fa fas fa-spinner fa-spin" hidden aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
<?php else : ?>
|
||||
<div class="box-body">
|
||||
<div class="title-h-left fa-2x"><?php esc_html_e('绑定账号', 'jio'); ?></div>
|
||||
</div>
|
||||
<div class="box-body"><div class="c-red px12"><i class="fa fas fa-info-circle mr6" aria-hidden="true"></i><?php esc_html_e('绑定会话已过期,请重新使用第三方登录。', 'jio'); ?></div></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,7 +17,6 @@ $image_id = $images ? (int) $images[array_rand($images)] : 0;
|
||||
$image_html = $image_id > 0 ? wp_get_attachment_image($image_id, 'full', false, [
|
||||
'class' => 'fit-cover radius8',
|
||||
'alt' => get_bloginfo('name'),
|
||||
'loading' => 'lazy',
|
||||
'decoding' => 'async',
|
||||
]) : '';
|
||||
$auto = class_exists('\Jio\Settings\Settings') ? \Jio\Settings\Settings::sign_modal_auto() : ['enabled' => false, 'waiting' => 5, 'expires' => 1];
|
||||
@@ -30,13 +29,11 @@ $jio_auth_context = [
|
||||
'redirect_to' => home_url('/'),
|
||||
];
|
||||
?>
|
||||
<div id="u_sign" class="jio-auth-modal<?php echo $image_html !== '' ? ' has-sign-img' : ''; ?>" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="jio-auth-modal-title" tabindex="-1" data-auth-modal data-auto="<?php echo !empty($auto['enabled']) ? '1' : '0'; ?>" data-auto-wait="<?php echo esc_attr((string) $auto['waiting']); ?>" data-auto-expires="<?php echo esc_attr((string) $auto['expires']); ?>">
|
||||
<h2 id="jio-auth-modal-title" class="screen-reader-text"><?php esc_html_e('账户登录与注册', 'jio'); ?></h2>
|
||||
<div class="auth-modal-backdrop" data-auth-close></div>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<button type="button" class="auth-modal-close" data-auth-close aria-label="<?php esc_attr_e('关闭', 'jio'); ?>"><i class="fa fas fa-times"></i></button>
|
||||
<?php if ($image_html !== '') : ?><div class="sign-img"><?php echo $image_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div><?php endif; ?>
|
||||
<div id="u_sign" class="modal jio-auth-modal<?php echo $image_html !== '' ? ' has-sign-img' : ''; ?>" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="jio-auth-modal-title" tabindex="-1" data-auth-modal data-auto="<?php echo !empty($auto['enabled']) ? '1' : '0'; ?>" data-auto-wait="<?php echo esc_attr((string) $auto['waiting']); ?>" data-auto-expires="<?php echo esc_attr((string) $auto['expires']); ?>">
|
||||
<h2 id="jio-auth-modal-title" class="screen-reader-text"><?php esc_html_e('账户登录与注册', 'jio'); ?></h2>
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="sign-content">
|
||||
<?php if ($image_html !== '') : ?><div class="sign-img absolute hide-sm"><?php echo $image_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div><?php endif; ?>
|
||||
<?php require get_template_directory() . '/templates/parts/auth-content.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,15 +28,20 @@ test('modal and sign page use one renderer and one state machine', () => {
|
||||
assert.doesNotMatch(loader, /sign-register/);
|
||||
});
|
||||
|
||||
test('static authentication dimensions and responsive contract are retained', () => {
|
||||
const css = read('assets/css/routes/sign.css');
|
||||
assert.match(css, /\.sign\s*\{[\s\S]*?max-width:\s*330px/);
|
||||
assert.match(css, /#u_sign\.has-sign-img \.modal-dialog\s*\{\s*width:\s*800px/);
|
||||
assert.match(css, /#u_sign \.sign-img\s*\{[^}]*inset:\s*0 45% 0 0;[^}]*padding:\s*0/);
|
||||
assert.match(css, /#u_sign \.sign-img \+ \.sign\s*\{[^}]*margin-left:\s*55%/);
|
||||
assert.match(css, /\.social-login-item\s*\{[\s\S]*?width:\s*32px;[\s\S]*?height:\s*32px/);
|
||||
assert.match(css, /\.auth-qrcode\s*\{[\s\S]*?width:\s*180px;[\s\S]*?min-height:\s*180px/);
|
||||
assert.match(css, /@media \(max-width:\s*767px\)[\s\S]*?\.sign-img\s*\{\s*display:\s*none/);
|
||||
test('authentication shell reuses the shared sign-card CSS contract', () => {
|
||||
// Card width, the 800px split dialog, the 55% card offset, the 32px social
|
||||
// items and the QR box all live in the shared theme stylesheet now.
|
||||
const mainCss = read('assets/css/main.css');
|
||||
const signCss = read('assets/css/routes/sign.css');
|
||||
assert.match(mainCss, /\.sign\s*\{[\s\S]*?max-width:\s*330px/);
|
||||
assert.match(mainCss, /#u_sign \.modal-dialog\s*\{\s*width:\s*800px;/);
|
||||
assert.match(mainCss, /\.sign-img \+ \.sign\s*\{[\s\S]*?margin-left:\s*55%/);
|
||||
assert.match(mainCss, /\.social-login-item\s*\{[\s\S]*?width:\s*32px !important;[\s\S]*?height:\s*32px !important/);
|
||||
assert.match(mainCss, /\.qrcode-signin-container\s*\{[\s\S]*?min-height:\s*254px/);
|
||||
assert.match(mainCss, /\.signin-qrcode-img\s*\{[\s\S]*?width:\s*180px/);
|
||||
assert.match(mainCss, /#u_sign \.modal-dialog\s*\{\s*width:\s*800px;/);
|
||||
assert.match(signCss, /\.sign-page \.sign\s*\{\s*width:\s*350px/);
|
||||
assert.match(signCss, /@media \(max-width:\s*767px\)[\s\S]*?\.sign-page \.sign\s*\{[\s\S]*?width:\s*340px/);
|
||||
});
|
||||
|
||||
test('authentication settings use reference defaults and canonical keys', () => {
|
||||
@@ -72,10 +77,10 @@ test('authentication galleries save attachment IDs and are consumed by both surf
|
||||
assert.match(reader, /auth_gallery_ids\('sign_modal_background'\)/);
|
||||
assert.match(reader, /auth_gallery_ids\('sign_page_background'\)/);
|
||||
assert.match(modal, /wp_get_attachment_image\(\$image_id, 'full'/);
|
||||
assert.match(modal, /<div class="sign-img"><\?php echo \$image_html/);
|
||||
assert.match(modal, /<div class="sign-img absolute hide-sm"><\?php echo \$image_html/);
|
||||
assert.match(page, /wp_get_attachment_image_url\(\$background_id, 'full'\)/);
|
||||
assert.match(page, /<div class="sign-page-background" style="background-image:url/);
|
||||
assert.match(css, /\.sign-img img\s*\{[\s\S]*?object-fit:\s*cover/);
|
||||
assert.match(page, /<div class="fixed lazyload" data-bg="<\?php echo esc_url\(\$background_url\)/);
|
||||
assert.match(css, /#u_sign \.sign-img img\s*\{[\s\S]*?object-fit:\s*cover/);
|
||||
assert.doesNotMatch(modal + page, /is_string\(\$images\)|explode\(',', \$images\)/);
|
||||
});
|
||||
|
||||
@@ -163,18 +168,19 @@ test('shared renderer contracts every configured authentication state', () => {
|
||||
const modal = read('templates/parts/modal-auth.php');
|
||||
const client = read('assets/js/auth.js');
|
||||
|
||||
assert.match(shared, /data-auth-password-fields/);
|
||||
assert.match(shared, /data-auth-code-fields/);
|
||||
assert.match(shared, /data-login-mode/);
|
||||
assert.match(shared, /data-signin-panel="nopas"/);
|
||||
assert.match(shared, /data-signin-panel="pas"/);
|
||||
assert.match(shared, /data-signin-mode="pas"/);
|
||||
['login', 'register', 'resetpassword'].forEach((scene) => {
|
||||
assert.match(shared, new RegExp(`data-send-code="${scene}"`));
|
||||
});
|
||||
assert.match(shared, /\$omit_confirm/);
|
||||
assert.match(shared, /\$ref_mode !== 'hidden'/);
|
||||
assert.match(shared, /\$ref_mode === 'required'/);
|
||||
assert.match(shared, /sign-agreement-implicit/);
|
||||
assert.match(shared, /data-invite-gate-panel/);
|
||||
assert.match(shared, /data-invite-form-panel/);
|
||||
assert.match(shared, /name="agree_terms"[\s\S]*?required/);
|
||||
assert.match(shared, /oauth-button-lg/);
|
||||
assert.match(shared, /render_social_buttons\(__\('社交账号登录'/);
|
||||
assert.match(shared, /data-auth-qrcode/);
|
||||
assert.match(modal, /data-auto=/);
|
||||
assert.match(client, /jioAuthAutoUntil/);
|
||||
@@ -220,8 +226,8 @@ test('OAuth frontend is accessible, redirect-aware, and removes retired provider
|
||||
assert.match(client, /setAttribute\('aria-label', visible \? '隐藏密码' : '显示密码'\)/);
|
||||
assert.match(client, /setAttribute\('aria-pressed', visible \? 'true' : 'false'\)/);
|
||||
assert.match(shared, /data-auth-qr-status[^>]*role="status"[^>]*aria-live="polite"/);
|
||||
assert.match(shared, /data-provider=/);
|
||||
assert.match(shared, /aria-label="<\?php echo esc_attr\(sprintf/);
|
||||
assert.match(read('src/Auth/OAuth.php'), /data-provider="' \. esc_attr\(\$name\)/);
|
||||
assert.match(read('src/Auth/OAuth.php'), /aria-label="' \. esc_attr\(sprintf/);
|
||||
assert.match(client, /searchParams\.set\('redirect_to', redirect\)/);
|
||||
|
||||
assert.match(client, /oauth_action/);
|
||||
@@ -240,14 +246,15 @@ test('OAuth frontend is accessible, redirect-aware, and removes retired provider
|
||||
assert.match(mainCss, /\.pay-box \.but\.baidu/);
|
||||
});
|
||||
|
||||
test('the social-login area drops the implicit agreement line', () => {
|
||||
test('agreement copy sits under each panel, not under the user card', () => {
|
||||
const shared = read('templates/parts/auth-content.php');
|
||||
const userRenderer = read('src/WidgetSystem/Renderers/UserRenderer.php');
|
||||
|
||||
// The reference shows no agreement copy under the social buttons; only the
|
||||
// registration panel keeps its own, and it stays reachable.
|
||||
assert.doesNotMatch(shared, /使用社交账号登录即表示/);
|
||||
assert.match(shared, /注册即表示/);
|
||||
// The sign-in column states the social agreement, the registration panel
|
||||
// states its own, and the compact user card carries neither line.
|
||||
assert.match(shared, /使用社交账号登录即表示同意/);
|
||||
assert.match(shared, /扫码登录即表示同意/);
|
||||
assert.match(shared, /注册即表示同意/);
|
||||
assert.match(shared, /name="agree_terms"[\s\S]*?required/);
|
||||
assert.doesNotMatch(userRenderer, /使用社交账号登录即表示|我已阅读并同意/);
|
||||
});
|
||||
@@ -308,7 +315,7 @@ test('provider URLs stay raw in the data layer and are escaped once per surface'
|
||||
assert.match(oauth, /'url'\s*=>\s*\$url,/);
|
||||
|
||||
// Every consumer still escapes on output, so the rendered href is unchanged.
|
||||
assert.match(shared, /esc_url\(\(string\) \(\$provider\['url'\] \?\? '#'\)\)/);
|
||||
assert.match(oauth, /href="' \. esc_url\(\$url\) \. '" class="' \. esc_attr\(\$class\)/);
|
||||
assert.match(userRenderer, /href="' \. esc_url\(\$url\)/);
|
||||
assert.match(oauth, /'<a rel="nofollow" href="' \. esc_url\(\$url\)/);
|
||||
assert.match(comments, /<a href="<\?php echo esc_url\(\$url\); \?\>" class="but hollow social-login-item ml10">/);
|
||||
|
||||
@@ -68,6 +68,7 @@ test('theme initializes when the removed jio namespace is absent', () => {
|
||||
getElementById() { return null; },
|
||||
createElement() { return { setAttribute() {} }; },
|
||||
dispatchEvent() {},
|
||||
addEventListener() {},
|
||||
};
|
||||
const window = {
|
||||
document,
|
||||
|
||||
@@ -36,6 +36,7 @@ function is_user_logged_in(): bool { return false; }
|
||||
function get_current_user_id(): int { return 0; }
|
||||
function wp_max_upload_size(): int { return 1048576; }
|
||||
function is_page_template(string $template = ''): bool { return false; }
|
||||
function apply_filters(string $hook, $value) { return $value; }
|
||||
function jio_is_lazy(string $scope): bool { return false; }
|
||||
function jio_get_lazy_thumb(string $size = ''): string { return 'https://example.test/lazy.svg'; }
|
||||
function jio_get_default_avatar_url(): string { return 'https://example.test/avatar.png'; }
|
||||
|
||||
Reference in new issue
Block a user