Make WordPress Core

Changeset 60988


Ignore:
Timestamp:
10/20/2025 07:47:31 PM (8 weeks ago)
Author:
joedolson
Message:

Login and Registration: Add Caps Lock notice to password input.

Add a notification when typing passwords on the user registration, user login, and user profile screens that notifies the user if they are typing with caps lock enabled.

This can help reduce user friction when logging in, prevent user error when creating passwords, and reduce the need for a user to use the show password button.

Props dartiss, swissspidy, johnbillion, nikunj8866, pmbaldha, mosescursor, sirlouen, westonruter, praful2111, devsabbirahmed, kawsar007, najmulsaju, yashyadav247, sajjad67, joedolson.
Fixes #48345.

Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/_enqueues/admin/user-profile.js

    r60306 r60988  
    2121        originalFormContent,
    2222        $passwordWrapper,
    23         successTimeout;
     23        successTimeout,
     24        isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false,
     25        ua = navigator.userAgent.toLowerCase(),
     26        isSafari = window.safari !== 'undefined' && typeof window.safari === 'object',
     27        isFirefox = ua.indexOf( 'firefox' ) !== -1;
    2428
    2529    function generatePassword() {
     
    8185            showOrHideWeakPasswordCheckbox();
    8286        } );
     87
     88        bindCapsLockWarning( $pass1 );
    8389    }
    8490
     
    214220            // Password field for the login form.
    215221            $pass1 = $( '#user_pass' );
     222
     223            bindCapsLockWarning( $pass1 );
    216224        }
    217225
     
    333341    }
    334342
     343    /**
     344     * Bind Caps Lock detection to a password input field.
     345     *
     346     * @param {jQuery} $input The password input field.
     347     */
     348    function bindCapsLockWarning( $input ) {
     349        var $capsWarning,
     350            $capsIcon,
     351            $capsText,
     352            capsLockOn = false;
     353
     354        // Skip warning on macOS Safari + Firefox (they show native indicators).
     355        if ( isMac && ( isSafari || isFirefox ) ) {
     356            return;
     357        }
     358
     359        $capsWarning = $( '<div id="caps-warning" class="caps-warning"></div>' );
     360        $capsIcon    = $( '<span class="caps-icon" aria-hidden="true"><svg viewBox="0 0 24 26" xmlns="http://www.w3.org/2000/svg" fill="#3c434a" stroke="#3c434a" stroke-width="0.5"><path d="M12 5L19 15H16V19H8V15H5L12 5Z"/><rect x="8" y="21" width="8" height="1.5" rx="0.75"/></svg></span>' );
     361        $capsText    = $( '<span>', { 'class': 'caps-warning-text', text: __( 'Caps lock is on.' ) } );
     362        $capsWarning.append( $capsIcon, $capsText );
     363
     364        $input.parent( 'div' ).append( $capsWarning );
     365
     366        $input.on( 'keydown', function( jqEvent ) {
     367            var event = jqEvent.originalEvent;
     368
     369            // Skip if key is not a printable character.
     370            // Key length > 1 usually means non-printable (e.g., "Enter", "Tab").
     371            if ( event.ctrlKey || event.metaKey || event.altKey || ! event.key || event.key.length !== 1 ) {
     372                return;
     373            }
     374
     375            var state = isCapsLockOn( event );
     376
     377            // React when the state changes or if caps lock is on when the user starts typing.
     378            if ( state !== capsLockOn ) {
     379                capsLockOn = state;
     380
     381                if ( capsLockOn ) {
     382                    $capsWarning.show();
     383                    // Don't duplicate existing screen reader Caps lock notifications.
     384                    if ( event.key !== 'CapsLock' ) {
     385                        wp.a11y.speak( __( 'Caps lock is on.' ), 'assertive' );
     386                    }
     387                } else {
     388                    $capsWarning.hide();
     389                }
     390            }
     391        } );
     392
     393        $input.on( 'blur', function() {
     394            if ( ! document.hasFocus() ) {
     395                return;
     396            }
     397            capsLockOn = false;
     398            $capsWarning.hide();
     399        } );
     400    }
     401
     402    /**
     403     * Determines if Caps Lock is currently enabled.
     404     *
     405     * On macOS Safari and Firefox, the native warning is preferred,
     406     * so this function returns false to suppress custom warnings.
     407     *
     408     * @param {KeyboardEvent} e The keydown event object.
     409     *
     410     * @return {boolean} True if Caps Lock is on, false otherwise.
     411     */
     412    function isCapsLockOn( event ) {
     413        return event.getModifierState( 'CapsLock' );
     414    }
     415
    335416    function showOrHideWeakPasswordCheckbox() {
    336417        var passStrengthResult = $('#pass-strength-result');
  • trunk/src/wp-admin/css/forms.css

    r60975 r60988  
    714714}
    715715
     716/* Caps lock warning */
     717.wp-pwd .caps-warning {
     718    display: none;
     719    position: relative;
     720    background: #fcf9e8;
     721    border: 1px solid #f0c33c;
     722    color: #1d2327;
     723    padding: 6px 10px;
     724    top: -8px;
     725}
     726
     727.profile-php .wp-pwd .caps-warning {
     728    padding: 3px 5px;
     729    top: -4px;
     730    border-radius: 4px;
     731}
     732
     733.wp-pwd .caps-icon {
     734    display: inline-flex;
     735    justify-content: center;
     736    width: 20px;
     737    height: 20px;
     738    margin-right: 5px;
     739    vertical-align: middle;
     740}
     741
     742.wp-pwd .caps-warning-text {
     743    vertical-align: middle;
     744}
     745/* Caps lock warning */
     746
    716747p.search-box {
    717748    display: flex;
     
    16411672    }
    16421673
     1674    .profile-php .wp-pwd .caps-warning {
     1675        padding: 8px;
     1676    }
     1677
    16431678    .password-input-wrapper {
    16441679        display: block;
Note: See TracChangeset for help on using the changeset viewer.