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
@@ -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