WordPress.org

Make WordPress Core

Changeset 23882


Ignore:
Timestamp:
03/30/13 23:32:12 (5 years ago)
Author:
azaozz
Message:

Heartbeat: improve setting the errorstate, add ajaxurl to the settings object when loading on the front-end, some code cleanup, see #23216

Location:
trunk/wp-includes
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/general-template.php

    r23801 r23882  
    23342334 */ 
    23352335function wp_heartbeat_settings( $settings ) { 
     2336    if ( ! is_admin() ) 
     2337        $settings['ajaxurl'] = admin_url( 'admin-ajax.php', 'relative' ); 
     2338 
    23362339    if ( is_user_logged_in() ) 
    23372340        $settings['nonce'] = wp_create_nonce( 'heartbeat-nonce' ); 
  • trunk/wp-includes/js/heartbeat.js

    r23481 r23882  
    1313            nonce, 
    1414            screenid = typeof pagenow != 'undefined' ? pagenow : '', 
     15            url = typeof ajaxurl != 'undefined' ? ajaxurl : '', 
    1516            settings, 
    1617            tick = 0, 
    1718            queue = {}, 
    1819            interval, 
    19             lastconnect = 0, 
    2020            connecting, 
    21             countdown, 
     21            countdown = 0, 
     22            errorcount = 0, 
    2223            tempInterval, 
    2324            hasFocus = true, 
     
    2728            frameBlurTimeout = -1; 
    2829 
    29         this.url = typeof ajaxurl != 'undefined' ? ajaxurl : 'wp-admin/admin-ajax.php'; 
    3030        this.autostart = true; 
     31        this.connectionLost = false; 
    3132 
    3233        if ( typeof( window.heartbeatSettings != 'undefined' ) ) { 
    33             settings = $.extend( {}, window.heartbeatSettings ); 
    34             window.heartbeatSettings = null; 
     34            settings = window.heartbeatSettings; 
    3535 
    3636            // Add private vars 
    3737            nonce = settings.nonce || ''; 
    3838            delete settings.nonce; 
     39 
     40            url = settings.ajaxurl || url; 
     41            delete settings.ajaxurl; 
    3942 
    4043            interval = settings.interval || 15; // default interval 
     
    4851            interval = interval * 1000; 
    4952 
    50             // todo: needed? 
    5153            // 'screenid' can be added from settings on the front-end where the JS global 'pagenow' is not set 
    5254            screenid = screenid || settings.screenid || 'site'; 
     
    7375        } 
    7476 
    75         // Set error state and fire an event if errors persist for over 2 min when the window has focus 
    76         // or 6 min when the window is in the background 
    77         function errorstate() { 
    78             var since; 
    79  
    80             if ( lastconnect ) { 
    81                 since = time() - lastconnect, duration = hasFocus ? 120000 : 360000; 
    82  
    83                 if ( since > duration ) { 
     77        // Set error state and fire an event if XHR errors or timeout 
     78        function errorstate( error ) { 
     79            var trigger; 
     80 
     81            if ( error ) { 
     82                switch ( error ) { 
     83                    case 'abort': 
     84                        // do nothing 
     85                        break; 
     86                    case 'timeout': 
     87                        // no response for 30 sec. 
     88                        trigger = true; 
     89                        break; 
     90                    case 'parsererror': 
     91                    case 'error': 
     92                    case 'empty': 
     93                    case 'unknown': 
     94                        errorcount++; 
     95 
     96                        if ( errorcount > 2 ) 
     97                            trigger = true; 
     98 
     99                        break; 
     100                } 
     101 
     102                if ( trigger && ! self.connectionLost ) { 
    84103                    self.connectionLost = true; 
    85                     $(document).trigger( 'heartbeat-connection-lost', parseInt(since / 1000) ); 
    86                 } else if ( self.connectionLost ) { 
    87                     self.connectionLost = false; 
    88                     $(document).trigger( 'heartbeat-connection-restored' ); 
     104                    $(document).trigger( 'heartbeat-connection-lost' ); 
    89105                } 
     106            } else if ( self.connectionLost ) { 
     107                errorcount = 0; 
     108                self.connectionLost = false; 
     109                $(document).trigger( 'heartbeat-connection-restored' ); 
    90110            } 
    91111        } 
     
    96116 
    97117            data.data = $.extend( {}, queue ); 
     118            // Clear the data queue, anything added after this point will be send on the next tick 
     119            queue = {}; 
     120 
    98121            $(document).trigger( 'heartbeat-send', [data.data] ); 
    99122 
     
    105128 
    106129            connecting = true; 
    107             self.xhr = $.post( self.url, data, 'json' ) 
    108             .done( function( data, textStatus, jqXHR ) { 
    109                 var interval; 
    110  
    111                 // Clear the data queue 
    112                 queue = {}; 
     130            self.xhr = $.ajax({ 
     131                url: url, 
     132                type: 'post', 
     133                timeout: 30000, // throw an error of not completed after 30 sec. 
     134                data: data, 
     135                dataType: 'json' 
     136            }).done( function( data, textStatus, jqXHR ) { 
     137                var new_interval, timed; 
     138 
     139                if ( ! data ) 
     140                    return errorstate( 'empty' ); 
    113141 
    114142                // Clear error state 
    115                 lastconnect = time(); 
    116143                if ( self.connectionLost ) 
    117144                    errorstate(); 
    118145 
    119146                // Change the interval from PHP 
    120                 interval = data.heartbeat_interval; 
     147                new_interval = data.heartbeat_interval; 
    121148                delete data.heartbeat_interval; 
    122149 
    123150                self.tick( data, textStatus, jqXHR ); 
    124151 
    125                 // do this last, can trigger the next XHR 
    126                 if ( interval ) 
    127                     self.interval.apply( self, data.heartbeat_interval ); 
    128             }).always( function(){ 
     152                // do this last, can trigger the next XHR if connection time > 5 sec. and new_interval == 'fast' 
     153                if ( new_interval ) 
     154                    self.interval.call( self, new_interval ); 
     155            }).always( function() { 
    129156                connecting = false; 
    130157                next(); 
    131             }).fail( function( jqXHR, textStatus, error ){ 
    132                 errorstate(); 
     158            }).fail( function( jqXHR, textStatus, error ) { 
     159                errorstate( textStatus || 'unknown' ); 
    133160                self.error( jqXHR, textStatus, error ); 
    134161            }); 
     
    143170            if ( !hasFocus ) { 
    144171                t = 120000; // 2 min 
    145             } else if ( countdown && tempInterval ) { 
     172            } else if ( countdown > 0 && tempInterval ) { 
    146173                t = tempInterval; 
    147174                countdown--; 
     
    215242        } 
    216243 
    217         $(window).on('blur.wp-heartbeat-focus', function(e){ 
     244        $(window).on('blur.wp-heartbeat-focus', function(e) { 
    218245            setFrameEvents(); 
    219246            winBlurTimeout = window.setTimeout( function(){ blurred(); }, 500 ); 
    220         }).on('focus.wp-heartbeat-focus', function(){ 
     247        }).on('focus.wp-heartbeat-focus', function() { 
    221248            $('iframe').each( function(i, frame){ 
    222249                if ( !isLocalFrame(frame) ) 
     
    262289            if ( !userActiveEvents ) { 
    263290                $(document).on('mouseover.wp-heartbeat-active keyup.wp-heartbeat-active', function(){ userIsActive(); }); 
     291 
    264292                $('iframe').each( function(i, frame){ 
    265293                    if ( !isLocalFrame(frame) ) 
     
    268296                    $(frame.contentWindow).on('mouseover.wp-heartbeat-active keyup.wp-heartbeat-active', function(){ userIsActive(); }); 
    269297                }); 
     298 
    270299                userActiveEvents = true; 
    271300            } 
     
    284313        } 
    285314 
    286         this.winHasFocus = function() { 
     315        this.hasFocus = function() { 
    287316            return hasFocus; 
    288317        } 
     
    291320         * Get/Set the interval 
    292321         * 
    293          * When setting the interval to 'fast', the number of ticks is specified wiht the second argument, default 30. 
    294          * If the window doesn't have focus, the interval is overridden to 2 min. In this case setting the 'ticks' 
    295          * will start counting after the window gets focus. 
     322         * When setting to 'fast', the interval is 5 sec. for the next 30 ticks (for 2 min and 30 sec). 
     323         * If the window doesn't have focus, the interval slows down to 2 min. 
    296324         * 
    297325         * @param string speed Interval speed: 'fast' (5sec), 'standard' (15sec) default, 'slow' (60sec) 
    298          * @param int ticks Number of ticks for the changed interval, optional when setting 'standard' or 'slow' 
    299326         * @return int Current interval in seconds 
    300327         */ 
    301         this.interval = function(speed, ticks) { 
     328        this.interval = function( speed ) { 
    302329            var reset, seconds; 
    303330 
     
    306333                    case 'fast': 
    307334                        seconds = 5; 
    308                         countdown = parseInt(ticks) || 30; 
     335                        countdown = 30; 
    309336                        break; 
    310337                    case 'slow': 
    311338                        seconds = 60; 
    312                         countdown = parseInt(ticks) || 0; 
     339                        countdown = 0; 
    313340                        break; 
    314341                    case 'long-polling': 
     
    325352                reset = seconds * 1000 < interval; 
    326353 
    327                 if ( countdown ) { 
     354                if ( countdown > 0 ) { 
    328355                    tempInterval = seconds * 1000; 
    329356                } else { 
     
    362389 
    363390        /** 
    364          * Send data with the next XHR 
     391         * Enqueue data to send with the next XHR 
    365392         * 
    366393         * As the data is sent later, this function doesn't return the XHR response. 
     
    372399         * Use wp.heartbeat.isQueued('handle') to see if any data is already queued for that handle. 
    373400         * 
    374          * $param string handle Unique handle for the data. The handle is used in PHP to receive the data 
    375          * $param mixed data The data to be sent 
    376          * $param bool overwrite Whether to overwrite existing data in the queue 
    377          * $return bool Whether the data was queued or not 
     401         * $param string handle Unique handle for the data. The handle is used in PHP to receive the data. 
     402         * $param mixed data The data to send. 
     403         * $param bool dont_overwrite Whether to overwrite existing data in the queue. 
     404         * $return bool Whether the data was queued or not. 
    378405         */ 
    379         this.send = function(handle, data, overwrite) { 
     406        this.enqueue = function( handle, data, dont_overwrite ) { 
    380407            if ( handle ) { 
    381                 if ( queue.hasOwnProperty(handle) && !overwrite ) 
     408                if ( queue.hasOwnProperty(handle) && dont_overwrite ) 
    382409                    return false; 
    383410 
     
    394421         * $return mixed The data queued with that handle or null 
    395422         */ 
    396         this.isQueued = function(handle) { 
     423        this.isQueued = function( handle ) { 
    397424            return queue[handle]; 
    398425        } 
     
    400427 
    401428    $.extend( Heartbeat.prototype, { 
    402         tick: function(data, textStatus, jqXHR) { 
     429        tick: function( data, textStatus, jqXHR ) { 
    403430            $(document).trigger( 'heartbeat-tick', [data, textStatus, jqXHR] ); 
    404431        }, 
    405         error: function(jqXHR, textStatus, error) { 
     432        error: function( jqXHR, textStatus, error ) { 
    406433            $(document).trigger( 'heartbeat-error', [jqXHR, textStatus, error] ); 
    407434        } 
Note: See TracChangeset for help on using the changeset viewer.