Make WordPress Core

Changeset 40816


Ignore:
Timestamp:
05/22/2017 08:23:49 PM (7 years ago)
Author:
afercia
Message:

Widgets: Remove the title attributes used in the Tag cloud widget.

  • improves accessibility using an aria-label attribute to match the information conveyed visually with the one exposed to assistive technologies
  • adds an option in the widget to display the item counts, consistently with what other widgets already do (Archives, Categories)

Props adamsoucie, emirpprime, Samantha Miller., MikeLittle, rianrietveld, sami.keijonen, adamsilverstein, westonruter, afercia.
See #24766.
Fixes #35566.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/category-template.php

    r40043 r40816  
    660660 *
    661661 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the
    662  * text for the tooltip of the tag link.
     662 * text for the tag link count.
    663663 *
    664664 * The 'topic_count_text_callback' argument is a function, which given the count
    665  * of the posts with that tag returns a text for the tooltip of the tag link.
     665 * of the posts with that tag returns a text for the tag link count.
    666666 *
    667667 * The 'post_type' argument is used only when 'link' is set to 'edit'. It determines the post_type
     
    672672 *
    673673 * @since 2.3.0
     674 * @since 4.8.0 Added the `show_count` argument.
    674675 *
    675676 * @param array|string|null $args Optional. Override default arguments.
     
    681682        'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,
    682683        'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',
    683         'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'post_type' => '', 'echo' => true
     684        'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'post_type' => '', 'echo' => true,
     685        'show_count' => 0,
    684686    );
    685687    $args = wp_parse_args( $args, $defaults );
     
    737739 * @todo Complete functionality.
    738740 * @since 2.3.0
     741 * @since 4.8.0 Added the `show_count` argument.
    739742 *
    740743 * @param array $tags List of tags.
     
    767770 *                                                via {@see 'wp_generate_tag_cloud'}. Default 1|true.
    768771 *     @type string   $topic_count_text           Nooped plural text from _n_noop() to supply to
    769  *                                                tag tooltips. Default null.
     772 *                                                tag counts. Default null.
    770773 *     @type callable $topic_count_text_callback  Callback used to generate nooped plural text for
    771  *                                                tag tooltips based on the count. Default null.
     774 *                                                tag counts based on the count. Default null.
    772775 *     @type callable $topic_count_scale_callback Callback used to determine the tag count scaling
    773776 *                                                value. Default default_topic_count_scale().
     777 *     @type bool|int $show_count                 Whether to display the tag counts. Default 0. Accepts
     778 *                                                0, 1, or their bool equivalents.
    774779 * }
    775780 * @return string|array Tag cloud as a string or an array, depending on 'format' argument.
     
    781786        'topic_count_text' => null, 'topic_count_text_callback' => null,
    782787        'topic_count_scale_callback' => 'default_topic_count_scale', 'filter' => 1,
     788        'show_count' => 0,
    783789    );
    784790
     
    791797    }
    792798
    793     // Juggle topic count tooltips:
     799    // Juggle topic counts.
    794800    if ( isset( $args['topic_count_text'] ) ) {
    795801        // First look for nooped plural support via topic_count_text.
     
    798804        // Look for the alternative callback style. Ignore the previous default.
    799805        if ( $args['topic_count_text_callback'] === 'default_topic_count_text' ) {
    800             $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );
     806            $translate_nooped_plural = _n_noop( '%s item', '%s items' );
    801807        } else {
    802808            $translate_nooped_plural = false;
     
    807813    } else {
    808814        // This is the default for when no callback, plural, or argument is passed in.
    809         $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );
     815        $translate_nooped_plural = _n_noop( '%s item', '%s items' );
    810816    }
    811817
     
    862868    $font_step = $font_spread / $spread;
    863869
     870    $aria_label = false;
     871    /*
     872     * Determine whether to output an 'aria-label' attribute with the tag name and count.
     873     * When tags have a different font size, they visually convey an important information
     874     * that should be available to assistive technologies too. On the other hand, sometimes
     875     * themes set up the Tag Cloud to display all tags with the same font size (setting
     876     * the 'smallest' and 'largest' arguments to the same value).
     877     * In order to always serve the same content to all users, the 'aria-label' gets printed out:
     878     * - when tags have a different size
     879     * - when the tag count is displayed (for example when users check the checkbox in the
     880     *   Tag Cloud widget), regardless of the tags font size
     881     */
     882    if ( $args['show_count'] || 0 !== $font_spread ) {
     883        $aria_label = true;
     884    }
     885
    864886    // Assemble the data that will be used to generate the tag cloud markup.
    865887    $tags_data = array();
     
    871893
    872894        if ( $translate_nooped_plural ) {
    873             $title = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) );
     895            $formatted_count = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) );
    874896        } else {
    875             $title = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args );
     897            $formatted_count = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args );
    876898        }
    877899
    878900        $tags_data[] = array(
    879             'id'         => $tag_id,
    880             'url'        => '#' != $tag->link ? $tag->link : '#',
    881             'role'       => '#' != $tag->link ? '' : ' role="button"',
    882             'name'       => $tag->name,
    883             'title'      => $title,
    884             'slug'       => $tag->slug,
    885             'real_count' => $real_count,
    886             'class'      => 'tag-link-' . $tag_id,
    887             'font_size'  => $args['smallest'] + ( $count - $min_count ) * $font_step,
     901            'id'              => $tag_id,
     902            'url'             => '#' != $tag->link ? $tag->link : '#',
     903            'role'            => '#' != $tag->link ? '' : ' role="button"',
     904            'name'            => $tag->name,
     905            'formatted_count' => $formatted_count,
     906            'slug'            => $tag->slug,
     907            'real_count'      => $real_count,
     908            'class'           => 'tag-cloud-link tag-link-' . $tag_id,
     909            'font_size'       => $args['smallest'] + ( $count - $min_count ) * $font_step,
     910            'aria_label'      => $aria_label ? sprintf( ' aria-label="%1$s (%2$s)"', esc_attr( $tag->name ), esc_attr( $formatted_count ) ) : '',
     911            'show_count'      => $args['show_count'] ? '<span class="tag-link-count"> (' . $real_count . ')</span>' : '',
    888912        );
    889913    }
     
    900924    $a = array();
    901925
    902     // generate the output links array
     926    // Generate the output links array.
    903927    foreach ( $tags_data as $key => $tag_data ) {
    904928        $class = $tag_data['class'] . ' tag-link-position-' . ( $key + 1 );
    905         $a[] = "<a href='" . esc_url( $tag_data['url'] ) . "'" . $tag_data['role'] . " class='" . esc_attr( $class ) . "' title='" . esc_attr( $tag_data['title'] ) . "' style='font-size: " . esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ) . ";'>" . esc_html( $tag_data['name'] ) . "</a>";
     929        $a[] = sprintf(
     930            '<a href="%1$s"%2$s class="%3$s" style="font-size: %4$s;"%5$s>%6$s%7$s</a>',
     931            esc_url( $tag_data['url'] ),
     932            $tag_data['role'],
     933            esc_attr( $class ),
     934            esc_attr( str_replace( ',', '.', $tag_data['font_size'] ) . $args['unit'] ),
     935            $tag_data['aria_label'],
     936            esc_html( $tag_data['name'] ),
     937            $tag_data['show_count']
     938        );
    906939    }
    907940
     
    911944            break;
    912945        case 'list' :
    913             $return = "<ul class='wp-tag-cloud'>\n\t<li>";
     946            /*
     947             * Force role="list", as some browsers (sic: Safari 10) don't expose to assistive
     948             * technologies the default role when the list is styled with `list-style: none`.
     949             * Note: this is redundant but doesn't harm.
     950             */
     951            $return = "<ul class='wp-tag-cloud' role='list'>\n\t<li>";
    914952            $return .= join( "</li>\n\t<li>", $a );
    915953            $return .= "</li>\n</ul>\n";
  • trunk/src/wp-includes/widgets/class-wp-widget-tag-cloud.php

    r40806 r40816  
    5454        }
    5555
     56        $show_count = ! empty( $instance['count'] );
     57
    5658        /**
    5759         * Filters the taxonomy used in the Tag Cloud widget.
     
    6567         */
    6668        $tag_cloud = wp_tag_cloud( apply_filters( 'widget_tag_cloud_args', array(
    67             'taxonomy' => $current_taxonomy,
    68             'echo' => false
     69            'taxonomy'   => $current_taxonomy,
     70            'echo'       => false,
     71            'show_count' => $show_count,
    6972        ) ) );
    7073
     
    103106        $instance = array();
    104107        $instance['title'] = sanitize_text_field( $new_instance['title'] );
     108        $instance['count'] = ! empty( $new_instance['count'] ) ? 1 : 0;
    105109        $instance['taxonomy'] = stripslashes($new_instance['taxonomy']);
    106110        return $instance;
     
    118122        $current_taxonomy = $this->_get_current_taxonomy($instance);
    119123        $title_id = $this->get_field_id( 'title' );
     124        $count = isset( $instance['count'] ) ? (bool) $instance['count'] : false;
    120125        $instance['title'] = ! empty( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
    121126
     
    129134        $input = '<input type="hidden" id="' . $id . '" name="' . $name . '" value="%s" />';
    130135
     136        $count_checkbox = sprintf(
     137            '<p><input type="checkbox" class="checkbox" id="%1$s" name="%2$s"%3$s /> <label for="%1$s">%4$s</label></p>',
     138            $this->get_field_id( 'count' ),
     139            $this->get_field_name( 'count' ),
     140            checked( $count, true, false ),
     141            __( 'Show tag counts' )
     142        );
     143
    131144        switch ( count( $taxonomies ) ) {
    132145
     
    137150            break;
    138151
    139         // Just a single tag cloud supporting taxonomy found, no need to display options
     152        // Just a single tag cloud supporting taxonomy found, no need to display a select.
    140153        case 1:
    141154            $keys = array_keys( $taxonomies );
    142155            $taxonomy = reset( $keys );
    143156            printf( $input, esc_attr( $taxonomy ) );
     157            echo $count_checkbox;
    144158            break;
    145159
    146         // More than one tag cloud supporting taxonomy found, display options
     160        // More than one tag cloud supporting taxonomy found, display a select.
    147161        default:
    148162            printf(
     
    163177            }
    164178
    165             echo '</select></p>';
     179            echo '</select></p>' . $count_checkbox;
    166180        }
    167181    }
  • trunk/tests/phpunit/tests/post.php

    r39174 r40816  
    940940        ) );
    941941
    942         preg_match_all( "|href='([^']+)'|", $wp_tag_cloud, $matches );
     942        preg_match_all( '|href="([^"]+)"|', $wp_tag_cloud, $matches );
    943943        $this->assertSame( 1, count( $matches[1] ) );
    944944
  • trunk/tests/phpunit/tests/term/wpGenerateTagCloud.php

    r35988 r40816  
    120120        ) );
    121121
    122         $this->assertRegExp( "|^<ul class='wp-tag-cloud'>|", $found );
     122        $this->assertRegExp( "|^<ul class='wp-tag-cloud' role='list'>|", $found );
    123123        $this->assertRegExp( "|</ul>\n|", $found );
    124124        $this->assertContains( '>' . $tags[0]->name . '<', $found );
     
    165165        ) );
    166166
    167         $this->assertRegExp( "|^<ul class='wp-tag-cloud'>|", $found );
     167        $this->assertRegExp( "|^<ul class='wp-tag-cloud' role='list'>|", $found );
    168168        $this->assertRegExp( "|</ul>\n|", $found );
    169169
     
    199199        ) );
    200200
    201         $this->assertContains( "title='Term has 1 post'", $actual[0] );
    202         $this->assertContains( "title='Term has 2 posts'", $actual[1] );
     201        $this->assertContains( 'aria-label="' . $term_objects[0]->name . ' (Term has 1 post)"', $actual[0] );
     202        $this->assertContains( 'aria-label="' . $term_objects[1]->name . ' (Term has 2 posts)"', $actual[1] );
    203203    }
    204204
     
    224224        ) );
    225225
    226         $this->assertContains( "title='1 foo'", $actual[0] );
    227         $this->assertContains( "title='2 foo'", $actual[1] );
     226        $this->assertContains( 'aria-label="' . $term_objects[0]->name . ' (1 foo)"', $actual[0] );
     227        $this->assertContains( 'aria-label="' . $term_objects[1]->name . ' (2 foo)"', $actual[1] );
    228228    }
    229229
Note: See TracChangeset for help on using the changeset viewer.