Accessibility improvements for Themes screen: fix keyboard events and callbacks for the Search field, increase trigger timeout a bit, improve Esc. key handling.

Props joedolson, adamsilverstein, afercia, DrewAPicture. Fixes #26600.

git-svn-id: https://develop.svn.wordpress.org/trunk@31994 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz 2015-04-03 02:31:11 +00:00
parent 04fbf4cd60
commit c3d7fa68ce
6 changed files with 58 additions and 32 deletions

View File

@ -1138,7 +1138,7 @@ p.no-themes {
font-size: 18px; font-size: 18px;
font-style: normal; font-style: normal;
margin: 0; margin: 0;
padding: 100px 0 0; padding: 0;
text-align: center; text-align: center;
display: none; display: none;
} }

View File

@ -79,8 +79,7 @@ themes.view.Appearance = wp.Backbone.View.extend({
// Render and append // Render and append
this.view.render(); this.view.render();
this.$el.find( '.themes' ).remove(); this.$el.empty().append( this.view.el ).addClass( 'rendered' );
this.$el.append( this.view.el ).addClass( 'rendered' );
this.$el.append( '<br class="clear"/>' ); this.$el.append( '<br class="clear"/>' );
}, },
@ -157,6 +156,7 @@ themes.Collection = Backbone.Collection.extend({
// Useful for resetting the views when you clean the input // Useful for resetting the views when you clean the input
if ( this.terms === '' ) { if ( this.terms === '' ) {
this.reset( themes.data.themes ); this.reset( themes.data.themes );
$( 'body' ).removeClass( 'no-results' );
} }
// Trigger an 'update' event // Trigger an 'update' event
@ -831,6 +831,9 @@ themes.view.Themes = wp.Backbone.View.extend({
// The theme count element // The theme count element
count: $( '.wp-core-ui .theme-count' ), count: $( '.wp-core-ui .theme-count' ),
// The live themes count
liveThemeCount: 0,
initialize: function( options ) { initialize: function( options ) {
var self = this; var self = this;
@ -854,8 +857,10 @@ themes.view.Themes = wp.Backbone.View.extend({
this.listenTo( self.collection, 'query:success', function( count ) { this.listenTo( self.collection, 'query:success', function( count ) {
if ( _.isNumber( count ) ) { if ( _.isNumber( count ) ) {
self.count.text( count ); self.count.text( count );
self.announceSearchResults( count );
} else { } else {
self.count.text( self.collection.length ); self.count.text( self.collection.length );
self.announceSearchResults( self.collection.length );
} }
}); });
@ -926,7 +931,10 @@ themes.view.Themes = wp.Backbone.View.extend({
} }
// Display a live theme count for the collection // Display a live theme count for the collection
this.count.text( this.collection.count ? this.collection.count : this.collection.length ); this.liveThemeCount = this.collection.count ? this.collection.count : this.collection.length;
this.count.text( this.liveThemeCount );
this.announceSearchResults( this.liveThemeCount );
}, },
// Iterates through each instance of the collection // Iterates through each instance of the collection
@ -1078,6 +1086,15 @@ themes.view.Themes = wp.Backbone.View.extend({
self.theme.trigger( 'theme:expand', previousModel.cid ); self.theme.trigger( 'theme:expand', previousModel.cid );
} }
},
// Dispatch audible search results feedback message
announceSearchResults: function( count ) {
if ( 0 === count ) {
wp.a11y.speak( l10n.noThemesFound );
} else {
wp.a11y.speak( l10n.themesFound.replace( '%d', count ) );
}
} }
}); });
@ -1091,14 +1108,13 @@ themes.view.Search = wp.Backbone.View.extend({
attributes: { attributes: {
placeholder: l10n.searchPlaceholder, placeholder: l10n.searchPlaceholder,
type: 'search' type: 'search',
'aria-describedby': 'live-search-desc'
}, },
events: { events: {
'input': 'search', 'input': 'search',
'keyup': 'search', 'keyup': 'search',
'change': 'search',
'search': 'search',
'blur': 'pushState' 'blur': 'pushState'
}, },
@ -1112,19 +1128,21 @@ themes.view.Search = wp.Backbone.View.extend({
}, },
// Runs a search on the theme collection.
search: function( event ) { search: function( event ) {
var options = {};
// Clear on escape. // Clear on escape.
if ( event.type === 'keyup' && event.which === 27 ) { if ( event.type === 'keyup' && event.which === 27 ) {
event.target.value = ''; event.target.value = '';
} }
// Lose input focus when pressing enter /**
if ( event.which === 13 ) { * Since doSearch is debounced, it will only run when user input comes to a rest
this.$el.trigger( 'blur' ); */
} this.doSearch( event );
},
// Runs a search on the theme collection.
doSearch: _.debounce( function( event ) {
var options = {};
this.collection.doSearch( event.target.value ); this.collection.doSearch( event.target.value );
@ -1141,7 +1159,7 @@ themes.view.Search = wp.Backbone.View.extend({
} else { } else {
themes.router.navigate( themes.router.baseUrl( '' ) ); themes.router.navigate( themes.router.baseUrl( '' ) );
} }
}, }, 500 ),
pushState: function( event ) { pushState: function( event ) {
var url = themes.router.baseUrl( '' ); var url = themes.router.baseUrl( '' );
@ -1252,6 +1270,7 @@ themes.Run = {
themes.view.InstallerSearch = themes.view.Search.extend({ themes.view.InstallerSearch = themes.view.Search.extend({
events: { events: {
'input': 'search',
'keyup': 'search' 'keyup': 'search'
}, },
@ -1305,7 +1324,7 @@ themes.view.InstallerSearch = themes.view.Search.extend({
// Set route // Set route
themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + value ), { replace: true } ); themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + value ), { replace: true } );
}, 300 ) }, 500 )
}); });
themes.view.Installer = themes.view.Appearance.extend({ themes.view.Installer = themes.view.Appearance.extend({

View File

@ -48,7 +48,9 @@ wp_localize_script( 'theme', '_wpThemeSettings', array(
'searchPlaceholder' => __( 'Search themes...' ), // placeholder (no ellipsis) 'searchPlaceholder' => __( 'Search themes...' ), // placeholder (no ellipsis)
'upload' => __( 'Upload Theme' ), 'upload' => __( 'Upload Theme' ),
'back' => __( 'Back' ), 'back' => __( 'Back' ),
'error' => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) 'error' => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ),
'themesFound' => __( 'Number of Themes found: %d' ),
'noThemesFound' => __( 'No themes found. Try a different search.' ),
), ),
'installedThemes' => array_keys( $installed_themes ), 'installedThemes' => array_keys( $installed_themes ),
) ); ) );
@ -70,7 +72,8 @@ if ( $tab ) {
$help_overview = $help_overview =
'<p>' . sprintf(__('You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the <a href="%s" target="_blank">WordPress.org Theme Directory</a>. These themes are designed and developed by third parties, are available free of charge, and are compatible with the license WordPress uses.'), 'https://wordpress.org/themes/') . '</p>' . '<p>' . sprintf(__('You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the <a href="%s" target="_blank">WordPress.org Theme Directory</a>. These themes are designed and developed by third parties, are available free of charge, and are compatible with the license WordPress uses.'), 'https://wordpress.org/themes/') . '</p>' .
'<p>' . __('You can Search for themes by keyword, author, or tag, or can get more specific and search by criteria listed in the feature filter. Alternately, you can browse the themes that are Featured, Popular, or Latest. When you find a theme you like, you can preview it or install it.') . '</p>' . '<p>' . __( 'You can Search for themes by keyword, author, or tag, or can get more specific and search by criteria listed in the feature filter.' ) . ' <span id="live-search-desc">' . __( 'The search results will be updated as you type.' ) . '</span></p>' .
'<p>' . __( 'Alternately, you can browse the themes that are Featured, Popular, or Latest. When you find a theme you like, you can preview it or install it.' ) . '</p>' .
'<p>' . __('You can Upload a theme manually if you have already downloaded its ZIP archive onto your computer (make sure it is from a trusted and original source). You can also do it the old-fashioned way and copy a downloaded theme&#8217;s folder via FTP into your <code>/wp-content/themes</code> directory.') . '</p>'; '<p>' . __('You can Upload a theme manually if you have already downloaded its ZIP archive onto your computer (make sure it is from a trusted and original source). You can also do it the old-fashioned way and copy a downloaded theme&#8217;s folder via FTP into your <code>/wp-content/themes</code> directory.') . '</p>';
get_current_screen()->add_help_tab( array( get_current_screen()->add_help_tab( array(
@ -166,10 +169,10 @@ include(ABSPATH . 'wp-admin/admin-header.php');
</div> </div>
</div> </div>
</div> </div>
<div class="theme-browser content-filterable" aria-live="polite"> <div class="theme-browser content-filterable"></div>
<p class="no-themes"><?php _e( 'No themes found. Try a different search.' ); ?></p>
</div>
<div class="theme-install-overlay wp-full-overlay expanded"></div> <div class="theme-install-overlay wp-full-overlay expanded"></div>
<p class="no-themes"><?php _e( 'No themes found. Try a different search.' ); ?></p>
<span class="spinner"></span> <span class="spinner"></span>
<br class="clear" /> <br class="clear" />

View File

@ -47,7 +47,8 @@ if ( current_user_can( 'switch_themes' ) ) {
'<ul><li>' . __( 'Hover or tap to see Activate and Live Preview buttons' ) . '</li>' . '<ul><li>' . __( 'Hover or tap to see Activate and Live Preview buttons' ) . '</li>' .
'<li>' . __( 'Click on the theme to see the theme name, version, author, description, tags, and the Delete link' ) . '</li>' . '<li>' . __( 'Click on the theme to see the theme name, version, author, description, tags, and the Delete link' ) . '</li>' .
'<li>' . __( 'Click Customize for the current theme or Live Preview for any other theme to see a live preview' ) . '</li></ul>' . '<li>' . __( 'Click Customize for the current theme or Live Preview for any other theme to see a live preview' ) . '</li></ul>' .
'<p>' . __( 'The current theme is displayed highlighted as the first theme.' ) . '</p>'; '<p>' . __( 'The current theme is displayed highlighted as the first theme.' ) . '</p>' .
'<p>' . __( 'The search for installed themes will search for terms in their name, description, author, or tag.' ) . ' <span id="live-search-desc">' . __( 'The search results will be updated as you type.' ) . '</span></p>';
get_current_screen()->add_help_tab( array( get_current_screen()->add_help_tab( array(
'id' => 'overview', 'id' => 'overview',
@ -110,6 +111,8 @@ wp_localize_script( 'theme', '_wpThemeSettings', array(
'addNew' => __( 'Add New Theme' ), 'addNew' => __( 'Add New Theme' ),
'search' => __( 'Search Installed Themes' ), 'search' => __( 'Search Installed Themes' ),
'searchPlaceholder' => __( 'Search installed themes...' ), // placeholder (no ellipsis) 'searchPlaceholder' => __( 'Search installed themes...' ), // placeholder (no ellipsis)
'themesFound' => __( 'Number of Themes found: %d' ),
'noThemesFound' => __( 'No themes found. Try a different search.' ),
), ),
) ); ) );
@ -198,7 +201,7 @@ if ( ! $ct->errors() || ( 1 == count( $ct->errors()->get_error_codes() )
?> ?>
<div class="theme-browser" aria-live="polite"> <div class="theme-browser">
<div class="themes"> <div class="themes">
<?php <?php
@ -255,10 +258,11 @@ foreach ( $themes as $theme ) :
<?php endforeach; ?> <?php endforeach; ?>
<br class="clear" /> <br class="clear" />
</div> </div>
<p class="no-themes"><?php _e( 'No themes found. Try a different search.' ); ?></p>
</div> </div>
<div class="theme-overlay"></div> <div class="theme-overlay"></div>
<p class="no-themes"><?php _e( 'No themes found. Try a different search.' ); ?></p>
<?php <?php
// List broken themes, if any. // List broken themes, if any.
if ( ! is_multisite() && current_user_can('edit_themes') && $broken_themes = wp_get_themes( array( 'errors' => true ) ) ) { if ( ! is_multisite() && current_user_can('edit_themes') && $broken_themes = wp_get_themes( array( 'errors' => true ) ) ) {

View File

@ -201,7 +201,7 @@ if ( isset($_GET['action']) ) {
if ( ! current_user_can('install_themes') ) if ( ! current_user_can('install_themes') )
wp_die( __( 'You do not have sufficient permissions to install themes on this site.' ) ); wp_die( __( 'You do not have sufficient permissions to install themes on this site.' ) );
include_once( ABSPATH . 'wp-admin/includes/theme-install.php' ); //for themes_api.. include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); //for themes_api..
check_admin_referer( 'install-theme_' . $theme ); check_admin_referer( 'install-theme_' . $theme );
$api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth. $api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth.

View File

@ -500,7 +500,7 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), false, 1 ); $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), false, 1 );
$scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone' ), false, 1 ); $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y' ), false, 1 );
$scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest' ), false, 1 ); $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest' ), false, 1 );
did_action( 'init' ) && $scripts->localize( 'inline-edit-post', 'inlineEditL10n', array( did_action( 'init' ) && $scripts->localize( 'inline-edit-post', 'inlineEditL10n', array(