Index: wp-admin/includes/class-wp-theme-install-list-table.php
===================================================================
--- wp-admin/includes/class-wp-theme-install-list-table.php (revision 20032)
+++ wp-admin/includes/class-wp-theme-install-list-table.php (working copy)
@@ -9,6 +9,8 @@
*/
class WP_Theme_Install_List_Table extends WP_List_Table {
+ var $features = array();
+
function __construct() {
parent::__construct( array(
'ajax' => true,
@@ -16,16 +18,30 @@
}
function ajax_user_can() {
- return current_user_can('install_themes');
+ return current_user_can( 'install_themes' );
}
function prepare_items() {
include( ABSPATH . 'wp-admin/includes/theme-install.php' );
- global $tabs, $tab, $paged, $type, $term, $theme_field_defaults;
-
+ global $tabs, $tab, $paged, $type, $theme_field_defaults;
wp_reset_vars( array( 'tab' ) );
+ $search = array();
+ $sanitized_terms = '';
+ if ( ! empty( $_REQUEST['s'] ) ) {
+ $sanitized_terms = strtolower( stripslashes( $_REQUEST['s'] ) );
+ $search = array_merge( $search, array_filter( array_map( 'trim', explode( ',', $sanitized_terms ) ) ) );
+ $search = array_unique( $search );
+ }
+
+ if ( ! empty( $_REQUEST['features'] ) ) {
+ $this->features = $_REQUEST['features'];
+ $this->features = array_map( 'trim', $this->features );
+ $this->features = array_map( 'sanitize_title_with_dashes', $this->features );
+ $this->features = array_unique( $this->features );
+ }
+
$paged = $this->get_pagenum();
$per_page = 36;
@@ -55,29 +71,21 @@
switch ( $tab ) {
case 'search':
$type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : '';
- $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
-
switch ( $type ) {
case 'tag':
- $terms = explode( ',', $term );
- $terms = array_map( 'trim', $terms );
- $terms = array_map( 'sanitize_title_with_dashes', $terms );
- $args['tag'] = $terms;
+ $args['tag'] = array_map( 'sanitize_title_with_dashes', $search );
break;
case 'term':
- $args['search'] = $term;
+ $args['search'] = $sanitized_terms;
break;
case 'author':
- $args['author'] = $term;
+ $args['author'] = $sanitized_terms;
break;
}
- if ( !empty( $_REQUEST['features'] ) ) {
- $terms = $_REQUEST['features'];
- $terms = array_map( 'trim', $terms );
- $terms = array_map( 'sanitize_title_with_dashes', $terms );
- $args['tag'] = $terms;
- $_REQUEST['s'] = implode( ',', $terms );
+ if ( ! empty( $this->features ) ) {
+ $args['tag'] = $this->features;
+ $_REQUEST['s'] = implode( ',', $this->features );
$_REQUEST['type'] = 'tag';
}
@@ -95,7 +103,7 @@
$args = false;
}
- if ( !$args )
+ if ( ! $args )
return;
$api = themes_api( 'query_themes', $args );
@@ -170,4 +178,39 @@
?>
Install screen
+ * @uses $type Global; type of search.
+ * @uses $this->features Array of all feature search terms.
+ * @uses get_pagenum()
+ * @uses _pagination_args['total_pages']
+ */
+ function _js_vars() {
+ global $tab, $type;
+ $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
+
+ $total_pages = 0;
+ if ( ! empty( $this->_pagination_args['total_pages'] ) )
+ $total_pages = $this->_pagination_args['total_pages'];
+
+ $args = array(
+ 'search' => $search_string,
+ 'features' => $this->features,
+ 'paged' => $this->get_pagenum(),
+ 'total_pages' => $total_pages,
+
+ // Send items specific to theme-install
+ 'tab' => $tab,
+ 'type' => $type,
+ );
+
+ printf( "\n", json_encode( $args ) );
+ parent::_js_vars();
+ }
}
Index: wp-admin/includes/class-wp-themes-list-table.php
===================================================================
--- wp-admin/includes/class-wp-themes-list-table.php (revision 20032)
+++ wp-admin/includes/class-wp-themes-list-table.php (working copy)
@@ -11,7 +11,7 @@
var $search = array();
var $features = array();
-
+
function __construct() {
parent::__construct( array(
'ajax' => true,
@@ -20,7 +20,7 @@
function ajax_user_can() {
// Do not check edit_theme_options here. AJAX calls for available themes require switch_themes.
- return current_user_can('switch_themes');
+ return current_user_can( 'switch_themes' );
}
function prepare_items() {
@@ -32,7 +32,7 @@
$this->search = array_unique( $this->search );
}
- if ( !empty( $_REQUEST['features'] ) ) {
+ if ( ! empty( $_REQUEST['features'] ) ) {
$this->features = $_REQUEST['features'];
$this->features = array_map( 'trim', $this->features );
$this->features = array_map( 'sanitize_title_with_dashes', $this->features );
@@ -217,4 +217,32 @@
return true;
}
+
+ /**
+ * Send required variables to JavaScript land
+ *
+ * @since 3.4
+ * @access private
+ *
+ * @uses $this->features Array of all feature search terms.
+ * @uses get_pagenum()
+ * @uses _pagination_args['total_pages']
+ */
+ function _js_vars() {
+ $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
+
+ $total_pages = 1;
+ if ( ! empty( $this->_pagination_args['total_pages'] ) )
+ $total_pages = $this->_pagination_args['total_pages'];
+
+ $args = array(
+ 'search' => $search_string,
+ 'features' => $this->features,
+ 'paged' => $this->get_pagenum(),
+ 'total_pages' => $total_pages,
+ );
+
+ printf( "\n", json_encode( $args ) );
+ parent::_js_vars();
+ }
}
Index: wp-admin/js/theme.dev.js
===================================================================
--- wp-admin/js/theme.dev.js (revision 20032)
+++ wp-admin/js/theme.dev.js (working copy)
@@ -54,48 +54,51 @@
theme_viewer.init();
});
+
+/**
+ * Class that provides infinite scroll for Themes admin screens
+ *
+ * @since 3.4
+ *
+ * @uses ajaxurl
+ * @uses list_args
+ * @uses theme_list_args
+ * @uses $('#_ajax_fetch_list_nonce').val()
+* */
var ThemeScroller;
-
(function($){
ThemeScroller = {
- // Inputs
nonce: '',
- search: '',
- tab: '',
- type: '',
- nextPage: 2,
- features: {},
-
- // Preferences
+ nextPage: 2, // By default, assume we're on the first page.
+ querying: false,
scrollPollingDelay: 500,
failedRetryDelay: 4000,
outListBottomThreshold: 300,
- // Flags
- scrolling: false,
- querying: false,
-
+ /**
+ * Initializer
+ *
+ * @since 3.4
+ * @access private
+ */
init: function() {
var self = this,
- startPage,
- queryArray = {},
- queryString = window.location.search;
+ startPage;
// We're using infinite scrolling, so hide all pagination.
$('.pagination-links').hide();
- // Parse GET query string
- queryArray = this.parseQuery( queryString.substring( 1 ) );
+ // Get out early if we don't have the required arguments.
+ if ( ajaxurl === undefined ||
+ list_args === undefined ||
+ theme_list_args === undefined )
+ return;
// Handle inputs
this.nonce = $('#_ajax_fetch_list_nonce').val();
- this.search = queryArray['s'];
- this.features = queryArray['features'];
- this.tab = queryArray['tab'];
- this.type = queryArray['type'];
- startPage = parseInt( queryArray['paged'], 10 );
- if ( ! isNaN( startPage ) )
+ startPage = theme_list_args.paged;
+ if ( startPage !== undefined )
this.nextPage = ( startPage + 1 );
// Cache jQuery selectors
@@ -104,12 +107,25 @@
this.$window = $(window);
this.$document = $(document);
- if ( $('.tablenav-pages').length )
+ /**
+ * If there are more pages to query, then start polling to track
+ * when user hits the bottom of the current page
+ */
+ if ( theme_list_args.total_pages !== undefined &&
+ theme_list_args.total_pages >= this.nextPage )
this.pollInterval =
setInterval( function() {
return self.poll();
}, this.scrollPollingDelay );
},
+
+ /**
+ * Checks to see if user has scrolled to bottom of page.
+ * If so, requests another page of content from self.ajax().
+ *
+ * @since 3.4
+ * @access private
+ */
poll: function() {
var bottom = this.$document.scrollTop() + this.$window.innerHeight();
@@ -119,32 +135,49 @@
this.ajax();
},
+
+ /**
+ * Applies results passed from this.ajax() to $outList
+ *
+ * @since 3.4
+ * @access private
+ *
+ * @param results Array with results from this.ajax() query.
+ */
process: function( results ) {
if ( ( results === undefined ) ||
- ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
+ ( results.rows === undefined ) ||
+ ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
clearInterval( this.pollInterval );
return;
}
- var totalPages = parseInt( results.total_pages, 10 );
- if ( this.nextPage > totalPages )
+ if ( this.nextPage > theme_list_args.total_pages )
clearInterval( this.pollInterval );
- if ( this.nextPage <= ( totalPages + 1 ) )
+ if ( this.nextPage <= ( theme_list_args.total_pages + 1 ) )
this.$outList.append( results.rows );
},
+
+ /**
+ * Queries next page of themes
+ *
+ * @since 3.4
+ * @access private
+ */
ajax: function() {
var self = this;
+
this.querying = true;
var query = {
action: 'fetch-list',
- tab: this.tab,
paged: this.nextPage,
- s: this.search,
- type: this.type,
+ s: theme_list_args.search,
+ tab: theme_list_args.tab,
+ type: theme_list_args.type,
_ajax_fetch_list_nonce: this.nonce,
- 'features[]': this.features,
+ 'features[]': theme_list_args.features,
'list_args': list_args
};
@@ -159,40 +192,13 @@
.fail( function() {
self.$spinner.css( 'visibility', 'hidden' );
self.querying = false;
- setTimeout( function() { self.ajax(); }, self.failedRetryDelay )
+ setTimeout( function() { self.ajax(); }, self.failedRetryDelay );
});
- },
- parseQuery: function( query ) {
- var params = {};
- if ( ! query )
- return params;
-
- var pairs = query.split( /[;&]/ );
- for ( var i = 0; i < pairs.length; i++ ) {
- var keyVal = pairs[i].split( '=' );
-
- if ( ! keyVal || keyVal.length != 2 )
- continue;
-
- var key = unescape( keyVal[0] );
- var val = unescape( keyVal[1] );
- val = val.replace( /\+/g, ' ' );
- key = key.replace( /\[.*\]$/g, '' );
-
- if ( params[key] === undefined ) {
- params[key] = val;
- } else {
- var oldVal = params[key];
- if ( ! $.isArray( params[key] ) )
- params[key] = new Array( oldVal, val );
- else
- params[key].push( val );
- }
- }
- return params;
}
}
- $(document).ready( function( $ ) { ThemeScroller.init(); });
+ $(document).ready( function($) {
+ ThemeScroller.init();
+ });
})(jQuery);