WordPress.org

Make WordPress Core

Ticket #19815: 19815.8.diff

File 19815.8.diff, 7.3 KB (added by mikeschroder, 9 years ago)

Renamed class to ThemeScroller, caching more JQuery selectors, throttling scroll, using Deferred for AJAX calls, and general cleanup. Does not include 19815.7.diff [edit - get rid of stray propset]

  • 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,
     69                // Preferences
     70                scrollThrottleDelay: 250,
     71                failedRetryDelay: 4000,
    6572                outListBottomThreshold: 200,
     73
     74                // Flags
    6675                noMoreResults: false,
    67                
     76                scrolling: false,
     77                querying: false,
     78
    6879                init : function() {
     80                        var self = this,
     81                                startPage,
     82                                queryArray = {},
     83                                queryString = window.location.search;
     84
     85                        // We're using infinite scrolling, so hide all pagination.
    6986                        $('.pagination-links').hide();
    7087
    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 ) );
     88                        // Parse GET query string
     89                        queryArray = this.parseQuery( queryString.substring( 1 ) );
    7690
    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'];
     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'];
    8397
    84                         if ( isNaN( inputs.startPage ) )
    85                                 inputs.startPage = 2;
    86                         else
    87                                 inputs.startPage++;
     98                        startPage = parseInt( queryArray['paged'] );
     99                        if ( !isNaN( startPage ) )
     100                                this.nextPage++;
    88101
    89                         // Cache jQuery objects
    90                         inputs.outList = $('#availablethemes');
    91                         inputs.waiting = $('div.tablenav.bottom').children( 'img.ajax-loading' );
    92                         inputs.window = $(window);
     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);
    93107
    94                         // Generate Query
    95                         wpThemes.query = new Query();
    96 
    97108                        // Start Polling
    98                         inputs.window.scroll( function(){ wpThemes.maybeLoad(); } );
     109                        this.$window.scroll( function(){ self.scrolling = true; });
     110                        setInterval( function() {
     111                                if ( self.scrolling ) {
     112                                        self.scrolling = false;
     113                                        self.maybeLoad();
     114                                }
     115                        }, this.scrollThrottleDelay );
    99116                },
    100                 delayedCallback : function( func, delay ) {
    101                         var timeoutTriggered, funcTriggered, funcArgs, funcContext;
    102 
    103                         if ( ! delay )
    104                                 return func;
    105 
    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                         };
    121                 },
    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);
     117                process: function( results ) {
    135118                        if ( ( results === undefined ) ||
    136                                  ( results.rows.indexOf( "no-items" ) != -1 ) ) {
     119                                ( results.rows.indexOf( "no-items" ) != -1 ) ) {
    137120                                this.noMoreResults = true;
    138121                        } else {
    139                                 inputs.outList.append( results.rows );
     122                                this.$outList.append( results.rows );
    140123                        }
    141124                },
    142125                maybeLoad: function() {
    143126                        var self = this,
    144                                 el = $(document),
    145                                 bottom = el.scrollTop() + inputs.window.innerHeight();
    146                                
     127                                bottom = this.$document.scrollTop() + this.$window.innerHeight();
     128
    147129                        if ( this.noMoreResults ||
    148                                  !this.query.ready() ||
    149                                  ( bottom < inputs.outList.height() - wpThemes.outListBottomThreshold ) )
     130                                this.querying ||
     131                                ( bottom < this.$outList.height() - this.outListBottomThreshold ) )
    150132                                return;
    151133
    152                         setTimeout( function() {
    153                                 var newTop = el.scrollTop(),
    154                                         newBottom = newTop + inputs.window.innerHeight();
     134                        this.querying = true;
     135                        var query = {
     136                                action: 'fetch-list',
     137                                tab: this.tab,
     138                                paged: this.nextPage,
     139                                s: this.search,
     140                                type: this.type,
     141                                _ajax_fetch_list_nonce: this.nonce,
     142                                'features[]': this.features,
     143                                'list_args': list_args
     144                        };
    155145
    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 );
     146                        this.$spinner.css( 'visibility', 'visible' );
     147                        $.getJSON( ajaxurl, query )
     148                                .done( function( response ) {
     149                                        self.nextPage++;
     150                                        self.process( response );
     151                                        self.$spinner.css( 'visibility', 'hidden' );
     152                                        self.querying = false;
     153                                })
     154                                .fail( function() {
     155                                        self.$spinner.css( 'visibility', 'hidden' );
     156                                        self.querying = false;
     157                                        setTimeout( function() { self.maybeLoad(); }, self.failedRetryDelay)
     158                                });
    164159                },
    165160                parseQuery: function( query ) {
    166161                        var Params = {};
    167                         if ( ! query ) {return Params;}// return empty object
     162                        if ( !query ) { return Params; }
    168163                        var Pairs = query.split(/[;&]/);
    169164                        for ( var i = 0; i < Pairs.length; i++ ) {
    170165                                var KeyVal = Pairs[i].split('=');
    171                                 if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
     166                                if ( ! KeyVal || KeyVal.length != 2 ) { continue; }
    172167                                var key = unescape( KeyVal[0] );
    173168                                var val = unescape( KeyVal[1] );
    174169                                val = val.replace(/\+/g, ' ');
    175170                                key = key.replace(/\[.*\]$/g, '');
    176        
     171
    177172                                if ( Params[key] === undefined ) {
    178173                                        Params[key] = val;
    179174                                } else {
    180175                                        var oldVal = Params[key];
    181                                         if ( ! jQuery.isArray( Params[key] ) )
     176                                        if ( !jQuery.isArray( Params[key] ) )
    182177                                                Params[key] = new Array( oldVal, val );
    183178                                        else
    184179                                                Params[key].push( val );
     
    188183                }
    189184        }
    190185
    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                         };
     186        $(document).ready( function($) { ThemeScroller.init(); });
    213187
    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 
    226188})(jQuery);