Accessibility: Improve the Tags meta box accessibility.

- changes the "X" links in buttons, improves their color contrast ratio and focus style
- adds screen reader text "Remove item: + tagname"
- uses `wp.a11y.speak()` to give screen reader users feedback when adding/removing tags
- makes the `tagcloud-link` toggle a button, with an `aria-expanded` attribute to indicate the tag cloud collapsed/expanded state
- changes colors for the autocomplete highlighted option in order to have a better color contrast ratio
- reduces the font size for the autocomplete on Press This
- removes CSS related to the old `suggest.js` from Press This

Props joedolson, cgrymala, azaozz, afercia.
Fixes #27555.

Built from https://develop.svn.wordpress.org/trunk@38880


git-svn-id: http://core.svn.wordpress.org/trunk@38823 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrea Fercia 2016-10-23 18:16:42 +00:00
parent 4e65c0cfb4
commit 5c555e5d10
34 changed files with 385 additions and 219 deletions

View File

@ -759,7 +759,7 @@ img.emoji {
/* @todo can we combine these into a class or use an existing dashicon one? */
.welcome-panel .welcome-panel-close:before,
.tagchecklist span a:before,
.tagchecklist .ntdelbutton .remove-tag-icon:before,
#bulk-titles div a:before,
.notice-dismiss:before {
background: none;
@ -779,18 +779,41 @@ img.emoji {
margin: 0;
}
.tagchecklist span a:before,
#bulk-titles div a:before {
margin: 1px 0;
}
.tagchecklist .ntdelbutton .remove-tag-icon:before {
margin-right: 2px;
-webkit-border-radius: 50%;
border-radius: 50%;
color: #0073aa;
/* vertically center the icon cross browsers */
line-height: 1.28;
}
.tagchecklist .ntdelbutton:focus {
outline: 0;
}
.welcome-panel .welcome-panel-close:hover:before,
.welcome-panel .welcome-panel-close:focus:before,
.tagchecklist span a:hover:before,
#bulk-titles div a:hover:before {
.tagchecklist .ntdelbutton:hover .remove-tag-icon:before,
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before,
#bulk-titles div a:hover:before,
#bulk-titles div a:focus:before {
color: #c00;
}
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
-webkit-box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
.key-labels label {
line-height: 24px;
}
@ -3571,9 +3594,7 @@ img {
.sidebar-name-arrow,
.sidebar-name:hover .sidebar-name-arrow,
.meta-box-sortables .postbox:hover .handlediv,
.tagchecklist span a,
#bulk-titles div a,
.tagchecklist span a:hover,
#bulk-titles div a:hover {
background: none !important;
}

File diff suppressed because one or more lines are too long

View File

@ -759,7 +759,7 @@ img.emoji {
/* @todo can we combine these into a class or use an existing dashicon one? */
.welcome-panel .welcome-panel-close:before,
.tagchecklist span a:before,
.tagchecklist .ntdelbutton .remove-tag-icon:before,
#bulk-titles div a:before,
.notice-dismiss:before {
background: none;
@ -779,18 +779,41 @@ img.emoji {
margin: 0;
}
.tagchecklist span a:before,
#bulk-titles div a:before {
margin: 1px 0;
}
.tagchecklist .ntdelbutton .remove-tag-icon:before {
margin-left: 2px;
-webkit-border-radius: 50%;
border-radius: 50%;
color: #0073aa;
/* vertically center the icon cross browsers */
line-height: 1.28;
}
.tagchecklist .ntdelbutton:focus {
outline: 0;
}
.welcome-panel .welcome-panel-close:hover:before,
.welcome-panel .welcome-panel-close:focus:before,
.tagchecklist span a:hover:before,
#bulk-titles div a:hover:before {
.tagchecklist .ntdelbutton:hover .remove-tag-icon:before,
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before,
#bulk-titles div a:hover:before,
#bulk-titles div a:focus:before {
color: #c00;
}
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
-webkit-box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
.key-labels label {
line-height: 24px;
}
@ -3571,9 +3594,7 @@ img {
.sidebar-name-arrow,
.sidebar-name:hover .sidebar-name-arrow,
.meta-box-sortables .postbox:hover .handlediv,
.tagchecklist span a,
#bulk-titles div a,
.tagchecklist span a:hover,
#bulk-titles div a:hover {
background: none !important;
}

File diff suppressed because one or more lines are too long

View File

@ -276,7 +276,9 @@ body {
box-sizing: border-box;
-webkit-transition: 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1), 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1), 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1); /* easeInOutCubic */
}

File diff suppressed because one or more lines are too long

View File

@ -276,7 +276,9 @@ body {
box-sizing: border-box;
-webkit-transition: 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1), 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1);
transition: 0.18s transform cubic-bezier(0.645, 0.045, 0.355, 1), 0.18s -webkit-transform cubic-bezier(0.645, 0.045, 0.355, 1); /* easeInOutCubic */
}

File diff suppressed because one or more lines are too long

View File

@ -582,10 +582,9 @@ span.wp-media-buttons-icon:before {
position: absolute;
}
.tagchecklist span {
margin-left: 25px;
display: block;
.tagchecklist > span {
float: right;
margin-left: 25px;
font-size: 13px;
line-height: 1.8em;
cursor: default;
@ -594,16 +593,16 @@ span.wp-media-buttons-icon:before {
text-overflow: ellipsis;
}
.tagchecklist span a {
margin: 1px -17px 0 0;
cursor: pointer;
width: 20px;
height: 20px;
display: block;
float: right;
text-indent: 0;
overflow: hidden;
.tagchecklist .ntdelbutton {
position: absolute;
width: 24px;
height: 24px;
border: none;
margin: 0 -19px 0 0;
padding: 0;
background: none;
cursor: pointer;
text-indent: 0;
}
#poststuff h3.hndle, /* Back-compat for pre-4.4 */
@ -1027,6 +1026,25 @@ span.description,
width: 260px;
}
.tagcloud-link.button-link {
color: #0073aa;
text-decoration: underline;
}
.tagcloud-link.button-link:hover {
color: #00a0d2;
}
.tagcloud-link.button-link:focus {
color: #124964;
-webkit-box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
#post-body-content .tagsdiv .the-tags {
margin: 0 5px;
}
@ -1052,6 +1070,7 @@ p.popular-tags a {
margin: 2px 0 12px;
}
/* Suggest.js autocomplete, no more used by core. */
.ac_results {
display: none;
margin: -1px 0 0;
@ -1438,7 +1457,7 @@ table.links-table {
margin: 25px 10px;
}
.tagchecklist span {
.tagchecklist > span {
font-size: 16px;
line-height: 1.4;
}

File diff suppressed because one or more lines are too long

View File

@ -582,10 +582,9 @@ span.wp-media-buttons-icon:before {
position: absolute;
}
.tagchecklist span {
margin-right: 25px;
display: block;
.tagchecklist > span {
float: left;
margin-right: 25px;
font-size: 13px;
line-height: 1.8em;
cursor: default;
@ -594,16 +593,16 @@ span.wp-media-buttons-icon:before {
text-overflow: ellipsis;
}
.tagchecklist span a {
margin: 1px 0 0 -17px;
cursor: pointer;
width: 20px;
height: 20px;
display: block;
float: left;
text-indent: 0;
overflow: hidden;
.tagchecklist .ntdelbutton {
position: absolute;
width: 24px;
height: 24px;
border: none;
margin: 0 0 0 -19px;
padding: 0;
background: none;
cursor: pointer;
text-indent: 0;
}
#poststuff h3.hndle, /* Back-compat for pre-4.4 */
@ -1027,6 +1026,25 @@ span.description,
width: 260px;
}
.tagcloud-link.button-link {
color: #0073aa;
text-decoration: underline;
}
.tagcloud-link.button-link:hover {
color: #00a0d2;
}
.tagcloud-link.button-link:focus {
color: #124964;
-webkit-box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
#post-body-content .tagsdiv .the-tags {
margin: 0 5px;
}
@ -1052,6 +1070,7 @@ p.popular-tags a {
margin: 2px 0 12px;
}
/* Suggest.js autocomplete, no more used by core. */
.ac_results {
display: none;
margin: -1px 0 0;
@ -1438,7 +1457,7 @@ table.links-table {
margin: 25px 10px;
}
.tagchecklist span {
.tagchecklist > span {
font-size: 16px;
line-height: 1.4;
}

File diff suppressed because one or more lines are too long

View File

@ -594,11 +594,18 @@ ul#add-to-blog-users {
padding: 4px 10px;
white-space: nowrap;
text-align: right;
cursor: pointer;
}
.ui-autocomplete li.ui-state-focus {
/* Colors for the wplink toolbar autocomplete. */
.ui-autocomplete .ui-state-focus {
background-color: #ddd;
cursor: pointer;
}
/* Colors for the tags autocomplete. */
.wp-tags-autocomplete .ui-state-focus {
background-color: #0073aa;
color: #fff;
}
/*------------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -594,11 +594,18 @@ ul#add-to-blog-users {
padding: 4px 10px;
white-space: nowrap;
text-align: left;
cursor: pointer;
}
.ui-autocomplete li.ui-state-focus {
/* Colors for the wplink toolbar autocomplete. */
.ui-autocomplete .ui-state-focus {
background-color: #ddd;
cursor: pointer;
}
/* Colors for the tags autocomplete. */
.wp-tags-autocomplete .ui-state-focus {
background-color: #0073aa;
color: #fff;
}
/*------------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -441,11 +441,15 @@ div#dashboard-widgets {
padding-left: 1px;
}
.tagchecklist span, .tagchecklist span a {
.tagchecklist > span, .tagchecklist .ntdelbutton {
display: inline-block;
display: block;
}
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
outline: 1px solid #5b9dd9;
}
.tablenav .button,
.nav .button {
padding-top: 2px;

File diff suppressed because one or more lines are too long

View File

@ -441,11 +441,15 @@ div#dashboard-widgets {
padding-right: 1px;
}
.tagchecklist span, .tagchecklist span a {
.tagchecklist > span, .tagchecklist .ntdelbutton {
display: inline-block;
display: block;
}
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
outline: 1px solid #5b9dd9;
}
.tablenav .button,
.nav .button {
padding-top: 2px;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -770,38 +770,6 @@ dd {
margin: 10px 16px 6px 0;
}
/* Tag hint TODO needed? */
/* Tag suggestions */
.ac_results {
padding: 0;
margin: -1px -1px 0 0;
list-style: none;
position: absolute;
z-index: 10000;
display: none;
border: 1px solid #d8d8d8;
background-color: #fff;
font-size: 14px;
}
.ac_results li {
padding: 6px 16px;
white-space: nowrap;
text-align: right;
}
.ac_results .ac_over {
background-color: #e5e5e5;
background-color: #00a0d2;
color: #fff;
cursor: pointer;
}
.ac_match {
text-decoration: underline;
}
/* Tags */
.tagchecklist {
padding: 16px 28px 5px;
@ -817,10 +785,9 @@ dd {
clear: both;
}
.tagchecklist span {
display: block;
margin-left: 25px;
.tagchecklist > span {
float: right;
margin-left: 25px;
font-size: 13px;
line-height: 1.8;
white-space: nowrap;
@ -828,7 +795,7 @@ dd {
}
@media (max-width: 600px) {
.tagchecklist span {
.tagchecklist > span {
margin-bottom: 15px;
font-size: 16px;
line-height: 1.3;
@ -836,36 +803,51 @@ dd {
}
.tagchecklist .ntdelbutton {
margin: 1px -17px 0 0;
cursor: pointer;
width: 20px;
height: 20px;
display: block;
float: right;
text-indent: 0;
overflow: hidden;
position: absolute;
outline: 0;
width: 24px;
height: 24px;
border: none;
margin: 0 -19px 0 0;
padding: 0;
background: none;
cursor: pointer;
text-indent: 0;;
position: absolute;
}
.tagchecklist .ntdelbutton:before {
.tagchecklist .ntdelbutton .remove-tag-icon:before {
content: "\f153";
display: block;
margin: 2px 0;
margin-right: 2px;
height: 20px;
width: 20px;
background: 100% 0;
color: #9ea7af;
font: 400 16px/1 dashicons;
-webkit-border-radius: 50%;
border-radius: 50%;
background: transparent;
color: #0073aa;
/* line-height tweak to vertically center the icon cross browsers */
font: 400 16px/1.28 dashicons;
text-align: center;
speak: none;
-webkit-font-smoothing: antialiased;
}
.tagchecklist .ntdelbutton:focus:before {
color: #00a0d2;
.tagchecklist .ntdelbutton:focus {
outline: 0;
}
.tagchecklist .ntdelbutton:hover .remove-tag-icon:before,
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
color: #c00;
}
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
-webkit-box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
/* THE TAG CLOUD. */
.tagsdiv + p {
@ -2194,6 +2176,7 @@ html {
-webkit-box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 );
box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 );
background-color: #fff;
font-size: 14px;
}
.ui-autocomplete li {
@ -2201,9 +2184,16 @@ html {
padding: 4px 10px;
white-space: nowrap;
text-align: right;
}
.ui-autocomplete li.ui-state-focus {
background-color: #ddd;
cursor: pointer;
}
/* Colors for the wplink toolbar autocomplete. */
.ui-autocomplete .ui-state-focus {
background-color: #ddd;
}
/* Colors for the tags autocomplete. */
.wp-tags-autocomplete .ui-state-focus {
background-color: #0073aa;
color: #fff;
}

File diff suppressed because one or more lines are too long

View File

@ -770,38 +770,6 @@ dd {
margin: 10px 0 6px 16px;
}
/* Tag hint TODO needed? */
/* Tag suggestions */
.ac_results {
padding: 0;
margin: -1px 0 0 -1px;
list-style: none;
position: absolute;
z-index: 10000;
display: none;
border: 1px solid #d8d8d8;
background-color: #fff;
font-size: 14px;
}
.ac_results li {
padding: 6px 16px;
white-space: nowrap;
text-align: left;
}
.ac_results .ac_over {
background-color: #e5e5e5;
background-color: #00a0d2;
color: #fff;
cursor: pointer;
}
.ac_match {
text-decoration: underline;
}
/* Tags */
.tagchecklist {
padding: 16px 28px 5px;
@ -817,10 +785,9 @@ dd {
clear: both;
}
.tagchecklist span {
display: block;
margin-right: 25px;
.tagchecklist > span {
float: left;
margin-right: 25px;
font-size: 13px;
line-height: 1.8;
white-space: nowrap;
@ -828,7 +795,7 @@ dd {
}
@media (max-width: 600px) {
.tagchecklist span {
.tagchecklist > span {
margin-bottom: 15px;
font-size: 16px;
line-height: 1.3;
@ -836,36 +803,51 @@ dd {
}
.tagchecklist .ntdelbutton {
margin: 1px 0 0 -17px;
cursor: pointer;
width: 20px;
height: 20px;
display: block;
float: left;
text-indent: 0;
overflow: hidden;
position: absolute;
outline: 0;
width: 24px;
height: 24px;
border: none;
margin: 0 0 0 -19px;
padding: 0;
background: none;
cursor: pointer;
text-indent: 0;;
position: absolute;
}
.tagchecklist .ntdelbutton:before {
.tagchecklist .ntdelbutton .remove-tag-icon:before {
content: "\f153";
display: block;
margin: 2px 0;
margin-left: 2px;
height: 20px;
width: 20px;
background: 0 0;
color: #9ea7af;
font: 400 16px/1 dashicons;
-webkit-border-radius: 50%;
border-radius: 50%;
background: transparent;
color: #0073aa;
/* line-height tweak to vertically center the icon cross browsers */
font: 400 16px/1.28 dashicons;
text-align: center;
speak: none;
-webkit-font-smoothing: antialiased;
}
.tagchecklist .ntdelbutton:focus:before {
color: #00a0d2;
.tagchecklist .ntdelbutton:focus {
outline: 0;
}
.tagchecklist .ntdelbutton:hover .remove-tag-icon:before,
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
color: #c00;
}
.tagchecklist .ntdelbutton:focus .remove-tag-icon:before {
-webkit-box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow:
0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
/* THE TAG CLOUD. */
.tagsdiv + p {
@ -2194,6 +2176,7 @@ html {
-webkit-box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 );
box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 );
background-color: #fff;
font-size: 14px;
}
.ui-autocomplete li {
@ -2201,9 +2184,16 @@ html {
padding: 4px 10px;
white-space: nowrap;
text-align: left;
}
.ui-autocomplete li.ui-state-focus {
background-color: #ddd;
cursor: pointer;
}
/* Colors for the wplink toolbar autocomplete. */
.ui-autocomplete .ui-state-focus {
background-color: #ddd;
}
/* Colors for the tags autocomplete. */
.wp-tags-autocomplete .ui-state-focus {
background-color: #0073aa;
color: #fff;
}

File diff suppressed because one or more lines are too long

View File

@ -940,7 +940,7 @@ class WP_Press_This {
if ( $user_can_assign_terms ) {
?>
<button type="button" class="button-link tagcloud-link" id="link-post_tag"><?php echo $taxonomy->labels->choose_from_most_used; ?></button>
<button type="button" class="button-link tagcloud-link" id="link-post_tag" aria-expanded="false"><?php echo $taxonomy->labels->choose_from_most_used; ?></button>
<?php
}
}

View File

@ -442,7 +442,7 @@ function post_tags_meta_box( $post, $box ) {
<div class="tagchecklist"></div>
</div>
<?php if ( $user_can_assign_terms ) : ?>
<p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
<p class="hide-if-no-js"><button type="button" class="button-link tagcloud-link" id="link-<?php echo $tax_name; ?>" aria-expanded="false"><?php echo $taxonomy->labels->choose_from_most_used; ?></button></p>
<?php endif; ?>
<?php
}

View File

@ -86,16 +86,28 @@ var tagBox, array_unique_noempty;
// If tags editing isn't disabled, create the X button.
if ( ! disabled ) {
xbutton = $( '<a id="' + id + '-check-num-' + key + '" class="ntdelbutton" tabindex="0">X</a>' );
/*
* Build the X buttons, hide the X icon with aria-hidden and
* use visually hidden text for screen readers.
*/
xbutton = $( '<button type="button" id="' + id + '-check-num-' + key + '" class="ntdelbutton">' +
'<span class="remove-tag-icon" aria-hidden="true"></span>' +
'<span class="screen-reader-text">' + window.tagsSuggestL10n.removeTerm + ' ' + val + '</span>' +
'</button>' );
xbutton.on( 'click keypress', function( e ) {
// Trigger function if pressed Enter - keyboard navigation
if ( e.type === 'click' || e.keyCode === 13 ) {
// When using keyboard, move focus back to the new tag field.
if ( e.keyCode === 13 ) {
$( this ).closest( '.tagsdiv' ).find( 'input.newtag' ).focus();
}
// On click or when using the Enter/Spacebar keys.
if ( 'click' === e.type || 13 === e.keyCode || 32 === e.keyCode ) {
/*
* When using the keyboard, move focus back to the
* add new tag field. Note: when releasing the pressed
* key this will fire the `keyup` event on the input.
*/
if ( 13 === e.keyCode || 32 === e.keyCode ) {
$( this ).closest( '.tagsdiv' ).find( 'input.newtag' ).focus();
}
tagBox.userAction = 'remove';
tagBox.parseTags( this );
}
});
@ -106,6 +118,8 @@ var tagBox, array_unique_noempty;
// Append the span to the tag list.
tagchecklist.append( span );
});
// The buttons list is built now, give feedback to screen reader users.
tagBox.screenReadersMessage();
},
flushTags : function( el, a, f ) {
@ -117,7 +131,14 @@ var tagBox, array_unique_noempty;
text = a ? $(a).text() : newtag.val();
if ( 'undefined' == typeof( text ) ) {
/*
* Return if there's no new tag or if the input field is empty.
* Note: when using the keyboard to add tags, focus is moved back to
* the input field and the `keyup` event attached on this field will
* fire when releasing the pressed key. Checking also for the field
* emptiness avoids to set the tags and call quickClicks() again.
*/
if ( 'undefined' == typeof( text ) || '' === text ) {
return false;
}
@ -148,6 +169,7 @@ var tagBox, array_unique_noempty;
r = $( '<p id="tagcloud-' + tax + '" class="the-tagcloud">' + r + '</p>' );
$( 'a', r ).click( function() {
tagBox.userAction = 'add';
tagBox.flushTags( $( '#' + tax ), this );
return false;
});
@ -156,6 +178,37 @@ var tagBox, array_unique_noempty;
});
},
/**
* Track the user's last action.
*
* @since 4.7.0
*/
userAction: '',
/**
* Dispatch an audible message to screen readers.
*
* @since 4.7.0
*/
screenReadersMessage: function() {
var message;
switch ( this.userAction ) {
case 'remove':
message = window.tagsSuggestL10n.termRemoved;
break;
case 'add':
message = window.tagsSuggestL10n.termAdded;
break;
default:
return;
}
window.wp.a11y.speak( message, 'assertive' );
},
init : function() {
var ajaxtag = $('div.ajaxtag');
@ -164,11 +217,13 @@ var tagBox, array_unique_noempty;
});
$( '.tagadd', ajaxtag ).click( function() {
tagBox.userAction = 'add';
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
});
$( 'input.newtag', ajaxtag ).keyup( function( event ) {
if ( 13 == event.which ) {
tagBox.userAction = 'add';
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
event.preventDefault();
event.stopPropagation();
@ -189,14 +244,19 @@ var tagBox, array_unique_noempty;
});
});
// tag cloud
// Fetch and toggle the Tag cloud.
$('.tagcloud-link').click(function(){
tagBox.get( $(this).attr('id') );
$(this).unbind().click(function(){
$(this).siblings('.the-tagcloud').toggle();
return false;
});
return false;
// On the first click, fetch the tag cloud and insert it in the DOM.
tagBox.get( $( this ).attr( 'id' ) );
// Update button state, remove previous click event and attach a new one to toggle the cloud.
$( this )
.attr( 'aria-expanded', 'true' )
.unbind()
.click( function() {
$( this )
.attr( 'aria-expanded', 'false' === $( this ).attr( 'aria-expanded' ) ? 'true' : 'false' )
.siblings( '.the-tagcloud' ).toggle();
});
});
}
};

View File

@ -1 +1 @@
var tagBox,array_unique_noempty;!function(a){var b=window.tagsSuggestL10n&&window.tagsSuggestL10n.tagDelimiter||",";array_unique_noempty=function(b){var c=[];return a.each(b,function(b,d){d=a.trim(d),d&&-1===a.inArray(d,c)&&c.push(d)}),c},tagBox={clean:function(a){return","!==b&&(a=a.replace(new RegExp(b,"g"),",")),a=a.replace(/\s*,\s*/g,",").replace(/,+/g,",").replace(/[,\s]+$/,"").replace(/^[,\s]+/,""),","!==b&&(a=a.replace(/,/g,b)),a},parseTags:function(c){var d=c.id,e=d.split("-check-num-")[1],f=a(c).closest(".tagsdiv"),g=f.find(".the-tags"),h=g.val().split(b),i=[];return delete h[e],a.each(h,function(b,c){c=a.trim(c),c&&i.push(c)}),g.val(this.clean(i.join(b))),this.quickClicks(f),!1},quickClicks:function(c){var d,e,f=a(".the-tags",c),g=a(".tagchecklist",c),h=a(c).attr("id");f.length&&(e=f.prop("disabled"),d=f.val().split(b),g.empty(),a.each(d,function(b,c){var d,f;c=a.trim(c),c&&(d=a("<span />").text(c),e||(f=a('<a id="'+h+"-check-num-"+b+'" class="ntdelbutton" tabindex="0">X</a>'),f.on("click keypress",function(b){"click"!==b.type&&13!==b.keyCode||(13===b.keyCode&&a(this).closest(".tagsdiv").find("input.newtag").focus(),tagBox.parseTags(this))}),d.prepend("&nbsp;").prepend(f)),g.append(d))}))},flushTags:function(c,d,e){var f,g,h,i=a(".the-tags",c),j=a("input.newtag",c);return d=d||!1,h=d?a(d).text():j.val(),"undefined"==typeof h?!1:(f=i.val(),g=f?f+b+h:h,g=this.clean(g),g=array_unique_noempty(g.split(b)).join(b),i.val(g),this.quickClicks(c),d||j.val(""),"undefined"==typeof e&&j.focus(),!1)},get:function(b){var c=b.substr(b.indexOf("-")+1);a.post(ajaxurl,{action:"get-tagcloud",tax:c},function(d,e){0!==d&&"success"==e&&(d=a('<p id="tagcloud-'+c+'" class="the-tagcloud">'+d+"</p>"),a("a",d).click(function(){return tagBox.flushTags(a("#"+c),this),!1}),a("#"+b).after(d))})},init:function(){var b=a("div.ajaxtag");a(".tagsdiv").each(function(){tagBox.quickClicks(this)}),a(".tagadd",b).click(function(){tagBox.flushTags(a(this).closest(".tagsdiv"))}),a("input.newtag",b).keyup(function(b){13==b.which&&(tagBox.flushTags(a(this).closest(".tagsdiv")),b.preventDefault(),b.stopPropagation())}).keypress(function(a){13==a.which&&(a.preventDefault(),a.stopPropagation())}).each(function(b,c){a(c).wpTagsSuggest()}),a("#post").submit(function(){a("div.tagsdiv").each(function(){tagBox.flushTags(this,!1,1)})}),a(".tagcloud-link").click(function(){return tagBox.get(a(this).attr("id")),a(this).unbind().click(function(){return a(this).siblings(".the-tagcloud").toggle(),!1}),!1})}}}(jQuery);
var tagBox,array_unique_noempty;!function(a){var b=window.tagsSuggestL10n&&window.tagsSuggestL10n.tagDelimiter||",";array_unique_noempty=function(b){var c=[];return a.each(b,function(b,d){d=a.trim(d),d&&-1===a.inArray(d,c)&&c.push(d)}),c},tagBox={clean:function(a){return","!==b&&(a=a.replace(new RegExp(b,"g"),",")),a=a.replace(/\s*,\s*/g,",").replace(/,+/g,",").replace(/[,\s]+$/,"").replace(/^[,\s]+/,""),","!==b&&(a=a.replace(/,/g,b)),a},parseTags:function(c){var d=c.id,e=d.split("-check-num-")[1],f=a(c).closest(".tagsdiv"),g=f.find(".the-tags"),h=g.val().split(b),i=[];return delete h[e],a.each(h,function(b,c){c=a.trim(c),c&&i.push(c)}),g.val(this.clean(i.join(b))),this.quickClicks(f),!1},quickClicks:function(c){var d,e,f=a(".the-tags",c),g=a(".tagchecklist",c),h=a(c).attr("id");f.length&&(e=f.prop("disabled"),d=f.val().split(b),g.empty(),a.each(d,function(b,c){var d,f;c=a.trim(c),c&&(d=a("<span />").text(c),e||(f=a('<button type="button" id="'+h+"-check-num-"+b+'" class="ntdelbutton"><span class="remove-tag-icon" aria-hidden="true"></span><span class="screen-reader-text">'+window.tagsSuggestL10n.removeTerm+" "+c+"</span></button>"),f.on("click keypress",function(b){"click"!==b.type&&13!==b.keyCode&&32!==b.keyCode||(13!==b.keyCode&&32!==b.keyCode||a(this).closest(".tagsdiv").find("input.newtag").focus(),tagBox.userAction="remove",tagBox.parseTags(this))}),d.prepend("&nbsp;").prepend(f)),g.append(d))}),tagBox.screenReadersMessage())},flushTags:function(c,d,e){var f,g,h,i=a(".the-tags",c),j=a("input.newtag",c);return d=d||!1,h=d?a(d).text():j.val(),"undefined"==typeof h||""===h?!1:(f=i.val(),g=f?f+b+h:h,g=this.clean(g),g=array_unique_noempty(g.split(b)).join(b),i.val(g),this.quickClicks(c),d||j.val(""),"undefined"==typeof e&&j.focus(),!1)},get:function(b){var c=b.substr(b.indexOf("-")+1);a.post(ajaxurl,{action:"get-tagcloud",tax:c},function(d,e){0!==d&&"success"==e&&(d=a('<p id="tagcloud-'+c+'" class="the-tagcloud">'+d+"</p>"),a("a",d).click(function(){return tagBox.userAction="add",tagBox.flushTags(a("#"+c),this),!1}),a("#"+b).after(d))})},userAction:"",screenReadersMessage:function(){var a;switch(this.userAction){case"remove":a=window.tagsSuggestL10n.termRemoved;break;case"add":a=window.tagsSuggestL10n.termAdded;break;default:return}window.wp.a11y.speak(a,"assertive")},init:function(){var b=a("div.ajaxtag");a(".tagsdiv").each(function(){tagBox.quickClicks(this)}),a(".tagadd",b).click(function(){tagBox.userAction="add",tagBox.flushTags(a(this).closest(".tagsdiv"))}),a("input.newtag",b).keyup(function(b){13==b.which&&(tagBox.userAction="add",tagBox.flushTags(a(this).closest(".tagsdiv")),b.preventDefault(),b.stopPropagation())}).keypress(function(a){13==a.which&&(a.preventDefault(),a.stopPropagation())}).each(function(b,c){a(c).wpTagsSuggest()}),a("#post").submit(function(){a("div.tagsdiv").each(function(){tagBox.flushTags(this,!1,1)})}),a(".tagcloud-link").click(function(){tagBox.get(a(this).attr("id")),a(this).attr("aria-expanded","true").unbind().click(function(){a(this).attr("aria-expanded","false"===a(this).attr("aria-expanded")?"true":"false").siblings(".the-tagcloud").toggle()})})}}}(jQuery);

View File

@ -1,6 +1,13 @@
/**
* Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies.
*/
( function( $ ) {
if ( typeof window.tagsSuggestL10n === 'undefined' || typeof window.uiAutocompleteL10n === 'undefined' ) {
return;
}
var tempID = 0;
var separator = ( window.tagsSuggestL10n && window.tagsSuggestL10n.tagDelimiter ) || ',';
var separator = window.tagsSuggestL10n.tagDelimiter || ',';
function split( val ) {
return val.split( new RegExp( separator + '\\s*' ) );
@ -10,19 +17,33 @@
return split( term ).pop();
}
/**
* Add UI Autocomplete to an input or textarea element with presets for use
* with non-hierarchical taxonomies.
*
* Example: `$( element ).wpTagsSuggest( options )`.
*
* The taxonomy can be passed in a `data-wp-taxonomy` attribute on the element or
* can be in `options.taxonomy`.
*
* @since 4.7
*
* @param {object} options Options that are passed to UI Autocomplete. Can be used to override the default settings.
* @returns {object} jQuery instance.
*/
$.fn.wpTagsSuggest = function( options ) {
var cache;
var last;
var $element = $( this );
options = options || {};
var taxonomy = options.taxonomy || $element.attr( 'data-wp-taxonomy' ) || 'post_tag';
delete( options.taxonomy );
options = $.extend( {
source: function( request, response ) {
source: function( request, response ) {
var term;
if ( last === request.term ) {
@ -39,25 +60,25 @@
} ).always( function() {
$element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes?
} ).done( function( data ) {
var value;
var terms = [];
var tagName;
var tags = [];
if ( data ) {
data = data.split( '\n' );
for ( value in data ) {
for ( tagName in data ) {
var id = ++tempID;
terms.push({
tags.push({
id: id,
name: data[value]
name: data[tagName]
});
}
cache = terms;
response( terms );
cache = tags;
response( tags );
} else {
response( terms );
response( tags );
}
} );
@ -80,11 +101,8 @@
$element.val( tags.join( separator + ' ' ) );
if ( $.ui.keyCode.TAB === event.keyCode ) {
if ( typeof window.uiAutocompleteL10n !== 'undefined' ) {
// Audible confirmation message when a tag has been selected.
window.wp.a11y.speak( window.uiAutocompleteL10n.itemSelected );
}
// Audible confirmation message when a tag has been selected.
window.wp.a11y.speak( window.tagsSuggestL10n.termSelected, 'assertive' );
event.preventDefault();
} else if ( $.ui.keyCode.ENTER === event.keyCode ) {
// Do not close Quick Edit / Bulk Edit
@ -105,15 +123,13 @@
my: 'left top+2'
},
messages: {
noResults: ( typeof window.uiAutocompleteL10n !== 'undefined' ) ? window.uiAutocompleteL10n.noResults : '',
noResults: window.uiAutocompleteL10n.noResults,
results: function( number ) {
if ( typeof window.uiAutocompleteL10n !== 'undefined' ) {
if ( number > 1 ) {
return window.uiAutocompleteL10n.manyResults.replace( '%d', number );
}
return window.uiAutocompleteL10n.oneResult;
if ( number > 1 ) {
return window.uiAutocompleteL10n.manyResults.replace( '%d', number );
}
return window.uiAutocompleteL10n.oneResult;
}
}
}, options );
@ -160,7 +176,7 @@
// so we need to find the active item with other means.
$( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' );
});
return this;
};

View File

@ -1 +1 @@
!function(a){function b(a){return a.split(new RegExp(e+"\\s*"))}function c(a){return b(a).pop()}var d=0,e=window.tagsSuggestL10n&&window.tagsSuggestL10n.tagDelimiter||",";a.fn.wpTagsSuggest=function(f){var g,h,i=a(this);f=f||{};var j=f.taxonomy||i.attr("data-wp-taxonomy")||"post_tag";return delete f.taxonomy,f=a.extend({source:function(b,e){var f;return h===b.term?void e(g):(f=c(b.term),a.get(window.ajaxurl,{action:"ajax-tag-search",tax:j,q:f}).always(function(){i.removeClass("ui-autocomplete-loading")}).done(function(a){var b,c=[];if(a){a=a.split("\n");for(b in a){var f=++d;c.push({id:f,name:a[b]})}g=c,e(c)}else e(c)}),void(h=b.term))},focus:function(a,b){i.attr("aria-activedescendant","wp-tags-autocomplete-"+b.item.id),a.preventDefault()},select:function(c,d){var f=b(i.val());return f.pop(),f.push(d.item.name,""),i.val(f.join(e+" ")),a.ui.keyCode.TAB===c.keyCode?("undefined"!=typeof window.uiAutocompleteL10n&&window.wp.a11y.speak(window.uiAutocompleteL10n.itemSelected),c.preventDefault()):a.ui.keyCode.ENTER===c.keyCode&&(c.preventDefault(),c.stopPropagation()),!1},open:function(){i.attr("aria-expanded","true")},close:function(){i.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"},messages:{noResults:"undefined"!=typeof window.uiAutocompleteL10n?window.uiAutocompleteL10n.noResults:"",results:function(a){return"undefined"!=typeof window.uiAutocompleteL10n?a>1?window.uiAutocompleteL10n.manyResults.replace("%d",a):window.uiAutocompleteL10n.oneResult:void 0}}},f),i.on("keydown",function(){i.removeAttr("aria-activedescendant")}).autocomplete(f).autocomplete("instance")._renderItem=function(b,c){return a('<li role="option" id="wp-tags-autocomplete-'+c.id+'">').text(c.name).appendTo(b)},i.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":i.autocomplete("widget").attr("id")}).on("focus",function(){var a=b(i.val()).pop();a&&i.autocomplete("search")}).autocomplete("widget").addClass("wp-tags-autocomplete").attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")}),this}}(jQuery);
!function(a){function b(a){return a.split(new RegExp(e+"\\s*"))}function c(a){return b(a).pop()}if("undefined"!=typeof window.tagsSuggestL10n&&"undefined"!=typeof window.uiAutocompleteL10n){var d=0,e=window.tagsSuggestL10n.tagDelimiter||",";a.fn.wpTagsSuggest=function(f){var g,h,i=a(this);f=f||{};var j=f.taxonomy||i.attr("data-wp-taxonomy")||"post_tag";return delete f.taxonomy,f=a.extend({source:function(b,e){var f;return h===b.term?void e(g):(f=c(b.term),a.get(window.ajaxurl,{action:"ajax-tag-search",tax:j,q:f}).always(function(){i.removeClass("ui-autocomplete-loading")}).done(function(a){var b,c=[];if(a){a=a.split("\n");for(b in a){var f=++d;c.push({id:f,name:a[b]})}g=c,e(c)}else e(c)}),void(h=b.term))},focus:function(a,b){i.attr("aria-activedescendant","wp-tags-autocomplete-"+b.item.id),a.preventDefault()},select:function(c,d){var f=b(i.val());return f.pop(),f.push(d.item.name,""),i.val(f.join(e+" ")),a.ui.keyCode.TAB===c.keyCode?(window.wp.a11y.speak(window.tagsSuggestL10n.termSelected,"assertive"),c.preventDefault()):a.ui.keyCode.ENTER===c.keyCode&&(c.preventDefault(),c.stopPropagation()),!1},open:function(){i.attr("aria-expanded","true")},close:function(){i.attr("aria-expanded","false")},minLength:2,position:{my:"left top+2"},messages:{noResults:window.uiAutocompleteL10n.noResults,results:function(a){return a>1?window.uiAutocompleteL10n.manyResults.replace("%d",a):window.uiAutocompleteL10n.oneResult}}},f),i.on("keydown",function(){i.removeAttr("aria-activedescendant")}).autocomplete(f).autocomplete("instance")._renderItem=function(b,c){return a('<li role="option" id="wp-tags-autocomplete-'+c.id+'">').text(c.name).appendTo(b)},i.attr({role:"combobox","aria-autocomplete":"list","aria-expanded":"false","aria-owns":i.autocomplete("widget").attr("id")}).on("focus",function(){var a=b(i.val()).pop();a&&i.autocomplete("search")}).autocomplete("widget").addClass("wp-tags-autocomplete").attr("role","listbox").removeAttr("tabindex").on("menufocus",function(a,b){b.item.attr("aria-selected","true")}).on("menublur",function(){a(this).find('[aria-selected="true"]').removeAttr("aria-selected")}),this}}}(jQuery);

View File

@ -538,6 +538,10 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'tags-suggest', "/wp-admin/js/tags-suggest$suffix.js", array( 'jquery-ui-autocomplete', 'wp-a11y' ), false, 1 );
did_action( 'init' ) && $scripts->localize( 'tags-suggest', 'tagsSuggestL10n', array(
'tagDelimiter' => _x( ',', 'tag delimiter' ),
'removeTerm' => __( 'Remove term:' ),
'termSelected' => __( 'Term selected.' ),
'termAdded' => __( 'Term added.' ),
'termRemoved' => __( 'Term removed.' ),
) );
$scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count', 'wp-a11y' ), false, 1 );

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.7-alpha-38879';
$wp_version = '4.7-alpha-38880';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.