Plugins: Improve Ajax search of new plugins.

Fixes a few accessibility issues, restores the "Search Results" tab and the search type selector, and improves compatibility with older browsers.

Props rahulsprajapati, swissspidy, adamsilverstein, ocean90
See #37233.

git-svn-id: https://develop.svn.wordpress.org/trunk@38119 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Dominik Schilling 2016-07-20 16:31:50 +00:00
parent 2586eeeeca
commit 44676ab38f
7 changed files with 84 additions and 46 deletions

View File

@ -3881,6 +3881,7 @@ function wp_ajax_search_install_plugins() {
ob_start();
$wp_list_table->display();
$status['count'] = (int) $wp_list_table->get_pagination_arg( 'total_items' );
$status['items'] = ob_get_clean();
wp_send_json_success( $status );

View File

@ -285,7 +285,7 @@ class WP_Plugin_Install_List_Table extends WP_List_Table {
?>
</ul>
<?php install_search_form( isset( $views['plugin-install-search'] ) ); ?>
<?php install_search_form(); ?>
</div>
<?php
}

View File

@ -214,6 +214,7 @@ function install_dashboard() {
<?php display_plugins_table(); ?>
<div class="plugins-popular-tags-wrapper">
<h2><?php _e( 'Popular tags' ) ?></h2>
<p><?php _e( 'You may also browse based on the most popular tags in the Plugin Directory:' ) ?></p>
<?php
@ -239,40 +240,32 @@ function install_dashboard() {
}
echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%s plugin'), 'multiple_text' => __('%s plugins') ) );
}
echo '</p><br class="clear" />';
echo '</p><br class="clear" /></div>';
}
/**
* Display search form for searching plugins.
* Displays a search form for searching plugins.
*
* @since 2.7.0
* @since 4.6.0 The `$type_selector` parameter was deprecated.
*
* @param bool $type_selector
* @param bool $deprecated Not used.
*/
function install_search_form( $type_selector = true ) {
$type = isset($_REQUEST['type']) ? wp_unslash( $_REQUEST['type'] ) : 'term';
$term = isset($_REQUEST['s']) ? wp_unslash( $_REQUEST['s'] ) : '';
$input_attrs = '';
$button_type = 'button screen-reader-text';
// assume no $type_selector means it's a simplified search form
if ( ! $type_selector ) {
$input_attrs = 'class="wp-filter-search" placeholder="' . esc_attr__( 'Search Plugins' ) . '" ';
}
function install_search_form( $deprecated = true ) {
$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
$term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
?><form class="search-form search-plugins" method="get">
<input type="hidden" name="tab" value="search" />
<?php if ( $type_selector ) : ?>
<label class="screen-reader-text" for="typeselector"><?php _e( 'Search plugins by:' ); ?></label>
<select name="type" id="typeselector">
<option value="term"<?php selected('term', $type) ?>><?php _e('Keyword'); ?></option>
<option value="author"<?php selected('author', $type) ?>><?php _e('Author'); ?></option>
<option value="tag"<?php selected('tag', $type) ?>><?php _ex('Tag', 'Plugin Installer'); ?></option>
<option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
<option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
<option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option>
</select>
<?php endif; ?>
<label><span class="screen-reader-text"><?php _e('Search Plugins'); ?></span>
<input type="search" name="s" value="<?php echo esc_attr($term) ?>" <?php echo $input_attrs; ?>/>
<label><span class="screen-reader-text"><?php _e( 'Search Plugins' ); ?></span>
<input type="search" name="s" value="<?php echo esc_attr( $term ) ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search Plugins' ); ?>" />
</label>
<?php submit_button( __( 'Search Plugins' ), $button_type, false, false, array( 'id' => 'search-submit' ) ); ?>
<?php submit_button( __( 'Search Plugins' ), 'button hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?>
</form><?php
}

View File

@ -1598,10 +1598,11 @@
};
$( function() {
var $pluginFilter = $( '#plugin-filter' ),
$bulkActionForm = $( '#bulk-action-form' ),
$filesystemModal = $( '#request-filesystem-credentials-dialog' ),
$pluginSearch = $( '.plugins-php .wp-filter-search' );
var $pluginFilter = $( '#plugin-filter' ),
$bulkActionForm = $( '#bulk-action-form' ),
$filesystemModal = $( '#request-filesystem-credentials-dialog' ),
$pluginSearch = $( '.plugins-php .wp-filter-search' ),
$pluginInstallSearch = $( '.plugin-install-php .wp-filter-search' );
/*
* Whether a user needs to submit filesystem credentials.
@ -2021,30 +2022,59 @@
wp.updates.queueChecker();
} );
if ( $pluginInstallSearch.length ) {
$pluginInstallSearch.attr( 'aria-describedby', 'live-search-desc' );
}
/**
* Handles changes to the plugin search box on the new-plugin page,
* searching the repository dynamically.
*
* @since 4.6.0
*/
$( '.plugin-install-php .wp-filter-search' ).on( 'keyup search', _.debounce( function() {
var $form = $( '#plugin-filter' ).empty(),
data = _.extend( {
_ajax_nonce: wp.updates.ajaxNonce,
s: $( this ).val(),
tab: 'search',
type: $( '#typeselector' ).val(),
pagenow: pagenow
}, { type: 'term' } );
$pluginInstallSearch.on( 'keyup input', _.debounce( function( event, eventtype ) {
var $searchTab = $( '.plugin-install-search' ), data, searchLocation;
if ( wp.updates.searchTerm === data.s ) {
data = {
_ajax_nonce: wp.updates.ajaxNonce,
s: event.target.value,
tab: 'search',
type: $( '#typeselector' ).val(),
pagenow: pagenow
};
searchLocation = location.href.split( '?' )[ 0 ] + '?' + $.param( _.omit( data, [ '_ajax_nonce', 'pagenow' ] ) );
// Clear on escape.
if ( 'keyup' === event.type && 27 === event.which ) {
event.target.value = '';
}
if ( wp.updates.searchTerm === data.s && 'typechange' !== eventtype ) {
return;
} else {
$pluginFilter.empty();
wp.updates.searchTerm = data.s;
}
if ( history.pushState ) {
history.pushState( null, '', location.href.split( '?' )[ 0 ] + '?' + $.param( _.omit( data, [ '_ajax_nonce', 'pagenow' ] ) ) );
if ( window.history && window.history.pushState ) {
window.history.pushState( null, '', searchLocation );
}
if ( ! $searchTab.length ) {
$searchTab = $( '<li class="plugin-install-search" />' )
.append( $( '<a />', {
'class': 'current',
'href': searchLocation,
'text': wp.updates.l10n.searchResultsLabel
} ) );
$( '.wp-filter .filter-links .current' )
.removeClass( 'current' )
.parents( '.filter-links' )
.prepend( $searchTab );
$pluginFilter.prev( 'p' ).remove();
$( '.plugins-popular-tags-wrapper' ).remove();
}
if ( 'undefined' !== typeof wp.updates.searchRequest ) {
@ -2054,12 +2084,18 @@
wp.updates.searchRequest = wp.ajax.post( 'search-install-plugins', data ).done( function( response ) {
$( 'body' ).removeClass( 'loading-content' );
$form.append( response.items );
$pluginFilter.append( response.items );
delete wp.updates.searchRequest;
if ( 0 === response.count ) {
wp.a11y.speak( wp.updates.l10n.noPluginsFound );
} else {
wp.a11y.speak( wp.updates.l10n.pluginsFound.replace( '%d', response.count ) );
}
} );
}, 500 ) );
if ( $pluginSearch.length > 0 ) {
if ( $pluginSearch.length ) {
$pluginSearch.attr( 'aria-describedby', 'live-search-desc' );
}
@ -2087,8 +2123,8 @@
wp.updates.searchTerm = data.s;
}
if ( history.pushState ) {
history.pushState( null, '', location.href.split( '?' )[ 0 ] + '?s=' + data.s );
if ( window.history && window.history.pushState ) {
window.history.pushState( null, '', location.href.split( '?' )[ 0 ] + '?s=' + data.s );
}
if ( 'undefined' !== typeof wp.updates.searchRequest ) {
@ -2132,7 +2168,7 @@
$document.on( 'submit', '.search-plugins', function( event ) {
event.preventDefault();
$( 'input.wp-filter-search' ).trigger( 'search' );
$( 'input.wp-filter-search' ).trigger( 'input' );
} );
/**
@ -2141,7 +2177,11 @@
* @since 4.6.0
*/
$( '#typeselector' ).on( 'change', function() {
$( 'input[name="s"]' ).trigger( 'search' );
var $search = $( 'input[name="s"]' );
if ( $search.val().length ) {
$search.trigger( 'input', 'typechange' );
}
} );
/**

View File

@ -70,7 +70,9 @@ get_current_screen()->add_help_tab( array(
'id' => 'overview',
'title' => __('Overview'),
'content' =>
'<p>' . sprintf(__('Plugins hook into WordPress to extend its functionality with custom features. Plugins are developed independently from the core WordPress application by thousands of developers all over the world. All plugins in the official <a href="%s" target="_blank">WordPress Plugin Directory</a> are compatible with the license WordPress uses. You can find new plugins to install by searching or browsing the Directory right here in your own Plugins section.'), 'https://wordpress.org/plugins/') . '</p>'
'<p>' . sprintf( __('Plugins hook into WordPress to extend its functionality with custom features. Plugins are developed independently from the core WordPress application by thousands of developers all over the world. All plugins in the official <a href="%s" target="_blank">WordPress Plugin Directory</a> are compatible with the license WordPress uses.' ), 'https://wordpress.org/plugins/' ) . '</p>' .
'<p>' . __( 'You can find new plugins to install by searching or browsing the directory right here in your own Plugins section.' ) . ' <span id="live-search-desc" class="hide-if-no-js">' . __( 'The search results will be updated as you type.' ) . '</span></p>'
) );
get_current_screen()->add_help_tab( array(
'id' => 'adding-plugins',

View File

@ -609,6 +609,7 @@ function wp_default_scripts( &$scripts ) {
'l10n' => array(
/* translators: %s: Search string */
'searchResults' => __( 'Search results for &#8220;%s&#8221;' ),
'searchResultsLabel' => __( 'Search Results' ),
'noPlugins' => __( 'You do not appear to have any plugins available at this time.' ),
'noItemsSelected' => __( 'Please select at least one item to perform this action on.' ),
'updating' => __( 'Updating...' ), // No ellipsis.

View File

@ -2,6 +2,7 @@ window._wpUpdatesSettings = {
'ajax_nonce': '719b10f05d',
'l10n': {
'searchResults': 'Search results for &#8220;%s&#8221;',
'searchResultsLabel': 'Search Results',
'noPlugins': 'You do not appear to have any plugins available at this time.',
'noItemsSelected': 'Please select at least one item to perform this action on.',
'updating': 'Updating...',