WordPress.org

Make WordPress Core

Ticket #19815: 19815.9.diff

File 19815.9.diff, 7.4 KB (added by garyc40, 6 years ago)

More efficient throttling. Based on 19815.8.diff.

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

    var ThemeViewer; 
    4545                        init: init
    4646                };
    4747
    48         return api;
     48        return api;
    4949        }
    5050})(jQuery);
    5151
    jQuery( document ).ready( function($) { 
    5454        theme_viewer.init();
    5555});
    5656
    57 var wpThemes;
     57var ThemeScroller;
    5858
    5959(function($){
    60         var inputs = {}, Query;
    61 
    62         wpThemes = {
    63                 timeToTriggerQuery: 150,
    64                 minQueryAJAXDuration: 200,
     60        ThemeScroller = {
     61                // Inputs
     62                nonce: '',
     63                search: '',
     64                tab: '',
     65                type: '',
     66                nextPage: 2,
     67                features: {},
     68
     69                // Preferences
     70                scrollThrottleDelay: 500,
     71                failedRetryDelay: 4000,
    6572                outListBottomThreshold: 200,
     73
     74                // Flags
    6675                noMoreResults: false,
    67                
     76                scrolling: false,
     77                querying: false,
     78
     79                // Timeout variable
     80                timeout: null,
     81
    6882                init : function() {
     83                        var self = this,
     84                                startPage,
     85                                queryArray = {},
     86                                queryString = window.location.search;
     87
     88                        // We're using infinite scrolling, so hide all pagination.
    6989                        $('.pagination-links').hide();
    7090
    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 ) );
    76 
    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'];
    83 
    84                         if ( isNaN( inputs.startPage ) )
    85                                 inputs.startPage = 2;
    86                         else
    87                                 inputs.startPage++;
    88 
    89                         // Cache jQuery objects
    90                         inputs.outList = $('#availablethemes');
    91                         inputs.waiting = $('div.tablenav.bottom').children( 'img.ajax-loading' );
    92                         inputs.window = $(window);
    93 
    94                         // Generate Query
    95                         wpThemes.query = new Query();
    96 
    97                         // Start Polling
    98                         inputs.window.scroll( function(){ wpThemes.maybeLoad(); } );
    99                 },
    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                         };
     91                        // Parse GET query string
     92                        queryArray = this.parseQuery( queryString.substring( 1 ) );
     93
     94                        // Handle inputs
     95                        this.nonce = $('#_ajax_fetch_list_nonce').val();
     96                        this.search = queryArray['s'];
     97                        this.features = queryArray['features'];
     98                        this.tab = queryArray['tab'];
     99                        this.type = queryArray['type'];
     100
     101                        startPage = parseInt( queryArray['paged'] );
     102                        if ( !isNaN( startPage ) )
     103                                this.nextPage++;
     104
     105                        // Cache jQuery selectors
     106                        this.$outList = $('#availablethemes');
     107                        this.$spinner = $('div.tablenav.bottom').children( 'img.ajax-loading' );
     108                        this.$window = $(window);
     109                        this.$document = $(document);
     110
     111                        setInterval(this.poll, this.scrollThrottleDelay);
    121112                },
    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 );
     113                poll : function() {
     114                        var t = ThemeScroller,
     115                                bottom = t.$document.scrollTop() + t.$window.innerHeight();
    129116
    130                         this.query.ajax( response );
     117                        if ( t.noMoreResults ||
     118                                t.querying ||
     119                                ( bottom < t.$outList.height() - t.outListBottomThreshold ) )
     120                                return;
     121
     122                        t.maybeLoad();
    131123                },
    132                 process: function( results, params ) {
    133                         // If no Results, for now, mark as no Matches, and bail.
    134                         // Alternately: inputs.outList.append(wpThemesL10n.noMatchesFound);
     124                process: function( results ) {
    135125                        if ( ( results === undefined ) ||
    136                                  ( results.rows.indexOf( "no-items" ) != -1 ) ) {
     126                                ( results.rows.indexOf( "no-items" ) != -1 ) ) {
    137127                                this.noMoreResults = true;
    138128                        } else {
    139                                 inputs.outList.append( results.rows );
     129                                this.$outList.append( results.rows );
    140130                        }
    141131                },
    142132                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;
    151 
    152                         setTimeout( function() {
    153                                 var newTop = el.scrollTop(),
    154                                         newBottom = newTop + inputs.window.innerHeight();
     133                        var self = this;
     134                        this.timeout = null;
     135                        this.querying = true;
    155136
    156                                 if ( !self.query.ready() ||
    157                                          ( newBottom < inputs.outList.height() - wpThemes.outListBottomThreshold ) )
    158                                         return;
     137                        var query = {
     138                                action: 'fetch-list',
     139                                tab: this.tab,
     140                                paged: this.nextPage,
     141                                s: this.search,
     142                                type: this.type,
     143                                _ajax_fetch_list_nonce: this.nonce,
     144                                'features[]': this.features,
     145                                'list_args': list_args
     146                        };
    159147
    160                                 inputs.waiting.css( 'visibility', 'visible' ); // Show Spinner
    161                                 self.ajax( function() { inputs.waiting.css( 'visibility', 'hidden' ) } ); // Hide Spinner
    162                                
    163                         }, wpThemes.timeToTriggerQuery );
     148                        this.$spinner.css( 'visibility', 'visible' );
     149                        $.getJSON( ajaxurl, query )
     150                                .done( function( response ) {
     151                                        self.nextPage++;
     152                                        self.process( response );
     153                                        self.$spinner.css( 'visibility', 'hidden' );
     154                                        self.querying = false;
     155                                })
     156                                .fail( function() {
     157                                        self.$spinner.css( 'visibility', 'hidden' );
     158                                        self.querying = false;
     159                                        setTimeout( function() { self.maybeLoad(); }, self.failedRetryDelay)
     160                                });
    164161                },
    165162                parseQuery: function( query ) {
    166163                        var Params = {};
    167                         if ( ! query ) {return Params;}// return empty object
     164                        if ( !query ) { return Params; }
    168165                        var Pairs = query.split(/[;&]/);
    169166                        for ( var i = 0; i < Pairs.length; i++ ) {
    170167                                var KeyVal = Pairs[i].split('=');
    171                                 if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
     168                                if ( ! KeyVal || KeyVal.length != 2 ) { continue; }
    172169                                var key = unescape( KeyVal[0] );
    173170                                var val = unescape( KeyVal[1] );
    174171                                val = val.replace(/\+/g, ' ');
    175172                                key = key.replace(/\[.*\]$/g, '');
    176        
     173
    177174                                if ( Params[key] === undefined ) {
    178175                                        Params[key] = val;
    179176                                } else {
    180177                                        var oldVal = Params[key];
    181                                         if ( ! jQuery.isArray( Params[key] ) )
     178                                        if ( !jQuery.isArray( Params[key] ) )
    182179                                                Params[key] = new Array( oldVal, val );
    183180                                        else
    184181                                                Params[key].push( val );
    var wpThemes; 
    188185                }
    189186        }
    190187
    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                         };
    213 
    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 );
     188        $(document).ready( function($) { ThemeScroller.init(); });
    225189
    226190})(jQuery);