first commit
This commit is contained in:
264
lib/js/jquery-periodical-updater.js
vendored
Normal file
264
lib/js/jquery-periodical-updater.js
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* PeriodicalUpdater - jQuery plugin for timed, decaying ajax calls
|
||||
*
|
||||
* http://www.360innovate.co.uk/blog/2009/03/periodicalupdater-for-jquery/
|
||||
* http://enfranchisedmind.com/blog/posts/jquery-periodicalupdater-ajax-polling/
|
||||
*
|
||||
* Copyright (c) 2009-2012 by the following:
|
||||
* Frank White (http://customcode.info)
|
||||
* Robert Fischer (http://smokejumperit.com)
|
||||
* 360innovate (http://www.360innovate.co.uk)
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
// The free version
|
||||
$.PeriodicalUpdater = function(url, options, callback){
|
||||
if(!options) options = {};
|
||||
var settings = jQuery.extend(true, {
|
||||
url: url, // URL of ajax request
|
||||
cache: false, // By default, don't allow caching
|
||||
method: 'GET', // method; get or post
|
||||
data: '', // array of values to be passed to the page - e.g. {name: "John", greeting: "hello"}
|
||||
minTimeout: 1000, // starting value for the timeout in milliseconds
|
||||
maxTimeout:64000, // maximum length of time between requests
|
||||
multiplier: 2, // if set to 2, timerInterval will double each time the response hasn't changed (up to maxTimeout)
|
||||
maxCalls: 0, // maximum number of calls. 0 = no limit.
|
||||
autoStop: 0, // automatically stop requests after this many returns of the same data. 0 = disabled
|
||||
autoStopCallback: null, // The callback to execute when we autoStop
|
||||
cookie: false, // whether (and how) to store a cookie
|
||||
runatonce: false, // Whether to fire initially or wait
|
||||
verbose: 0 // The level to be logging at: 0 = none; 1 = some; 2 = all
|
||||
}, options);
|
||||
|
||||
var pu_log = function (msg, lvl) {
|
||||
lvl = lvl || 1;
|
||||
if(settings.verbose >= lvl) {
|
||||
try {
|
||||
console.log(msg);
|
||||
} catch (err) { }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// set some initial values, then begin
|
||||
var timer = null;
|
||||
var remoteData = null;
|
||||
var prevData = null;
|
||||
var timerInterval = settings.minTimeout;
|
||||
var maxCalls = settings.maxCalls;
|
||||
var autoStop = settings.autoStop;
|
||||
var calls = 0;
|
||||
var noChange = 0;
|
||||
var originalMaxCalls = maxCalls;
|
||||
|
||||
// Function to reset the timer to a given time
|
||||
var reset_timer = function (interval) {
|
||||
$(function() { // Ensure we're live
|
||||
if (timer !== null) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timerInterval = interval;
|
||||
pu_log('resetting timer to ' + timerInterval + '.', 2);
|
||||
if(settings.cookie && $.cookie) {
|
||||
$.cookie(settings.cookie.name, timerInterval, settings.cookie);
|
||||
}
|
||||
timer = setTimeout(getdata, timerInterval);
|
||||
});
|
||||
};
|
||||
|
||||
// Function to boost the timer
|
||||
var boostPeriod = function () {
|
||||
if (settings.multiplier > 1) {
|
||||
var before = timerInterval;
|
||||
timerInterval = timerInterval * settings.multiplier;
|
||||
|
||||
if (timerInterval > settings.maxTimeout) {
|
||||
timerInterval = settings.maxTimeout;
|
||||
}
|
||||
pu_log('adjusting timer from ' + before + ' to ' + timerInterval + '.', 2);
|
||||
}
|
||||
|
||||
reset_timer(timerInterval);
|
||||
};
|
||||
|
||||
// Handle the cookie config
|
||||
if(settings.cookie) {
|
||||
if(typeof(settings.cookie) == 'boolean') {
|
||||
settings.cookie = {
|
||||
name: url
|
||||
};
|
||||
} else if(typeof(settings.cookie) != 'object') {
|
||||
settings.cookie = {
|
||||
name: settings.cookie.toString()
|
||||
};
|
||||
}
|
||||
if(!settings.cookie.name) {
|
||||
settings.cookie.name = url;
|
||||
}
|
||||
|
||||
if(!$.cookie) {
|
||||
$.getScript("https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js", function() {
|
||||
pu_log("Loaded the cookies handler script", 2);
|
||||
if($.cookie(settings.cookie.name)) {
|
||||
pu_log("Not runatonce and have cookie value", 2);
|
||||
reset_timer($.cookie(settings.cookie.name));
|
||||
} else {
|
||||
pu_log("Not runatonce, but no cookie value", 2);
|
||||
reset_timer(timerInterval);
|
||||
}
|
||||
}).fail(function() {
|
||||
pu_log("Could not load the cookies handler script", 1);
|
||||
reset_timer(timerInterval);
|
||||
});
|
||||
} else {
|
||||
if($.cookie(settings.cookie.name)) {
|
||||
reset_timer($.cookie(settings.cookie.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the settings for $.ajax based on settings
|
||||
var ajaxSettings = jQuery.extend(true, {}, settings);
|
||||
if (settings.type && !ajaxSettings.dataType) { ajaxSettings.dataType = settings.type; }
|
||||
if (settings.sendData) { ajaxSettings.data = settings.sendData; }
|
||||
ajaxSettings.type = settings.method; // 'type' is used internally for jQuery. Who knew?
|
||||
ajaxSettings.ifModified = true;
|
||||
|
||||
|
||||
// Create the function to get data
|
||||
function getdata(force) {
|
||||
var toSend = jQuery.extend(true, {}, ajaxSettings); // jQuery screws with what you pass in
|
||||
if (typeof (options.data) == 'function') {
|
||||
toSend.data = options.data();
|
||||
}
|
||||
if (toSend.data) {
|
||||
// Handle transformations (only strings and objects are understood)
|
||||
if (typeof (toSend.data) == "number") {
|
||||
toSend.data = toSend.data.toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (force || maxCalls === 0) {
|
||||
pu_log("Sending data");
|
||||
$(function() { $.ajax(toSend); });
|
||||
} else if (maxCalls > 0 && calls < maxCalls) {
|
||||
pu_log("Sending data because we are at " + calls + " of " + maxCalls + " calls");
|
||||
$(function() { $.ajax(toSend); });
|
||||
calls++;
|
||||
} else if(maxCalls == -1) {
|
||||
pu_log("NOT sending data: stop has been called", 1);
|
||||
} else {
|
||||
pu_log("NOT sending data: maximum number of calls reached - " + maxCalls, 1);
|
||||
}
|
||||
}
|
||||
|
||||
var handle = {
|
||||
boostTimer: function(mag) {
|
||||
if(mag > 0 && mag != 1) {
|
||||
pu_log("Boosting timer by a factor of " + mag);
|
||||
timerInterval = timerInterval * mag;
|
||||
} else {
|
||||
pu_log("Cannot boost timer by a factor of " + mag);
|
||||
}
|
||||
reset_timer(timerInterval);
|
||||
return;
|
||||
},
|
||||
restart: function (newInterval) {
|
||||
pu_log("Calling restart");
|
||||
maxCalls = originalMaxCalls;
|
||||
calls = 0;
|
||||
noChange = 0;
|
||||
reset_timer(newInterval || timerInterval);
|
||||
return;
|
||||
},
|
||||
send: function() {
|
||||
pu_log("Explicit call to send");
|
||||
getdata(true);
|
||||
return;
|
||||
},
|
||||
stop: function () {
|
||||
pu_log("Calling stop");
|
||||
maxCalls = -1;
|
||||
if(settings.cookie && $.cookie) {
|
||||
$.cookie(settings.cookie.name, null, settings.cookie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Implement the tricky comparison logic
|
||||
ajaxSettings.success = function (data) {
|
||||
pu_log("Successful run! (In 'success')", 2);
|
||||
remoteData = data;
|
||||
};
|
||||
|
||||
ajaxSettings.complete = function (xhr, success) {
|
||||
pu_log("Status of call: " + success + " (In 'complete')", 2);
|
||||
if (success == "success" || success == "notmodified") {
|
||||
var rawData = $.trim(xhr.responseText);
|
||||
if (prevData == rawData) {
|
||||
if (autoStop > 0) {
|
||||
noChange++;
|
||||
if (noChange == autoStop) {
|
||||
handle.stop();
|
||||
if (settings.autoStopCallback) { settings.autoStopCallback(noChange); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
boostPeriod();
|
||||
} else {
|
||||
noChange = 0;
|
||||
reset_timer(settings.minTimeout);
|
||||
prevData = rawData;
|
||||
if (settings.cookie) $.cookie(settings.cookie.name, prevData, settings.cookie);
|
||||
if (remoteData === null) { remoteData = rawData; }
|
||||
// jQuery 1.4+ $.ajax() automatically converts "data" into a JS Object for "type:json" requests now
|
||||
// For compatibility with 1.4+ and pre1.4 jQuery only try to parse actual strings, skip when remoteData is already an Object
|
||||
if ((ajaxSettings.dataType === 'json') && (typeof (remoteData) === 'string') && (success == "success")) {
|
||||
remoteData = JSON.parse(remoteData);
|
||||
}
|
||||
if (settings.success) { settings.success(remoteData, success, xhr, handle); }
|
||||
if (callback) { callback(remoteData, success, xhr, handle); }
|
||||
}
|
||||
}
|
||||
if (settings.complete) { settings.complete(xhr, success); }
|
||||
remoteData = null;
|
||||
};
|
||||
|
||||
ajaxSettings.error = function (xhr, textStatus) {
|
||||
pu_log("Error message: " + textStatus + " (In 'error')", 2);
|
||||
if(textStatus != "notmodified") {
|
||||
prevData = null;
|
||||
if(settings.cookie) $.cookie(settings.cookie.name, null, settings.cookie);
|
||||
reset_timer(settings.minTimeout);
|
||||
}
|
||||
if(settings.error) { settings.error(xhr, textStatus); }
|
||||
};
|
||||
|
||||
// Make the first call
|
||||
if (settings.runatonce) {
|
||||
pu_log("Executing a call immediately", 1);
|
||||
getdata(true);
|
||||
} else if($.cookie && $.cookie(settings.cookie.name)) {
|
||||
// Do nothing (already handled above)
|
||||
} else {
|
||||
pu_log("Enqueing a the call for after " + timerInterval, 1);
|
||||
reset_timer(timerInterval);
|
||||
}
|
||||
|
||||
return handle;
|
||||
};
|
||||
|
||||
// The bound version
|
||||
$.fn.PeriodicalUpdater = function(url, options, callback) {
|
||||
var me = this;
|
||||
return $.PeriodicalUpdater(url, options, function() {
|
||||
return callback.apply(me, arguments);
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
Reference in New Issue
Block a user