Make WordPress Core


Ignore:
Timestamp:
02/26/2024 12:50:22 AM (3 years ago)
Author:
joedolson
Message:

Toolbar: Accessibility: Keyboard navigation for screen readers.

Change the admin toolbar to have role="menu" and support opening for screen readers. Remove screen reader only log out link and collapse duplicate profile links into one link. This is an imperfect solution to a complex problem in the adminbar, but the lack of screen reader access to submenus is a major accessibility problem, and this fix provides access, even if the mechanism is imperfect.

Screen reader log out added in [21452].

Props abletec, Cheffheid, sabernhardt, alexstine, joedolson, afercia, sparklingrobots, danieltj, swissspidy, netweb, dionysous.
Fixes #34668, #43633.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-admin-bar.php

    r56177 r57708  
    108108         * @since 3.1.0
    109109         * @since 4.5.0 Added the ability to pass 'lang' and 'dir' meta data.
     110         * @since 6.5.0 Added the ability to pass 'menu_title' for an ARIA menu name.
    110111         *
    111112         * @param array $args {
     
    118119         *     @type bool   $group  Optional. Whether or not the node is a group. Default false.
    119120         *     @type array  $meta   Meta data including the following keys: 'html', 'class', 'rel', 'lang', 'dir',
    120          *                          'onclick', 'target', 'title', 'tabindex'. Default empty.
     121         *                          'onclick', 'target', 'title', 'tabindex', 'menu_title'. Default empty.
    121122         * }
    122123         */
     
    479480                                ?>
    480481                        </div>
    481                         <?php if ( is_user_logged_in() ) : ?>
    482                         <a class="screen-reader-shortcut" href="<?php echo esc_url( wp_logout_url() ); ?>"><?php _e( 'Log Out' ); ?></a>
    483                         <?php endif; ?>
    484482                </div>
    485483
     
    506504        /**
    507505         * @since 3.3.0
     506         * @since 6.5.0 Added `$menu_title` parameter to allow an ARIA menu name.
    508507         *
    509508         * @param object $node
    510          */
    511         final protected function _render_group( $node ) {
     509         * @param string|bool $menu_title The accessible name of this aria menu or false if not provided.
     510         */
     511        final protected function _render_group( $node, $menu_title = false ) {
    512512                if ( 'container' === $node->type ) {
    513513                        $this->_render_container( $node );
     
    524524                }
    525525
    526                 echo "<ul id='" . esc_attr( 'wp-admin-bar-' . $node->id ) . "'$class>";
     526                if ( empty( $menu_title ) ) {
     527                        echo "<ul role='menu' id='" . esc_attr( 'wp-admin-bar-' . $node->id ) . "'$class>";
     528                } else {
     529                        echo "<ul role='menu' aria-label='" . esc_attr( $menu_title ) . "' id='" . esc_attr( 'wp-admin-bar-' . $node->id ) . "'$class>";
     530                }
    527531                foreach ( $node->children as $item ) {
    528532                        $this->_render_item( $item );
     
    547551
    548552                // Allow only numeric values, then casted to integers, and allow a tabindex value of `0` for a11y.
    549                 $tabindex        = ( isset( $node->meta['tabindex'] ) && is_numeric( $node->meta['tabindex'] ) ) ? (int) $node->meta['tabindex'] : '';
    550                 $aria_attributes = ( '' !== $tabindex ) ? ' tabindex="' . $tabindex . '"' : '';
     553                $tabindex         = ( isset( $node->meta['tabindex'] ) && is_numeric( $node->meta['tabindex'] ) ) ? (int) $node->meta['tabindex'] : '';
     554                $aria_attributes  = ( '' !== $tabindex ) ? ' tabindex="' . $tabindex . '"' : '';
     555                $aria_attributes .= ' role="menuitem"';
    551556
    552557                $menuclass = '';
     
    555560                if ( $is_parent ) {
    556561                        $menuclass        = 'menupop ';
    557                         $aria_attributes .= ' aria-haspopup="true"';
     562                        $aria_attributes .= ' aria-expanded="false"';
    558563                }
    559564
     
    604609                        echo '<div class="ab-sub-wrapper">';
    605610                        foreach ( $node->children as $group ) {
    606                                 $this->_render_group( $group );
     611                                if ( empty( $node->meta['menu_title'] ) ) {
     612                                        $this->_render_group( $group, false );
     613                                } else {
     614                                        $this->_render_group( $group, $node->meta['menu_title'] );
     615                                }
    607616                        }
    608617                        echo '</div>';
Note: See TracChangeset for help on using the changeset viewer.