Make WordPress Core

Changeset 23882


Ignore:
Timestamp:
03/30/2013 11:32:12 PM (11 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.