Login and Registration: Add a "Show password" button on the login page.

The ability for users to see the password they're typing improves usability and accessibility of the login users flow.

- brings the login screen in line with the same feature already used in the New User, Edit User, and Reset Password pages
- improves association of labels and input fields by using explicit association with `for` / `id` attributes
- slightly increases the "Remember me" label font size

Props johnbillion, Iceable, audrasjb, joyously, adamsilverstein, boemedia, DrewAPicture, shadyvb, birgire, peterwilsoncc, pento, anevins, davidbaumwald, whyisjake, afercia.
Fixes #42888.


git-svn-id: https://develop.svn.wordpress.org/trunk@46256 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrea Fercia 2019-09-23 18:05:16 +00:00
parent 03fe23cc8a
commit 0ff03b3290
5 changed files with 124 additions and 173 deletions

View File

@ -7,10 +7,7 @@
var updateLock = false,
$pass1Row,
$pass1Wrap,
$pass1,
$pass1Text,
$pass1Label,
$pass2,
$weakRow,
$weakCheckbox,
@ -36,7 +33,7 @@
}
if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
$pass1Wrap.addClass( 'show-password' );
$pass1.attr( 'type', 'text' );
} else {
$toggleButton.trigger( 'click' );
}
@ -48,28 +45,6 @@
function bindPass1() {
currentPass = $pass1.val();
$pass1Wrap = $pass1.parent();
$pass1Text = $( '<input type="text"/>' )
.attr( {
'id': 'pass1-text',
'name': 'pass1-text',
'autocomplete': 'off'
} )
.addClass( $pass1[0].className )
.data( 'pw', $pass1.data( 'pw' ) )
.val( $pass1.val() )
.on( 'input', function () {
if ( $pass1Text.val() === currentPass ) {
return;
}
$pass2.val( $pass1Text.val() );
$pass1.val( $pass1Text.val() ).trigger( 'pwupdate' );
currentPass = $pass1Text.val();
} );
$pass1.after( $pass1Text );
if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
generatePassword();
}
@ -80,64 +55,40 @@
}
currentPass = $pass1.val();
if ( $pass1Text.val() !== currentPass ) {
$pass1Text.val( currentPass );
}
$pass1.add( $pass1Text ).removeClass( 'short bad good strong' );
$pass1.removeClass( 'short bad good strong' );
showOrHideWeakPasswordCheckbox();
} );
}
function resetToggle() {
function resetToggle( show ) {
$toggleButton
.data( 'toggle', 0 )
.attr({
'aria-label': userProfileL10n.ariaHide
'aria-label': show ? userProfileL10n.ariaShow : userProfileL10n.ariaHide
})
.find( '.text' )
.text( userProfileL10n.hide )
.text( show ? userProfileL10n.show : userProfileL10n.hide )
.end()
.find( '.dashicons' )
.removeClass( 'dashicons-visibility' )
.addClass( 'dashicons-hidden' );
$pass1Text.focus();
$pass1Label.attr( 'for', 'pass1-text' );
.removeClass( show ? 'dashicons-hidden' : 'dashicons-visibility' )
.addClass( show ? 'dashicons-visibility' : 'dashicons-hidden' );
}
function bindToggleButton() {
$toggleButton = $pass1Row.find('.wp-hide-pw');
$toggleButton.show().on( 'click', function () {
if ( 1 === parseInt( $toggleButton.data( 'toggle' ), 10 ) ) {
$pass1Wrap.addClass( 'show-password' );
resetToggle();
if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
$pass1Text[0].setSelectionRange( 0, 100 );
}
if ( 'password' === $pass1.attr( 'type' ) ) {
$pass1.attr( 'type', 'text' );
resetToggle( false );
} else {
$pass1Wrap.removeClass( 'show-password' );
$toggleButton
.data( 'toggle', 1 )
.attr({
'aria-label': userProfileL10n.ariaShow
})
.find( '.text' )
.text( userProfileL10n.show )
.end()
.find( '.dashicons' )
.removeClass('dashicons-hidden')
.addClass('dashicons-visibility');
$pass1.attr( 'type', 'password' );
resetToggle( true );
}
$pass1.focus();
$pass1.focus();
$pass1Label.attr( 'for', 'pass1' );
if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
$pass1[0].setSelectionRange( 0, 100 );
}
if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
$pass1[0].setSelectionRange( 0, 100 );
}
});
}
@ -147,10 +98,9 @@
$generateButton,
$cancelButton;
$pass1Row = $('.user-pass1-wrap');
$pass1Label = $pass1Row.find('th label').attr( 'for', 'pass1-text' );
$pass1Row = $( '.user-pass1-wrap, .user-pass-wrap' );
// hide this
// Hide the confirm password field when JavaScript support is enabled.
$('.user-pass2-wrap').hide();
$submitButton = $( '#submit, #wp-submit' ).on( 'click', function () {
@ -168,6 +118,9 @@
$pass1 = $('#pass1');
if ( $pass1.length ) {
bindPass1();
} else {
// Password field for the login form.
$pass1 = $( '#user_pass' );
}
/**
@ -189,7 +142,6 @@
if ( $pass1.is( ':hidden' ) ) {
$pass1.prop( 'disabled', true );
$pass2.prop( 'disabled', true );
$pass1Text.prop( 'disabled', true );
}
$passwordWrapper = $pass1Row.find( '.wp-pwd' );
@ -211,18 +163,10 @@
// Enable the inputs when showing.
$pass1.attr( 'disabled', false );
$pass2.attr( 'disabled', false );
$pass1Text.attr( 'disabled', false );
if ( $pass1Text.val().length === 0 ) {
if ( $pass1.val().length === 0 ) {
generatePassword();
}
_.defer( function() {
$pass1Text.focus();
if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
$pass1Text[0].setSelectionRange( 0, 100 );
}
}, 0 );
} );
$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
@ -230,7 +174,7 @@
updateLock = false;
// Clear any entered password.
$pass1Text.val( '' );
$pass1.val( '' );
// Generate a new password.
wp.ajax.post( 'generate-password' )
@ -248,9 +192,8 @@
// Disable the inputs when hiding to prevent autofill and submission.
$pass1.prop( 'disabled', true );
$pass2.prop( 'disabled', true );
$pass1Text.prop( 'disabled', true );
resetToggle();
resetToggle( false );
if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) {
// Clear password field to prevent update
@ -265,7 +208,6 @@
$pass1.prop( 'disabled', false );
$pass2.prop( 'disabled', false );
$pass2.val( $pass1.val() );
$pass1Wrap.removeClass( 'show-password' );
});
}
@ -305,7 +247,7 @@
var passStrength = $('#pass-strength-result')[0];
if ( passStrength.className ) {
$pass1.add( $pass1Text ).addClass( passStrength.className );
$pass1.addClass( passStrength.className );
if ( $( passStrength ).is( '.short, .bad' ) ) {
if ( ! $weakCheckbox.prop( 'checked' ) ) {
$submitButtons.prop( 'disabled', true );

View File

@ -1500,9 +1500,9 @@ table.form-table td .updated p {
position: relative;
}
.wp-pwd [type="text"],
.wp-pwd [type="password"] {
padding-right: 88px;
/* Needs higher specificity than normal input type text and password. */
#profile-page .form-table #pass1 {
padding-right: 90px;
}
.wp-pwd button.button {

View File

@ -301,6 +301,17 @@ body.rtl,
box-sizing: border-box;
}
.wp-pwd #pass1 {
padding-right: 50px;
}
.wp-pwd .button.wp-hide-pw {
right: 0;
}
#pass-strength-result {
width: 100%;
}
}
body.language-chooser {

View File

@ -37,10 +37,6 @@ a:focus {
0 0 2px 1px rgba(30, 140, 190, 0.8);
}
.ie8 a:focus {
outline: #5b9dd9 solid 1px;
}
p {
line-height: 1.5;
}
@ -75,14 +71,6 @@ p {
padding: 0;
}
.login .password-input-wrapper {
position: relative;
}
.login .input.password-input {
margin: 0;
}
.login .input::-ms-clear {
display: none;
}
@ -91,7 +79,7 @@ p {
margin-bottom: 15px;
}
.login .button.button-secondary {
.login .button.wp-hide-pw {
background: transparent;
border: 1px solid transparent;
box-shadow: none;
@ -102,25 +90,37 @@ p {
padding: 5px 9px;
position: absolute;
right: 0;
top: 0;
top: 3px;
}
.login .button.button-secondary:hover {
.login .button.wp-hide-pw:hover {
background: transparent;
}
.login .button.button-secondary:focus {
.login .button.wp-hide-pw:focus {
background: transparent;
border-color: #5b9dd9;
box-shadow: 0 0 3px rgba(0, 115, 170, 0.8);
}
.login .button.button-secondary:active {
.login .button.wp-hide-pw:active {
background: transparent;
box-shadow: none;
transform: none;
}
.login .button.wp-hide-pw .dashicons {
top: 4px;
}
.login .wp-pwd {
position: relative;
}
.no-js .hide-if-no-js {
display: none;
}
.login form {
margin-top: 20px;
margin-left: 0;
@ -195,9 +195,10 @@ p {
font-size: 14px;
}
.login form .forgetmenot label {
font-size: 12px;
line-height: 1.58333333;
.login .forgetmenot label,
.login .pw-weak label {
line-height: 1.5;
vertical-align: baseline;
}
.login h1 {
@ -270,16 +271,18 @@ p {
}
.login form .input,
.login input[type="text"] {
.login input[type="text"],
.login input[type="password"] {
font-size: 24px;
width: 100%;
padding: 5px;
margin: 2px 6px 16px 0;
margin: 3px 6px 16px 0;
}
.login-action-rp form .input,
.login-action-rp input[type="text"] {
padding: 5px 45px 5px 5px;
.js.login input.password-input,
.js.login-action-rp form .input,
.js.login-action-rp input[type="text"] {
padding-right: 45px;
}
.login form .input,
@ -288,14 +291,9 @@ p {
background: #fbfbfb;
}
.ie7 .login form .input,
.ie8 .login form .input {
font-family: sans-serif;
}
.login-action-rp input[type="text"] {
box-shadow: none;
margin: 0;
.js.login-action-rp input[type="text"],
.js.login-action-rp input[type="password"] {
margin-bottom: 0;
}
.login #pass-strength-result {

View File

@ -825,10 +825,9 @@ switch ( $action ) {
?>
<form name="lostpasswordform" id="lostpasswordform" action="<?php echo esc_url( network_site_url( 'wp-login.php?action=lostpassword', 'login_post' ) ); ?>" method="post">
<p>
<label for="user_login" ><?php _e( 'Username or Email Address' ); ?><br />
<input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" autocapitalize="off" /></label>
</p>
<label for="user_login"><?php _e( 'Username or Email Address' ); ?></label>
<input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" autocapitalize="off" />
<?php
/**
@ -840,12 +839,12 @@ switch ( $action ) {
?>
<input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
<p class="submit">
<div class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Get New Password' ); ?>" />
</p>
</div>
</form>
<p id="nav">
<div id="nav">
<a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log in' ); ?></a>
<?php
@ -859,7 +858,7 @@ switch ( $action ) {
}
?>
</p>
</div>
<?php
login_footer( 'user_login' );
@ -936,31 +935,27 @@ switch ( $action ) {
<input type="hidden" id="user_login" value="<?php echo esc_attr( $rp_login ); ?>" autocomplete="off" />
<div class="user-pass1-wrap">
<p>
<label for="pass1"><?php _e( 'New password' ); ?></label>
</p>
<label for="pass1"><?php _e( 'New password' ); ?></label>
<div class="wp-pwd">
<div class="password-input-wrapper">
<input type="password" data-reveal="1" data-pw="<?php echo esc_attr( wp_generate_password( 16 ) ); ?>" name="pass1" id="pass1" class="input password-input" size="24" value="" autocomplete="off" aria-describedby="pass-strength-result" />
<button type="button" class="button button-secondary wp-hide-pw hide-if-no-js">
<span class="dashicons dashicons-hidden" aria-hidden="true"></span>
</button>
</div>
<input type="password" data-reveal="1" data-pw="<?php echo esc_attr( wp_generate_password( 16 ) ); ?>" name="pass1" id="pass1" class="input password-input" size="24" value="" autocomplete="off" aria-describedby="pass-strength-result" />
<button type="button" class="button button-secondary wp-hide-pw hide-if-no-js" data-toggle="0" aria-label="<?php esc_attr_e( 'Hide password' ); ?>">
<span class="dashicons dashicons-hidden" aria-hidden="true"></span>
</button>
<div id="pass-strength-result" class="hide-if-no-js" aria-live="polite"><?php _e( 'Strength indicator' ); ?></div>
</div>
<div class="pw-weak">
<label>
<input type="checkbox" name="pw_weak" class="pw-checkbox" />
<?php _e( 'Confirm use of weak password' ); ?>
</label>
<input type="checkbox" name="pw_weak" id="pw-weak" class="pw-checkbox" />
<label for="pw-weak"><?php _e( 'Confirm use of weak password' ); ?></label>
</div>
</div>
<p class="user-pass2-wrap">
<label for="pass2"><?php _e( 'Confirm new password' ); ?></label><br />
<div class="user-pass2-wrap">
<label for="pass2"><?php _e( 'Confirm new password' ); ?></label>
<input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off" />
</p>
</div>
<p class="description indicator-hint"><?php echo wp_get_password_hint(); ?></p>
<br class="clear" />
@ -978,12 +973,12 @@ switch ( $action ) {
?>
<input type="hidden" name="rp_key" value="<?php echo esc_attr( $rp_key ); ?>" />
<p class="submit">
<div class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Reset Password' ); ?>" />
</p>
</div>
</form>
<p id="nav">
<div id="nav">
<a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log in' ); ?></a>
<?php
@ -997,7 +992,7 @@ switch ( $action ) {
}
?>
</p>
</div>
<?php
login_footer( 'user_pass' );
@ -1057,14 +1052,14 @@ switch ( $action ) {
?>
<form name="registerform" id="registerform" action="<?php echo esc_url( site_url( 'wp-login.php?action=register', 'login_post' ) ); ?>" method="post" novalidate="novalidate">
<p>
<label for="user_login"><?php _e( 'Username' ); ?><br />
<input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr( wp_unslash( $user_login ) ); ?>" size="20" autocapitalize="off" /></label>
</p>
<p>
<label for="user_email"><?php _e( 'Email' ); ?><br />
<input type="email" name="user_email" id="user_email" class="input" value="<?php echo esc_attr( wp_unslash( $user_email ) ); ?>" size="25" /></label>
</p>
<div>
<label for="user_login"><?php _e( 'Username' ); ?></label>
<input type="text" name="user_login" id="user_login" class="input" value="<?php echo esc_attr( wp_unslash( $user_login ) ); ?>" size="20" autocapitalize="off" />
</div>
<div>
<label for="user_email"><?php _e( 'Email' ); ?></label>
<input type="email" name="user_email" id="user_email" class="input" value="<?php echo esc_attr( wp_unslash( $user_email ) ); ?>" size="25" />
</div>
<?php
/**
@ -1080,16 +1075,16 @@ switch ( $action ) {
</p>
<br class="clear" />
<input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>" />
<p class="submit">
<div class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Register' ); ?>" />
</p>
</div>
</form>
<p id="nav">
<div id="nav">
<a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log in' ); ?></a>
<?php echo esc_html( $login_link_separator ); ?>
<a href="<?php echo esc_url( wp_lostpassword_url() ); ?>"><?php _e( 'Lost your password?' ); ?></a>
</p>
</div>
<?php
login_footer( 'user_login' );
@ -1329,17 +1324,22 @@ switch ( $action ) {
$aria_describedby_error = '';
}
wp_enqueue_script( 'user-profile' );
?>
<form name="loginform" id="loginform" action="<?php echo esc_url( site_url( 'wp-login.php', 'login_post' ) ); ?>" method="post">
<p>
<label for="user_login"><?php _e( 'Username or Email Address' ); ?><br />
<input type="text" name="log" id="user_login"<?php echo $aria_describedby_error; ?> class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" autocapitalize="off" /></label>
</p>
<p>
<label for="user_pass"><?php _e( 'Password' ); ?><br />
<input type="password" name="pwd" id="user_pass"<?php echo $aria_describedby_error; ?> class="input" value="" size="20" /></label>
</p>
<label for="user_login"><?php _e( 'Username or Email Address' ); ?></label>
<input type="text" name="log" id="user_login"<?php echo $aria_describedby_error; ?> class="input" value="<?php echo esc_attr( $user_login ); ?>" size="20" autocapitalize="off" />
<div class="user-pass-wrap">
<label for="user_pass"><?php _e( 'Password' ); ?></label>
<div class="wp-pwd">
<input type="password" name="pwd" id="user_pass"<?php echo $aria_describedby_error; ?> class="input password-input" value="" size="20" />
<button type="button" class="button button-secondary wp-hide-pw hide-if-no-js" data-toggle="0" aria-label="<?php esc_attr_e( 'Show password' ); ?>">
<span class="dashicons dashicons-visibility" aria-hidden="true"></span>
</button>
</div>
</div>
<?php
/**
@ -1350,8 +1350,8 @@ switch ( $action ) {
do_action( 'login_form' );
?>
<p class="forgetmenot"><label for="rememberme"><input name="rememberme" type="checkbox" id="rememberme" value="forever" <?php checked( $rememberme ); ?> /> <?php esc_html_e( 'Remember Me' ); ?></label></p>
<p class="submit">
<div class="forgetmenot"><input name="rememberme" type="checkbox" id="rememberme" value="forever" <?php checked( $rememberme ); ?> /> <label for="rememberme"><?php esc_html_e( 'Remember Me' ); ?></label></div>
<div class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e( 'Log In' ); ?>" />
<?php
@ -1373,14 +1373,14 @@ switch ( $action ) {
?>
<input type="hidden" name="testcookie" value="1" />
</p>
</div>
</form>
<?php
if ( ! $interim_login ) {
?>
<p id="nav">
<div id="nav">
<?php
if ( ! isset( $_GET['checkemail'] ) || ! in_array( $_GET['checkemail'], array( 'confirm', 'newpass' ), true ) ) {
@ -1399,7 +1399,7 @@ switch ( $action ) {
}
?>
</p>
</div>
<?php
}