WordPress.org

Make WordPress Core

Changeset 20094


Ignore:
Timestamp:
03/02/2012 10:09:26 PM (9 years ago)
Author:
nacin
Message:

Output themes and theme-install infinite scrolling args in JS, rather than parsing query strings. props DH-Shredder, helenyhou. Make WP_Theme_Install_List_Table extend WP_Themes_List_Table. Doesn't help much yet, but we should be able to dry things up further. see #19815.

Location:
trunk/wp-admin
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/class-wp-list-table.php

    r19819 r20094  
    485485            return;
    486486
    487         extract( $this->_pagination_args );
     487        extract( $this->_pagination_args, EXTR_SKIP );
    488488
    489489        $output = '<span class="displaying-num">' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';
     
    544544        );
    545545
    546         $output .= "\n<span class='pagination-links'>" . join( "\n", $page_links ) . '</span>';
     546        $pagination_links_class = 'pagination-links';
     547        if ( ! empty( $infinite_scroll ) )
     548            $pagination_links_class = ' hide-if-js';
     549        $output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';
    547550
    548551        if ( $total_pages )
     
    873876
    874877        extract( $this->_args );
    875         extract( $this->_pagination_args );
     878        extract( $this->_pagination_args, EXTR_SKIP );
    876879
    877880        ob_start();
  • trunk/wp-admin/includes/class-wp-theme-install-list-table.php

    r19887 r20094  
    88 * @access private
    99 */
    10 class WP_Theme_Install_List_Table extends WP_List_Table {
     10class WP_Theme_Install_List_Table extends WP_Themes_List_Table {
    1111
    12     function __construct() {
    13         parent::__construct( array(
    14             'ajax' => true,
    15         ) );
    16     }
     12    var $features = array();
    1713
    1814    function ajax_user_can() {
    19         return current_user_can('install_themes');
     15        return current_user_can( 'install_themes' );
    2016    }
    2117
     
    2319        include( ABSPATH . 'wp-admin/includes/theme-install.php' );
    2420
    25         global $tabs, $tab, $paged, $type, $term, $theme_field_defaults;
     21        global $tabs, $tab, $paged, $type, $theme_field_defaults;
     22        wp_reset_vars( array( 'tab' ) );
    2623
    27         wp_reset_vars( array( 'tab' ) );
     24        $search_terms = array();
     25        $search_string = '';
     26        if ( ! empty( $_REQUEST['s'] ) ){
     27            $search_string = strtolower( stripslashes( $_REQUEST['s'] ) );
     28            $search_terms = array_unique( array_filter( array_map( 'trim', explode( ',', $search_string ) ) ) );
     29        }
     30
     31        if ( ! empty( $_REQUEST['features'] ) )
     32            $this->features = $_REQUEST['features'];
    2833
    2934        $paged = $this->get_pagenum();
     
    5661            case 'search':
    5762                $type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : '';
    58                 $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
    59 
    6063                switch ( $type ) {
    6164                    case 'tag':
    62                         $terms = explode( ',', $term );
    63                         $terms = array_map( 'trim', $terms );
    64                         $terms = array_map( 'sanitize_title_with_dashes', $terms );
    65                         $args['tag'] = $terms;
     65                        $args['tag'] = array_map( 'sanitize_title_with_dashes', $search_terms );
    6666                        break;
    6767                    case 'term':
    68                         $args['search'] = $term;
     68                        $args['search'] = $search_string;
    6969                        break;
    7070                    case 'author':
    71                         $args['author'] = $term;
     71                        $args['author'] = $search_string;
    7272                        break;
    7373                }
    7474
    75                 if ( !empty( $_REQUEST['features'] ) ) {
    76                     $terms = $_REQUEST['features'];
    77                     $terms = array_map( 'trim', $terms );
    78                     $terms = array_map( 'sanitize_title_with_dashes', $terms );
    79                     $args['tag'] = $terms;
    80                     $_REQUEST['s'] = implode( ',', $terms );
     75                if ( ! empty( $this->features ) ) {
     76                    $args['tag'] = $this->features;
     77                    $_REQUEST['s'] = implode( ',', $this->features );
    8178                    $_REQUEST['type'] = 'tag';
    8279                }
     
    9693        }
    9794
    98         if ( !$args )
     95        if ( ! $args )
    9996            return;
    10097
     
    109106            'total_items' => $api->info['results'],
    110107            'per_page' => $per_page,
     108            'infinite_scroll' => true,
    111109        ) );
    112110    }
     
    129127    }
    130128
    131     function get_columns() {
    132         return array();
    133     }
    134 
    135129    function display() {
    136 
    137130        wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' );
    138131?>
     
    150143        </div>
    151144
    152         <div class="tablenav bottom themes">
    153             <?php $this->pagination( 'bottom' ); ?>
    154             <img src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" class="ajax-loading list-ajax-loading" alt="" />
    155             <br class="clear" />
    156         </div>
    157 <?php
     145        <?php
     146        parent::tablenav( 'bottom' );
    158147    }
    159148
     
    171160        <?php } // end foreach $theme_names
    172161    }
     162
     163    /**
     164     * Send required variables to JavaScript land
     165     *
     166     * @since 3.4
     167     * @access private
     168     *
     169     * @uses $tab Global; current tab within Themes->Install screen
     170     * @uses $type Global; type of search.
     171     */
     172    function _js_vars() {
     173        global $tab, $type;
     174        parent::_js_vars( compact( $tab, $type ) );
     175    }
    173176}
  • trunk/wp-admin/includes/class-wp-themes-list-table.php

    r20068 r20094  
    2121    function ajax_user_can() {
    2222        // Do not check edit_theme_options here. AJAX calls for available themes require switch_themes.
    23         return current_user_can('switch_themes');
     23        return current_user_can( 'switch_themes' );
    2424    }
    2525
     
    5353            'total_items' => count( $themes ),
    5454            'per_page' => $per_page,
     55            'infinite_scroll' => true,
    5556        ) );
    5657    }
     
    203204        return true;
    204205    }
     206
     207    /**
     208     * Send required variables to JavaScript land
     209     *
     210     * @since 3.4
     211     * @access private
     212     *
     213     * @uses $this->features Array of all feature search terms.
     214     * @uses get_pagenum()
     215     * @uses _pagination_args['total_pages']
     216     */
     217     function _js_vars( $extra_args = array() ) {
     218        $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
     219
     220        $total_pages = 1;
     221        if ( ! empty( $this->_pagination_args['total_pages'] ) )
     222            $total_pages = $this->_pagination_args['total_pages'];
     223
     224        $args = array(
     225            'search' => $search_string,
     226            'features' => $this->features,
     227            'paged' => $this->get_pagenum(),
     228            'total_pages' => $total_pages,
     229        );
     230
     231        if ( is_array( $extra_args ) )
     232        $args = array_merge( $args, $extra_args );
     233
     234        printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", json_encode( $args ) );
     235        parent::_js_vars();
     236    }
    205237}
  • trunk/wp-admin/includes/list-table.php

    r19712 r20094  
    2929        'WP_Plugin_Install_List_Table' => 'plugin-install',
    3030        'WP_Themes_List_Table' => 'themes',
    31         'WP_Theme_Install_List_Table' => 'theme-install',
     31        'WP_Theme_Install_List_Table' => array( 'themes', 'theme-install' ),
    3232        'WP_Plugins_List_Table' => 'plugins',
    3333        // Network Admin
     
    3838
    3939    if ( isset( $core_classes[ $class ] ) ) {
    40         require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $core_classes[ $class ] . '-list-table.php' );
     40        foreach ( (array) $core_classes[ $class ] as $required )
     41            require_once( ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php' );
    4142        return new $class;
    4243    }
  • trunk/wp-admin/js/theme.dev.js

    r20000 r20094  
    5555});
    5656
     57
     58/**
     59 * Class that provides infinite scroll for Themes admin screens
     60 *
     61 * @since 3.4
     62 *
     63 * @uses ajaxurl
     64 * @uses list_args
     65 * @uses theme_list_args
     66 * @uses $('#_ajax_fetch_list_nonce').val()
     67* */
    5768var ThemeScroller;
    58 
    5969(function($){
    6070    ThemeScroller = {
    61         // Inputs
    6271        nonce: '',
    63         search: '',
    64         tab: '',
    65         type: '',
    66         nextPage: 2,
    67         features: {},
    68 
    69         // Preferences
     72        nextPage: 2, // By default, assume we're on the first page.
     73        querying: false,
    7074        scrollPollingDelay: 500,
    7175        failedRetryDelay: 4000,
    7276        outListBottomThreshold: 300,
    7377
    74         // Flags
    75         scrolling: false,
    76         querying: false,
    77 
     78        /**
     79         * Initializer
     80         *
     81         * @since 3.4
     82         * @access private
     83         */
    7884        init: function() {
    7985            var self = this,
    80                 startPage,
    81                 queryArray = {},
    82                 queryString = window.location.search;
    83 
    84             // We're using infinite scrolling, so hide all pagination.
    85             $('.pagination-links').hide();
    86 
    87             // Parse GET query string
    88             queryArray = this.parseQuery( queryString.substring( 1 ) );
     86                startPage;
     87
     88            // Get out early if we don't have the required arguments.
     89            if ( typeof ajaxurl === 'undefined' ||
     90                 typeof list_args === 'undefined' ||
     91                 typeof theme_list_args === 'undefined' ) {
     92                    $('.pagination-links').show();
     93                    return;
     94            }
    8995
    9096            // Handle inputs
    9197            this.nonce = $('#_ajax_fetch_list_nonce').val();
    92             this.search = queryArray['s'];
    93             this.features = queryArray['features'];
    94             this.tab = queryArray['tab'];
    95             this.type = queryArray['type'];
    96 
    97             startPage = parseInt( queryArray['paged'], 10 );
    98             if ( ! isNaN( startPage ) )
     98
     99            startPage = theme_list_args.paged;
     100            if ( startPage !== undefined )
    99101                this.nextPage = ( startPage + 1 );
    100102
     
    105107            this.$document = $(document);
    106108
    107             if ( $('.tablenav-pages').length )
     109            /**
     110             * If there are more pages to query, then start polling to track
     111             * when user hits the bottom of the current page
     112             */
     113            if ( theme_list_args.total_pages !== undefined &&
     114                 theme_list_args.total_pages >= this.nextPage )
    108115                this.pollInterval =
    109116                    setInterval( function() {
     
    111118                    }, this.scrollPollingDelay );
    112119        },
     120
     121        /**
     122         * Checks to see if user has scrolled to bottom of page.
     123         * If so, requests another page of content from self.ajax().
     124         *
     125         * @since 3.4
     126         * @access private
     127         */
    113128        poll: function() {
    114129            var bottom = this.$document.scrollTop() + this.$window.innerHeight();
     
    120135            this.ajax();
    121136        },
     137
     138        /**
     139         * Applies results passed from this.ajax() to $outList
     140         *
     141         * @since 3.4
     142         * @access private
     143         *
     144         * @param results Array with results from this.ajax() query.
     145         */
    122146        process: function( results ) {
    123147            if ( ( results === undefined ) ||
    124                 ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
     148                 ( results.rows === undefined ) ||
     149                 ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
    125150                clearInterval( this.pollInterval );
    126151                return;
    127152            }
    128153
    129             var totalPages = parseInt( results.total_pages, 10 );
    130             if ( this.nextPage > totalPages )
     154            if ( this.nextPage > theme_list_args.total_pages )
    131155                clearInterval( this.pollInterval );
    132156
    133             if ( this.nextPage <= ( totalPages + 1 ) )
     157            if ( this.nextPage <= ( theme_list_args.total_pages + 1 ) )
    134158                this.$outList.append( results.rows );
    135159        },
     160
     161        /**
     162         * Queries next page of themes
     163         *
     164         * @since 3.4
     165         * @access private
     166         */
    136167        ajax: function() {
    137168            var self = this;
     169
    138170            this.querying = true;
    139171
    140172            var query = {
    141173                action: 'fetch-list',
    142                 tab: this.tab,
    143174                paged: this.nextPage,
    144                 s: this.search,
    145                 type: this.type,
     175                s: theme_list_args.search,
     176                tab: theme_list_args.tab,
     177                type: theme_list_args.type,
    146178                _ajax_fetch_list_nonce: this.nonce,
    147                 'features[]': this.features,
     179                'features[]': theme_list_args.features,
    148180                'list_args': list_args
    149181            };
     
    160192                    self.$spinner.css( 'visibility', 'hidden' );
    161193                    self.querying = false;
    162                     setTimeout( function() { self.ajax(); }, self.failedRetryDelay )
     194                    setTimeout( function() { self.ajax(); }, self.failedRetryDelay );
    163195                });
    164         },
    165         parseQuery: function( query ) {
    166             var params = {};
    167             if ( ! query )
    168                 return params;
    169 
    170             var pairs = query.split( /[;&]/ );
    171             for ( var i = 0; i < pairs.length; i++ ) {
    172                 var keyVal = pairs[i].split( '=' );
    173 
    174                 if ( ! keyVal || keyVal.length != 2 )
    175                     continue;
    176 
    177                 var key = unescape( keyVal[0] );
    178                 var val = unescape( keyVal[1] );
    179                 val = val.replace( /\+/g, ' ' );
    180                 key = key.replace( /\[.*\]$/g, '' );
    181 
    182                 if ( params[key] === undefined ) {
    183                     params[key] = val;
    184                 } else {
    185                     var oldVal = params[key];
    186                     if ( ! $.isArray( params[key] ) )
    187                         params[key] = new Array( oldVal, val );
    188                     else
    189                         params[key].push( val );
    190                 }
    191             }
    192             return params;
    193196        }
    194197    }
    195198
    196     $(document).ready( function( $ ) { ThemeScroller.init(); });
     199    $(document).ready( function($) {
     200        ThemeScroller.init();
     201    });
    197202
    198203})(jQuery);
Note: See TracChangeset for help on using the changeset viewer.