From 220980cc04dc19117f89cb5850692d3641e2d864 Mon Sep 17 00:00:00 2001 From: patdenice Date: Wed, 30 Mar 2011 08:48:20 +0000 Subject: Add ajaxmanager plugin. git-svn-id: http://piwigo.org/svn/trunk@9933 68402e56-0260-453c-a942-63ccdbb3a9ee --- themes/default/js/plugins/jquery.ajaxmanager.js | 342 ++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 themes/default/js/plugins/jquery.ajaxmanager.js (limited to 'themes') diff --git a/themes/default/js/plugins/jquery.ajaxmanager.js b/themes/default/js/plugins/jquery.ajaxmanager.js new file mode 100644 index 000000000..9c99df670 --- /dev/null +++ b/themes/default/js/plugins/jquery.ajaxmanager.js @@ -0,0 +1,342 @@ +/**! + * project-site: http://plugins.jquery.com/project/AjaxManager + * repository: http://github.com/aFarkas/Ajaxmanager + * @author Alexander Farkas + * @version 3.12 + * Copyright 2010, Alexander Farkas + * Dual licensed under the MIT or GPL Version 2 licenses. + */ + +(function($){ + "use strict"; + var managed = {}, + cache = {} + ; + $.manageAjax = (function(){ + function create(name, opts){ + managed[name] = new $.manageAjax._manager(name, opts); + return managed[name]; + } + + function destroy(name){ + if(managed[name]){ + managed[name].clear(true); + delete managed[name]; + } + } + + + var publicFns = { + create: create, + destroy: destroy + }; + + return publicFns; + })(); + + $.manageAjax._manager = function(name, opts){ + this.requests = {}; + this.inProgress = 0; + this.name = name; + this.qName = name; + + this.opts = $.extend({}, $.manageAjax.defaults, opts); + if(opts && opts.queue && opts.queue !== true && typeof opts.queue === 'string' && opts.queue !== 'clear'){ + this.qName = opts.queue; + } + }; + + $.manageAjax._manager.prototype = { + add: function(url, o){ + if(typeof url == 'object'){ + o = url; + } else if(typeof url == 'string'){ + o = $.extend(o || {}, {url: url}); + } + o = $.extend({}, this.opts, o); + + var origCom = o.complete || $.noop, + origSuc = o.success || $.noop, + beforeSend = o.beforeSend || $.noop, + origError = o.error || $.noop, + strData = (typeof o.data == 'string') ? o.data : $.param(o.data || {}), + xhrID = o.type + o.url + strData, + that = this, + ajaxFn = this._createAjax(xhrID, o, origSuc, origCom) + ; + if(o.preventDoubleRequests && o.queueDuplicateRequests){ + if(o.preventDoubleRequests){ + o.queueDuplicateRequests = false; + } + setTimeout(function(){ + throw("preventDoubleRequests and queueDuplicateRequests can't be both true"); + }, 0); + } + if(this.requests[xhrID] && o.preventDoubleRequests){ + return; + } + ajaxFn.xhrID = xhrID; + o.xhrID = xhrID; + + o.beforeSend = function(xhr, opts){ + var ret = beforeSend.call(this, xhr, opts); + if(ret === false){ + that._removeXHR(xhrID); + } + xhr = null; + return ret; + }; + o.complete = function(xhr, status){ + that._complete.call(that, this, origCom, xhr, status, xhrID, o); + xhr = null; + }; + + o.success = function(data, status, xhr){ + that._success.call(that, this, origSuc, data, status, xhr, o); + xhr = null; + }; + + //always add some error callback + o.error = function(ahr, status, errorStr){ + var httpStatus = '', + content = '' + ; + if(status !== 'timeout' && ahr){ + httpStatus = ahr.status; + content = ahr.responseXML || ahr.responseText; + } + if(origError) { + origError.call(this, ahr, status, errorStr, o); + } else { + setTimeout(function(){ + throw status + '| status: ' + httpStatus + ' | URL: ' + o.url + ' | data: '+ strData + ' | thrown: '+ errorStr + ' | response: '+ content; + }, 0); + } + ahr = null; + }; + + if(o.queue === 'clear'){ + $(document).clearQueue(this.qName); + } + + if(o.queue || (o.queueDuplicateRequests && this.requests[xhrID])){ + $.queue(document, this.qName, ajaxFn); + if(this.inProgress < o.maxRequests && (!this.requests[xhrID] || !o.queueDuplicateRequests)){ + $.dequeue(document, this.qName); + } + return xhrID; + } + return ajaxFn(); + }, + _createAjax: function(id, o, origSuc, origCom){ + var that = this; + return function(){ + if(o.beforeCreate.call(o.context || that, id, o) === false){return;} + that.inProgress++; + if(that.inProgress === 1){ + $.event.trigger(that.name +'AjaxStart'); + } + if(o.cacheResponse && cache[id]){ + if(!cache[id].cacheTTL || cache[id].cacheTTL < 0 || ((new Date().getTime() - cache[id].timestamp) < cache[id].cacheTTL)){ + that.requests[id] = {}; + setTimeout(function(){ + that._success.call(that, o.context || o, origSuc, cache[id]._successData, 'success', cache[id], o); + that._complete.call(that, o.context || o, origCom, cache[id], 'success', id, o); + }, 0); + } else { + delete cache[id]; + } + } + if(!o.cacheResponse || !cache[id]) { + if (o.async) { + that.requests[id] = $.ajax(o); + } else { + $.ajax(o); + } + } + return id; + }; + }, + _removeXHR: function(xhrID){ + if(this.opts.queue || this.opts.queueDuplicateRequests){ + $.dequeue(document, this.qName); + } + this.inProgress--; + this.requests[xhrID] = null; + delete this.requests[xhrID]; + }, + clearCache: function () { + cache = {}; + }, + _isAbort: function(xhr, status, o){ + if(!o.abortIsNoSuccess || (!xhr && !status)){ + return false; + } + var ret = !!( ( !xhr || xhr.readyState === 0 || this.lastAbort === o.xhrID ) ); + xhr = null; + return ret; + }, + _complete: function(context, origFn, xhr, status, xhrID, o){ + if(this._isAbort(xhr, status, o)){ + status = 'abort'; + o.abort.call(context, xhr, status, o); + } + origFn.call(context, xhr, status, o); + + $.event.trigger(this.name +'AjaxComplete', [xhr, status, o]); + + if(o.domCompleteTrigger){ + $(o.domCompleteTrigger) + .trigger(this.name +'DOMComplete', [xhr, status, o]) + .trigger('DOMComplete', [xhr, status, o]) + ; + } + + this._removeXHR(xhrID); + if(!this.inProgress){ + $.event.trigger(this.name +'AjaxStop'); + } + xhr = null; + }, + _success: function(context, origFn, data, status, xhr, o){ + var that = this; + if(this._isAbort(xhr, status, o)){ + xhr = null; + return; + } + if(o.abortOld){ + $.each(this.requests, function(name){ + if(name === o.xhrID){ + return false; + } + that.abort(name); + }); + } + if(o.cacheResponse && !cache[o.xhrID]){ + if(!xhr){ + xhr = {}; + } + cache[o.xhrID] = { + status: xhr.status, + statusText: xhr.statusText, + responseText: xhr.responseText, + responseXML: xhr.responseXML, + _successData: data, + cacheTTL: o.cacheTTL, + timestamp: new Date().getTime() + }; + if('getAllResponseHeaders' in xhr){ + var responseHeaders = xhr.getAllResponseHeaders(); + var parsedHeaders; + var parseHeaders = function(){ + if(parsedHeaders){return;} + parsedHeaders = {}; + $.each(responseHeaders.split("\n"), function(i, headerLine){ + var delimiter = headerLine.indexOf(":"); + parsedHeaders[headerLine.substr(0, delimiter)] = headerLine.substr(delimiter + 2); + }); + }; + $.extend(cache[o.xhrID], { + getAllResponseHeaders: function() {return responseHeaders;}, + getResponseHeader: function(name) { + parseHeaders(); + return (name in parsedHeaders) ? parsedHeaders[name] : null; + } + }); + } + } + origFn.call(context, data, status, xhr, o); + $.event.trigger(this.name +'AjaxSuccess', [xhr, o, data]); + if(o.domSuccessTrigger){ + $(o.domSuccessTrigger) + .trigger(this.name +'DOMSuccess', [data, o]) + .trigger('DOMSuccess', [data, o]) + ; + } + xhr = null; + }, + getData: function(id){ + if( id ){ + var ret = this.requests[id]; + if(!ret && this.opts.queue) { + ret = $.grep($(document).queue(this.qName), function(fn, i){ + return (fn.xhrID === id); + })[0]; + } + return ret; + } + return { + requests: this.requests, + queue: (this.opts.queue) ? $(document).queue(this.qName) : [], + inProgress: this.inProgress + }; + }, + abort: function(id){ + var xhr; + if(id){ + xhr = this.getData(id); + + if(xhr && xhr.abort){ + this.lastAbort = id; + xhr.abort(); + this.lastAbort = false; + } else { + $(document).queue( + this.qName, $.grep($(document).queue(this.qName), function(fn, i){ + return (fn !== xhr); + }) + ); + } + xhr = null; + return; + } + + var that = this, + ids = [] + ; + $.each(this.requests, function(id){ + ids.push(id); + }); + $.each(ids, function(i, id){ + that.abort(id); + }); + }, + clear: function(shouldAbort){ + $(document).clearQueue(this.qName); + if(shouldAbort){ + this.abort(); + } + } + }; + $.manageAjax._manager.prototype.getXHR = $.manageAjax._manager.prototype.getData; + $.manageAjax.defaults = { + beforeCreate: $.noop, + abort: $.noop, + abortIsNoSuccess: true, + maxRequests: 1, + cacheResponse: false, + async: true, + domCompleteTrigger: false, + domSuccessTrigger: false, + preventDoubleRequests: true, + queueDuplicateRequests: false, + cacheTTL: -1, + queue: false // true, false, clear + }; + + $.each($.manageAjax._manager.prototype, function(n, fn){ + if(n.indexOf('_') === 0 || !$.isFunction(fn)){return;} + $.manageAjax[n] = function(name, o){ + if(!managed[name]){ + if(n === 'add'){ + $.manageAjax.create(name, o); + } else { + return; + } + } + var args = Array.prototype.slice.call(arguments, 1); + managed[name][n].apply(managed[name], args); + }; + }); + +})(jQuery); \ No newline at end of file -- cgit v1.2.3