WordPress.org

Make WordPress Core

Ticket #19815: 19815.9.diff

File 19815.9.diff, 7.4 KB (added by garyc40, 2 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);