diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index f59b2a98c5..8653ccd153 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -1138,7 +1138,7 @@ p.no-themes { font-size: 18px; font-style: normal; margin: 0; - padding: 100px 0 0; + padding: 0; text-align: center; display: none; } diff --git a/src/wp-admin/js/theme.js b/src/wp-admin/js/theme.js index fbd378961f..3a9a5fd30a 100644 --- a/src/wp-admin/js/theme.js +++ b/src/wp-admin/js/theme.js @@ -79,8 +79,7 @@ themes.view.Appearance = wp.Backbone.View.extend({ // Render and append this.view.render(); - this.$el.find( '.themes' ).remove(); - this.$el.append( this.view.el ).addClass( 'rendered' ); + this.$el.empty().append( this.view.el ).addClass( 'rendered' ); this.$el.append( '
' ); }, @@ -157,6 +156,7 @@ themes.Collection = Backbone.Collection.extend({ // Useful for resetting the views when you clean the input if ( this.terms === '' ) { this.reset( themes.data.themes ); + $( 'body' ).removeClass( 'no-results' ); } // Trigger an 'update' event @@ -831,6 +831,9 @@ themes.view.Themes = wp.Backbone.View.extend({ // The theme count element count: $( '.wp-core-ui .theme-count' ), + // The live themes count + liveThemeCount: 0, + initialize: function( options ) { var self = this; @@ -854,8 +857,10 @@ themes.view.Themes = wp.Backbone.View.extend({ this.listenTo( self.collection, 'query:success', function( count ) { if ( _.isNumber( count ) ) { self.count.text( count ); + self.announceSearchResults( count ); } else { 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 - 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 @@ -1078,6 +1086,15 @@ themes.view.Themes = wp.Backbone.View.extend({ 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,15 +1108,14 @@ themes.view.Search = wp.Backbone.View.extend({ attributes: { placeholder: l10n.searchPlaceholder, - type: 'search' + type: 'search', + 'aria-describedby': 'live-search-desc' }, events: { - 'input': 'search', - 'keyup': 'search', - 'change': 'search', - 'search': 'search', - 'blur': 'pushState' + 'input': 'search', + 'keyup': 'search', + 'blur': 'pushState' }, initialize: function( options ) { @@ -1112,19 +1128,21 @@ themes.view.Search = wp.Backbone.View.extend({ }, - // Runs a search on the theme collection. search: function( event ) { - var options = {}; - // Clear on escape. if ( event.type === 'keyup' && event.which === 27 ) { event.target.value = ''; } - // Lose input focus when pressing enter - if ( event.which === 13 ) { - this.$el.trigger( 'blur' ); - } + /** + * Since doSearch is debounced, it will only run when user input comes to a rest + */ + this.doSearch( event ); + }, + + // Runs a search on the theme collection. + doSearch: _.debounce( function( event ) { + var options = {}; this.collection.doSearch( event.target.value ); @@ -1141,7 +1159,7 @@ themes.view.Search = wp.Backbone.View.extend({ } else { themes.router.navigate( themes.router.baseUrl( '' ) ); } - }, + }, 500 ), pushState: function( event ) { var url = themes.router.baseUrl( '' ); @@ -1252,6 +1270,7 @@ themes.Run = { themes.view.InstallerSearch = themes.view.Search.extend({ events: { + 'input': 'search', 'keyup': 'search' }, @@ -1305,7 +1324,7 @@ themes.view.InstallerSearch = themes.view.Search.extend({ // Set route themes.router.navigate( themes.router.baseUrl( themes.router.searchPath + value ), { replace: true } ); - }, 300 ) + }, 500 ) }); themes.view.Installer = themes.view.Appearance.extend({ diff --git a/src/wp-admin/theme-install.php b/src/wp-admin/theme-install.php index 73e343a9a9..6b2a738ff0 100644 --- a/src/wp-admin/theme-install.php +++ b/src/wp-admin/theme-install.php @@ -44,11 +44,13 @@ wp_localize_script( 'theme', '_wpThemeSettings', array( ), 'l10n' => array( 'addNew' => __( 'Add New Theme' ), - 'search' => __( 'Search Themes' ), + 'search' => __( 'Search Themes' ), 'searchPlaceholder' => __( 'Search themes...' ), // placeholder (no ellipsis) 'upload' => __( 'Upload Theme' ), 'back' => __( 'Back' ), - 'error' => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ) + 'error' => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ), + 'themesFound' => __( 'Number of Themes found: %d' ), + 'noThemesFound' => __( 'No themes found. Try a different search.' ), ), 'installedThemes' => array_keys( $installed_themes ), ) ); @@ -70,7 +72,8 @@ if ( $tab ) { $help_overview = '

' . sprintf(__('You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the WordPress.org Theme Directory. 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/') . '

' . - '

' . __('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.') . '

' . + '

' . __( 'You can Search for themes by keyword, author, or tag, or can get more specific and search by criteria listed in the feature filter.' ) . ' ' . __( 'The search results will be updated as you type.' ) . '

' . + '

' . __( '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.' ) . '

' . '

' . __('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’s folder via FTP into your /wp-content/themes directory.') . '

'; get_current_screen()->add_help_tab( array( @@ -166,10 +169,10 @@ include(ABSPATH . 'wp-admin/admin-header.php'); -
-

-
+
+ +


diff --git a/src/wp-admin/themes.php b/src/wp-admin/themes.php index 4d68b58d13..79ac41eeca 100644 --- a/src/wp-admin/themes.php +++ b/src/wp-admin/themes.php @@ -47,7 +47,8 @@ if ( current_user_can( 'switch_themes' ) ) { '' . - '

' . __( 'The current theme is displayed highlighted as the first theme.' ) . '

'; + '

' . __( 'The current theme is displayed highlighted as the first theme.' ) . '

' . + '

' . __( 'The search for installed themes will search for terms in their name, description, author, or tag.' ) . ' ' . __( 'The search results will be updated as you type.' ) . '

'; get_current_screen()->add_help_tab( array( 'id' => 'overview', @@ -107,9 +108,11 @@ wp_localize_script( 'theme', '_wpThemeSettings', array( 'adminUrl' => parse_url( admin_url(), PHP_URL_PATH ), ), 'l10n' => array( - 'addNew' => __( 'Add New Theme' ), - 'search' => __( 'Search Installed Themes' ), + 'addNew' => __( 'Add New Theme' ), + 'search' => __( 'Search Installed Themes' ), '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() ) ?> -
+

-

+

+ true ) ) ) { diff --git a/src/wp-admin/update.php b/src/wp-admin/update.php index 6ded7a7d7a..4cfdeca6c6 100644 --- a/src/wp-admin/update.php +++ b/src/wp-admin/update.php @@ -201,7 +201,7 @@ if ( isset($_GET['action']) ) { if ( ! current_user_can('install_themes') ) 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 ); $api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth. diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index ecab928398..9875636b59 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -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( '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 ); did_action( 'init' ) && $scripts->localize( 'inline-edit-post', 'inlineEditL10n', array(