Make WordPress Core

Ticket #19815: 19815.10.diff

File 19815.10.diff, 7.9 KB (added by kirasong, 13 years ago)

Combined garyc40's patch, and koopersmith's suggestions from IRC

  • wp-admin/js/theme.dev.js

     
    4545                        init: init
    4646                };
    4747
    48         return api;
     48        return api;
    4949        }
    5050})(jQuery);
    5151
     
    5454        theme_viewer.init();
    5555});
    5656
    57 var wpThemes;
     57var ThemeScroller;
    5858
    5959(function($){
    60         var inputs = {}, Query;
     60        ThemeScroller = {
     61                // Inputs
     62                nonce: '',
     63                search: '',
     64                tab: '',
     65                type: '',
     66                nextPage: 2,
     67                features: {},
    6168
    62         wpThemes = {
    63                 timeToTriggerQuery: 150,
    64                 minQueryAJAXDuration: 200,
    65                 outListBottomThreshold: 200,
     69                // Preferences
     70                scrollPollingDelay: 500,
     71                failedRetryDelay: 4000,
     72                outListBottomThreshold: 300,
     73
     74                // Flags
    6675                noMoreResults: false,
    67                
    68                 init : function() {
    69                         $('.pagination-links').hide();
     76                scrolling: false,
     77                querying: false,
    7078
    71                         inputs.nonce = $('#_ajax_fetch_list_nonce').val();
    72        
    73                         // Parse Query
    74                         inputs.queryString = window.location.search;                   
    75                         inputs.queryArray = wpThemes.parseQuery( inputs.queryString.substring( 1 ) );
     79                init: function() {
     80                        var self = this,
     81                                startPage,
     82                                queryArray = {},
     83                                queryString = window.location.search;
    7684
    77                         // Handle Inputs from Query
    78                         inputs.search = inputs.queryArray['s'];
    79                         inputs.features = inputs.queryArray['features'];
    80                         inputs.startPage = parseInt( inputs.queryArray['paged'] );     
    81                         inputs.tab = inputs.queryArray['tab'];
    82                         inputs.type = inputs.queryArray['type'];
     85                        // We're using infinite scrolling, so hide all pagination.
     86                        $('.pagination-links').hide();
    8387
    84                         if ( isNaN( inputs.startPage ) )
    85                                 inputs.startPage = 2;
    86                         else
    87                                 inputs.startPage++;
     88                        // Parse GET query string
     89                        queryArray = this.parseQuery( queryString.substring( 1 ) );
    8890
    89                         // Cache jQuery objects
    90                         inputs.outList = $('#availablethemes');
    91                         inputs.waiting = $('div.tablenav.bottom').children( 'img.ajax-loading' );
    92                         inputs.window = $(window);
     91                        // Handle inputs
     92                        this.nonce = $('#_ajax_fetch_list_nonce').val();
     93                        this.search = queryArray['s'];
     94                        this.features = queryArray['features'];
     95                        this.tab = queryArray['tab'];
     96                        this.type = queryArray['type'];
    9397
    94                         // Generate Query
    95                         wpThemes.query = new Query();
     98                        startPage = parseInt( queryArray['paged'], 10 );
     99                        if ( ! isNaN( startPage ) )
     100                                this.nextPage++;
    96101
    97                         // Start Polling
    98                         inputs.window.scroll( function(){ wpThemes.maybeLoad(); } );
     102                        // Cache jQuery selectors
     103                        this.$outList = $('#availablethemes');
     104                        this.$spinner = $('div.tablenav.bottom').children( 'img.ajax-loading' );
     105                        this.$window = $(window);
     106                        this.$document = $(document);
     107
     108                        setInterval( function() {
     109                                return self.poll();
     110                        }, this.scrollPollingDelay );
    99111                },
    100                 delayedCallback : function( func, delay ) {
    101                         var timeoutTriggered, funcTriggered, funcArgs, funcContext;
     112                poll: function() {
     113                        var bottom = this.$document.scrollTop() + this.$window.innerHeight();
    102114
    103                         if ( ! delay )
    104                                 return func;
     115                        if ( this.noMoreResults || this.querying ||
     116                                ( bottom < this.$outList.height() - this.outListBottomThreshold ) )
     117                                return;
    105118
    106                         setTimeout( function() {
    107                                 if ( funcTriggered )
    108                                         return func.apply( funcContext, funcArgs );
    109                                 // Otherwise, wait.
    110                                 timeoutTriggered = true;
    111                         }, delay);
    112 
    113                         return function() {
    114                                 if ( timeoutTriggered )
    115                                         return func.apply( this, arguments );
    116                                 // Otherwise, wait.
    117                                 funcArgs = arguments;
    118                                 funcContext = this;
    119                                 funcTriggered = true;
    120                         };
     119                        this.maybeLoad();
    121120                },
    122                 ajax: function( callback ) {
    123                         var self = this,
    124                                 response = wpThemes.delayedCallback( function( results, params ) {
    125                                         self.process( results, params );
    126                                         if ( callback )
    127                                                 callback( results, params );
    128                                 }, wpThemes.minQueryAJAXDuration );
    129 
    130                         this.query.ajax( response );
    131                 },
    132                 process: function( results, params ) {
    133                         // If no Results, for now, mark as no Matches, and bail.
    134                         // Alternately: inputs.outList.append(wpThemesL10n.noMatchesFound);
     121                process: function( results ) {
    135122                        if ( ( results === undefined ) ||
    136                                  ( results.rows.indexOf( "no-items" ) != -1 ) ) {
     123                                ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
    137124                                this.noMoreResults = true;
    138125                        } else {
    139                                 inputs.outList.append( results.rows );
     126                                this.$outList.append( results.rows );
    140127                        }
    141128                },
    142129                maybeLoad: function() {
    143                         var self = this,
    144                                 el = $(document),
    145                                 bottom = el.scrollTop() + inputs.window.innerHeight();
    146                                
    147                         if ( this.noMoreResults ||
    148                                  !this.query.ready() ||
    149                                  ( bottom < inputs.outList.height() - wpThemes.outListBottomThreshold ) )
    150                                 return;
     130                        var self = this;
     131                        this.querying = true;
    151132
    152                         setTimeout( function() {
    153                                 var newTop = el.scrollTop(),
    154                                         newBottom = newTop + inputs.window.innerHeight();
     133                        var query = {
     134                                action: 'fetch-list',
     135                                tab: this.tab,
     136                                paged: this.nextPage,
     137                                s: this.search,
     138                                type: this.type,
     139                                _ajax_fetch_list_nonce: this.nonce,
     140                                'features[]': this.features,
     141                                'list_args': list_args
     142                        };
    155143
    156                                 if ( !self.query.ready() ||
    157                                          ( newBottom < inputs.outList.height() - wpThemes.outListBottomThreshold ) )
    158                                         return;
    159 
    160                                 inputs.waiting.css( 'visibility', 'visible' ); // Show Spinner
    161                                 self.ajax( function() { inputs.waiting.css( 'visibility', 'hidden' ) } ); // Hide Spinner
    162                                
    163                         }, wpThemes.timeToTriggerQuery );
     144                        this.$spinner.css( 'visibility', 'visible' );
     145                        $.getJSON( ajaxurl, query )
     146                                .done( function( response ) {
     147                                        self.nextPage++;
     148                                        self.process( response );
     149                                        self.$spinner.css( 'visibility', 'hidden' );
     150                                        self.querying = false;
     151                                })
     152                                .fail( function() {
     153                                        self.$spinner.css( 'visibility', 'hidden' );
     154                                        self.querying = false;
     155                                        setTimeout( function() { self.maybeLoad(); }, self.failedRetryDelay)
     156                                });
    164157                },
    165158                parseQuery: function( query ) {
    166                         var Params = {};
    167                         if ( ! query ) {return Params;}// return empty object
    168                         var Pairs = query.split(/[;&]/);
    169                         for ( var i = 0; i < Pairs.length; i++ ) {
    170                                 var KeyVal = Pairs[i].split('=');
    171                                 if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
    172                                 var key = unescape( KeyVal[0] );
    173                                 var val = unescape( KeyVal[1] );
    174                                 val = val.replace(/\+/g, ' ');
    175                                 key = key.replace(/\[.*\]$/g, '');
    176        
    177                                 if ( Params[key] === undefined ) {
    178                                         Params[key] = val;
     159                        var params = {};
     160                        if ( ! query )
     161                                return params;
     162
     163                        var pairs = query.split( /[;&]/ );
     164                        for ( var i = 0; i < pairs.length; i++ ) {
     165                                var keyVal = pairs[i].split( '=' );
     166
     167                                if ( ! keyVal || keyVal.length != 2 )
     168                                        continue;
     169
     170                                var key = unescape( keyVal[0] );
     171                                var val = unescape( keyVal[1] );
     172                                val = val.replace( /\+/g, ' ' );
     173                                key = key.replace( /\[.*\]$/g, '' );
     174
     175                                if ( params[key] === undefined ) {
     176                                        params[key] = val;
    179177                                } else {
    180                                         var oldVal = Params[key];
    181                                         if ( ! jQuery.isArray( Params[key] ) )
    182                                                 Params[key] = new Array( oldVal, val );
     178                                        var oldVal = params[key];
     179                                        if ( ! $.isArray( params[key] ) )
     180                                                params[key] = new Array( oldVal, val );
    183181                                        else
    184                                                 Params[key].push( val );
     182                                                params[key].push( val );
    185183                                }
    186184                        }
    187                         return Params;
     185                        return params;
    188186                }
    189187        }
    190188
    191         Query = function() {
    192                 this.failedRequest = false;
    193                 this.querying = false;
    194                 this.page = inputs.startPage;
    195         }
    196        
    197         $.extend( Query.prototype, {
    198                 ready: function() {
    199                         return !( this.querying || this.failedRequest );
    200                 },
    201                 ajax: function( callback ) {
    202                         var self = this,
    203                         query = {
    204                                 action: 'fetch-list',
    205                                 tab: inputs.tab,
    206                                 paged: this.page,
    207                                 s: inputs.search,
    208                                 type: inputs.type,
    209                                 _ajax_fetch_list_nonce: inputs.nonce,
    210                                 'features[]': inputs.features,
    211                                 'list_args': list_args
    212                         };
     189        $(document).ready( function( $ ) { ThemeScroller.init(); });
    213190
    214                         this.querying = true;
    215                         $.get( ajaxurl, query, function(r) {
    216                                 self.page++;
    217                                 self.querying = false;
    218                                 self.failedRequest = !r;
    219                                 callback( r, query );
    220                         }, "json" );
    221                 }
    222         });
    223 
    224         $(document).ready( wpThemes.init );
    225 
    226191})(jQuery);