5edc6b2711
git-svn-id: https://develop.svn.wordpress.org/trunk@23355 602fd350-edb4-49c9-b593-d223f7449a82
179 lines
3.4 KiB
JavaScript
179 lines
3.4 KiB
JavaScript
/**
|
|
* Heartbeat API
|
|
*/
|
|
|
|
// Ensure the global `wp` object exists.
|
|
window.wp = window.wp || {};
|
|
|
|
(function($){
|
|
var Heartbeat = function() {
|
|
var self = this,
|
|
running,
|
|
timeout,
|
|
nonce,
|
|
screen = typeof pagenow != 'undefined' ? pagenow : '',
|
|
settings,
|
|
tick = 0,
|
|
queue = {},
|
|
interval,
|
|
lastconnect = 0;
|
|
|
|
this.url = typeof ajaxurl != 'undefined' ? ajaxurl : 'wp-admin/admin-ajax.php';
|
|
this.autostart = true;
|
|
|
|
if ( typeof( window.heartbeatSettings != 'undefined' ) ) {
|
|
settings = $.extend( {}, window.heartbeatSettings );
|
|
delete window.heartbeatSettings;
|
|
|
|
// Add private vars
|
|
nonce = settings.nonce || '';
|
|
delete settings.nonce;
|
|
|
|
interval = settings.interval || 15000; // default interval
|
|
delete settings.interval;
|
|
|
|
// todo: needed?
|
|
// 'pagenow' can be added from settings if not already defined
|
|
screen = screen || settings.pagenow;
|
|
delete settings.pagenow;
|
|
|
|
// Add public vars
|
|
$.extend( this, settings );
|
|
}
|
|
|
|
function time(s) {
|
|
if ( s )
|
|
return parseInt( (new Date()).getTime() / 1000 );
|
|
|
|
return (new Date()).getTime();
|
|
}
|
|
|
|
// Set error state and fire an event if it persists for over 3 min
|
|
function errorstate() {
|
|
var since;
|
|
|
|
if ( lastconnect ) {
|
|
since = time() - lastconnect;
|
|
|
|
if ( since > 180000 ) {
|
|
self.connectionLost = true;
|
|
$(document).trigger( 'heartbeat-connection-lost', parseInt(since / 1000) );
|
|
} else if ( self.connectionLost ) {
|
|
self.connectionLost = false;
|
|
$(document).trigger( 'heartbeat-connection-restored' );
|
|
}
|
|
}
|
|
}
|
|
|
|
function connect() {
|
|
var data = {};
|
|
tick = time();
|
|
|
|
data.data = $.extend( {}, queue );
|
|
queue = {};
|
|
|
|
data.interval = interval / 1000;
|
|
data._nonce = nonce;
|
|
data.action = 'heartbeat';
|
|
data.pagenow = screen;
|
|
|
|
self.xhr = $.post( self.url, data, function(r){
|
|
lastconnect = time();
|
|
// Clear error state
|
|
if ( self.connectionLost )
|
|
errorstate();
|
|
|
|
self.tick(r);
|
|
}, 'json' ).always( function(){
|
|
next();
|
|
}).fail( function(r){
|
|
errorstate();
|
|
self.error(r);
|
|
});
|
|
};
|
|
|
|
function next() {
|
|
var delta = time() - tick;
|
|
|
|
if ( !running )
|
|
return;
|
|
|
|
if ( delta < interval ) {
|
|
timeout = window.setTimeout(
|
|
function(){
|
|
if ( running )
|
|
connect();
|
|
},
|
|
interval - delta
|
|
);
|
|
} else {
|
|
window.clearTimeout(timeout); // this has already expired?
|
|
connect();
|
|
}
|
|
};
|
|
|
|
this.interval = function(seconds) {
|
|
if ( seconds ) {
|
|
// Limit
|
|
if ( 5 > seconds || seconds > 60 )
|
|
return false;
|
|
|
|
interval = seconds * 1000;
|
|
} else if ( seconds === 0 ) {
|
|
// Allow long polling to be turned on
|
|
interval = 0;
|
|
}
|
|
return interval / 1000;
|
|
};
|
|
|
|
this.start = function() {
|
|
// start only once
|
|
if ( running )
|
|
return false;
|
|
|
|
running = true;
|
|
connect();
|
|
|
|
return true;
|
|
};
|
|
|
|
this.stop = function() {
|
|
if ( !running )
|
|
return false;
|
|
|
|
if ( self.xhr )
|
|
self.xhr.abort();
|
|
|
|
running = false;
|
|
return true;
|
|
}
|
|
|
|
this.send = function(action, data) {
|
|
if ( action )
|
|
queue[action] = data;
|
|
}
|
|
|
|
if ( this.autostart ) {
|
|
$(document).ready( function(){
|
|
// Start one tick (15 sec) after DOM ready
|
|
running = true;
|
|
tick = time();
|
|
next();
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
$.extend( Heartbeat.prototype, {
|
|
tick: function(r) {
|
|
$(document).trigger( 'heartbeat-tick', r );
|
|
},
|
|
error: function(r) {
|
|
$(document).trigger( 'heartbeat-error', r );
|
|
}
|
|
});
|
|
|
|
wp.heartbeat = new Heartbeat();
|
|
|
|
}(jQuery));
|