Make WordPress Core

Changeset 38035


Ignore:
Timestamp:
07/12/2016 11:18:00 AM (8 years ago)
Author:
ocean90
Message:

Toolbar: Allow 0 as a value for the tabindex property of a menu item.

To enhance accessibility for items without a link you can now define tabindex="0", which makes descendant dropdowns accessible.

Props joedolson, afercia, ocean90.
Fixes #32495.

Location:
trunk
Files:
3 edited

Legend:

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

    r37985 r38035  
    478478        $has_link  = ! empty( $node->href );
    479479
    480         $tabindex = isset( $node->meta['tabindex'] ) ? (int) $node->meta['tabindex'] : '';
    481         $aria_attributes = $tabindex ? 'tabindex="' . $tabindex . '"' : '';
     480        // Allow only numeric values, then casted to integers, and allow a tabindex value of `0` for a11y.
     481        $tabindex = ( isset( $node->meta['tabindex'] ) && is_numeric( $node->meta['tabindex'] ) ) ? (int) $node->meta['tabindex'] : '';
     482        $aria_attributes = ( '' !== $tabindex ) ? ' tabindex="' . $tabindex . '"' : '';
    482483
    483484        $menuclass = '';
     
    498499        <li id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>"<?php echo $menuclass; ?>><?php
    499500            if ( $has_link ):
    500                 ?><a class="ab-item" <?php echo $aria_attributes; ?> href="<?php echo esc_url( $node->href ) ?>"<?php
     501                ?><a class="ab-item"<?php echo $aria_attributes; ?> href="<?php echo esc_url( $node->href ) ?>"<?php
    501502                    if ( ! empty( $node->meta['onclick'] ) ) :
    502503                        ?> onclick="<?php echo esc_js( $node->meta['onclick'] ); ?>"<?php
     
    519520                ?>><?php
    520521            else:
    521                 ?><div class="ab-item ab-empty-item" <?php echo $aria_attributes;
     522                ?><div class="ab-item ab-empty-item"<?php echo $aria_attributes;
    522523                if ( ! empty( $node->meta['title'] ) ) :
    523524                    ?> title="<?php echo esc_attr( $node->meta['title'] ); ?>"<?php
  • trunk/src/wp-includes/css/admin-bar.css

    r37740 r38035  
    287287#wpadminbar .quicklinks .menupop.hover ul li a:hover,
    288288#wpadminbar .quicklinks .menupop.hover ul li a:focus,
     289#wpadminbar .quicklinks .menupop.hover ul li div[tabindex]:hover,
     290#wpadminbar .quicklinks .menupop.hover ul li div[tabindex]:focus,
    289291#wpadminbar.nojs .quicklinks .menupop:hover ul li a:hover,
    290292#wpadminbar.nojs .quicklinks .menupop:hover ul li a:focus,
  • trunk/tests/phpunit/tests/adminbar.php

    r35246 r38035  
    133133        $this->assertEquals( $profile_url, $node_user_info->href );
    134134        $this->assertEquals( $profile_url, $node_edit_profile->href );
    135 
    136135    }
    137136
     
    255254    }
    256255
     256    /**
     257     * @ticket 32495
     258     *
     259     * @dataProvider data_admin_bar_nodes_with_tabindex_meta
     260     *
     261     * @param array  $node_data     The data for a node, passed to `WP_Admin_Bar::add_node()`.
     262     * @param string $expected_html The expected HTML when admin menu is rendered.
     263     */
     264    public function test_admin_bar_with_tabindex_meta( $node_data, $expected_html ) {
     265        $admin_bar = new WP_Admin_Bar();
     266        $admin_bar->add_node( $node_data );
     267        $admin_bar_html = get_echo( array( $admin_bar, 'render' ) );
     268        $this->assertContains( $expected_html, $admin_bar_html );
     269    }
     270
     271    /**
     272     * Data provider for test_admin_bar_with_tabindex_meta().
     273     *
     274     * @return array {
     275     *     @type array {
     276     *         @type array  $node_data     The data for a node, passed to `WP_Admin_Bar::add_node()`.
     277     *         @type string $expected_html The expected HTML when admin bar is rendered.
     278     *     }
     279     * }
     280     */
     281    public function data_admin_bar_nodes_with_tabindex_meta() {
     282        return array(
     283            array(
     284                // No tabindex.
     285                array(
     286                    'id' => 'test-node',
     287                ),
     288                '<div class="ab-item ab-empty-item">',
     289            ),
     290            array(
     291                // Empty string.
     292                array(
     293                    'id' => 'test-node',
     294                    'meta' => array( 'tabindex' => '' ),
     295                ),
     296                '<div class="ab-item ab-empty-item">',
     297            ),
     298            array(
     299                // Integer 1 as string.
     300                array(
     301                    'id'   => 'test-node',
     302                    'meta' => array( 'tabindex' => '1' ),
     303                ),
     304                '<div class="ab-item ab-empty-item" tabindex="1">',
     305            ),
     306            array(
     307                // Integer -1 as string.
     308                array(
     309                    'id'   => 'test-node',
     310                    'meta' => array( 'tabindex' => '-1' ),
     311                ),
     312                '<div class="ab-item ab-empty-item" tabindex="-1">',
     313            ),
     314            array(
     315                // Integer 0 as string.
     316                array(
     317                    'id'   => 'test-node',
     318                    'meta' => array( 'tabindex' => '0' ),
     319                ),
     320                '<div class="ab-item ab-empty-item" tabindex="0">',
     321            ),
     322            array(
     323                // Integer, 0.
     324                array(
     325                    'id'   => 'test-node',
     326                    'meta' => array( 'tabindex' => 0 ),
     327                ),
     328                '<div class="ab-item ab-empty-item" tabindex="0">',
     329            ),
     330            array(
     331                // Integer, 2.
     332                array(
     333                    'id'   => 'test-node',
     334                    'meta' => array( 'tabindex' => 2 ),
     335                ),
     336                '<div class="ab-item ab-empty-item" tabindex="2">',
     337            ),
     338            array(
     339                // Boolean, false
     340                array(
     341                    'id'   => 'test-node',
     342                    'meta' => array( 'tabindex' => false ),
     343                ),
     344                '<div class="ab-item ab-empty-item">',
     345            ),
     346        );
     347    }
    257348}
Note: See TracChangeset for help on using the changeset viewer.