WordPress.org

Make WordPress Core

Ticket #48894: 48894.4.diff

File 48894.4.diff, 4.2 KB (added by isabel_brison, 15 months ago)

Toggle all admin bar dropdowns on click or keypress.

  • src/js/_enqueues/lib/admin-bar.js

    diff --git a/src/js/_enqueues/lib/admin-bar.js b/src/js/_enqueues/lib/admin-bar.js
    index ea69ae7efe..dd48a038fd 100644
    a b  
    3030                }
    3131
    3232                topMenuItems = adminBar.querySelectorAll( 'li.menupop' );
     33                toggleMenuItems = adminBar.querySelectorAll( 'li.menupop > .ab-item' )
    3334                allMenuItems = adminBar.querySelectorAll( '.ab-item' );
    3435                adminBarLogout = document.getElementById( 'wp-admin-bar-logout' );
    3536                adminBarSearchForm = document.getElementById( 'adminbarsearch' );
     
    6263                // Scroll page to top when clicking on the admin bar.
    6364                adminBar.addEventListener( 'click', scrollToTop );
    6465
    65                 for ( i = 0; i < topMenuItems.length; i++ ) {
    66                         // Adds or removes the hover class based on the hover intent.
    67                         window.hoverintent(
    68                                 topMenuItems[i],
    69                                 addClass.bind( null, topMenuItems[i], 'hover' ),
    70                                 removeClass.bind( null, topMenuItems[i], 'hover' )
    71                         ).options( {
    72                                 timeout: 180
    73                         } );
    74 
    75                         // Toggle hover class if the enter key is pressed.
    76                         topMenuItems[i].addEventListener( 'keydown', toggleHoverIfEnter );
    77                 }
    78 
    7966                // Remove hover class if the escape key is pressed.
    8067                for ( i = 0; i < allMenuItems.length; i++ ) {
    8168                        allMenuItems[i].addEventListener( 'keydown', removeHoverIfEscape );
    8269                }
     70               
     71                for ( i = 0; i < toggleMenuItems.length; i++ ) {
     72                        // Make the menu dropdown toggles be perceived and behave as buttons.
     73                        toggleMenuItems[i].setAttribute( 'role', 'button' );
     74                        toggleMenuItems[i].setAttribute( 'aria-expanded', 'false' );
     75
     76                        // Handle opening/closing menus with Enter and Space.
     77                        toggleMenuItems[i].addEventListener( 'keydown', handleKeyDown );
     78                        // Handle opening/closing menus with click.
     79                        toggleMenuItems[i].addEventListener( 'click', handleClick );
     80                }
    8381
    8482                if ( adminBarSearchForm ) {
    8583                        adminBarSearchInput = document.getElementById( 'adminbar-search' );
     
    115113                }
    116114        } );
    117115
     116        /**
     117         * Updates the My Account menu aria-expanded attribute.
     118         *
     119         * @since 5.5.0
     120         */
     121        function toggleAriaExpanded( element ) {
     122                if ( element.getAttribute('aria-expanded') === 'true' ) {
     123                        element.setAttribute( 'aria-expanded', 'false' );
     124                } else {
     125                        element.setAttribute( 'aria-expanded', 'true' );
     126                }
     127        }
     128
    118129        /**
    119130         * Remove hover class for top level menu item when escape is pressed.
    120131         *
     
    123134         * @param {Event} event The keydown event.
    124135         */
    125136        function removeHoverIfEscape( event ) {
    126                 var wrapper;
     137                var wrapper,
     138                toggle;
    127139
    128140                if ( event.which !== 27 ) {
    129141                        return;
    130142                }
    131143
    132144                wrapper = getClosest( event.target, '.menupop' );
    133 
     145                toggle = wrapper.querySelector( '.menupop > .ab-item' );
    134146                if ( ! wrapper ) {
    135147                        return;
    136148                }
    137149
    138                 wrapper.querySelector( '.menupop > .ab-item' ).focus();
     150                toggle.focus();
     151                toggleAriaExpanded( toggle );
    139152                removeClass( wrapper, 'hover' );
    140153        }
    141154
    142155        /**
    143          * Toggle hover class for top level menu item when enter is pressed.
     156         * Handles the click event on dropdown toggles.
     157         *
     158         * @since 5.5.0
     159         *
     160         * @param {Event} event The click event.
     161         */
     162        function handleClick( event ) {
     163                event.preventDefault();
     164                var wrapper = getClosest( event.target, '.menupop' );
     165                wrapper.classList.toggle( 'hover' );
     166                toggleAriaExpanded( event.target );
     167        }
     168
     169        /**
     170         * Handles the keydown event on dropdown toggles.
    144171         *
    145172         * @since 5.3.1
    146173         *
    147174         * @param {Event} event The keydown event.
    148175         */
    149         function toggleHoverIfEnter( event ) {
    150                 var wrapper;
    151 
    152                 if ( event.which !== 13 ) {
    153                         return;
    154                 }
    155 
    156                 if ( !! getClosest( event.target, '.ab-sub-wrapper' ) ) {
    157                         return;
    158                 }
    159 
    160                 wrapper = getClosest( event.target, '.menupop' );
     176        function handleKeyDown( event ) {
     177                var wrapper = getClosest( event.target, '.menupop' );
    161178
    162                 if ( ! wrapper ) {
     179                if (
     180                        ! wrapper ||
     181                        !! getClosest( event.target, '.ab-sub-wrapper' ) ||
     182                        ( event.which !== 32 && event.which !== 13 )
     183                ) {
    163184                        return;
    164185                }
    165186
     187                // Prevent scrolling the page when activating the links via the Spacebar key.
    166188                event.preventDefault();
    167189
    168                 if ( hasClass( wrapper, 'hover' ) ) {
    169                         removeClass( wrapper, 'hover' );
    170                 } else {
    171                         addClass( wrapper, 'hover' );
    172                 }
     190                wrapper.classList.toggle( 'hover' );
     191                toggleAriaExpanded( event.target );
    173192        }
    174193
    175194        /**