From 3662f4c6fc76eeed159cbaaebe55db2023e9e465 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Thu, 19 Jan 2017 15:26:52 -0500 Subject: [PATCH] install jquery.ajaxq from npm --- app/assets/javascripts/lib/jquery.ajaxq.js | 301 +++++++++++++++++++++ frontend/src/index.js | 1 - package.json | 1 + 3 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/lib/jquery.ajaxq.js diff --git a/app/assets/javascripts/lib/jquery.ajaxq.js b/app/assets/javascripts/lib/jquery.ajaxq.js new file mode 100644 index 00000000..72000c76 --- /dev/null +++ b/app/assets/javascripts/lib/jquery.ajaxq.js @@ -0,0 +1,301 @@ +;(function(root) { + 'use strict'; + + var $ = root.jQuery || root.Zepto || root.$; + + if (typeof $ === 'undefined') throw 'jquery.ajaxq requires jQuery or jQuery-compatible library (e.g. Zepto.js)'; + + /** + * @type {Function} + */ + var slice = Array.prototype.slice; + + /** + * @type {Function} + */ + var noop = function() {}; + + /** + * Copy of jQuery function + * @type {Function} + */ + var isNumeric = function(obj) { + return !$.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + } + + /** + * @type {Function} + */ + var isObject = function(obj) { + return "[object Object]" === Object.prototype.toString.call(obj); + } + + + var Request = (function (argument) { + + function Request(url, settings) { + this._aborted = false; + this._jqXHR = null; + this._calls = {}; + this._args = [url, settings]; + this._deferred = $.Deferred(); + + this._deferred.pipe = this._deferred.then; + + this.readyState = 1; + } + + var proto = Request.prototype; + + $.extend(proto, { + + // start jqXHR by calling $.ajax + run: function() { + var + deferred = this._deferred, + methodName, argsStack, i; + + if (this._jqXHR !== null) { + return this._jqXHR; + } + // clreate new jqXHR object + var + url = this._args[0], + settings = this._args[1]; + + if (isObject(url)) { + settings = url; + } else { + settings = $.extend(true, settings || {}, { + url: url + }); + } + + this._jqXHR = $.ajax.call($, settings); + + this._jqXHR.done(function() { + deferred.resolve.apply(deferred, arguments); + }); + + this._jqXHR.fail(function() { + deferred.reject.apply(deferred, arguments); + }); + + if (this._aborted) { + this._jqXHR.abort(this.statusText); + } + + // apply buffered calls + for (methodName in this._calls) { + argsStack = this._calls[methodName]; + for (var i in argsStack) { + this._jqXHR[methodName].apply(this._jqXHR, argsStack[i]); + } + } + + return this._jqXHR; + }, + + // returns original jqXHR object if it exists + // or writes to callected method to _calls and returns itself + _call: function(methodName, args) { + if (this._jqXHR !== null) { + if (typeof this._jqXHR[methodName] === 'undefined') { + return this._jqXHR; + } + return this._jqXHR[methodName].apply(this._jqXHR, args); + } + + this._calls[methodName] = this._calls[methodName] || []; + this._calls[methodName].push(args); + + return this; + }, + + // returns original jqXHR object if it exists + // or writes to callected method to _calls and returns itself + abort: function(statusText) { + if (this._jqXHR !== null) { + var + self = this, + _copyProperties = ['readyState', 'status', 'statusText'], + _return = this._jqXHR.abort.apply(this._jqXHR, arguments) || this._jqXHR; + + if (_return) { + $.each(_copyProperties, function(i, prop) { + self[prop] = _return[prop]; + }); + } + + return _return; + } + + this.statusText = statusText || 'abort'; + this.status = 0; + this.readyState = 0; + this._aborted = true; + + return this; + }, + state: function() { + if (this._jqXHR !== null) { + return this._jqXHR.state.apply(this._jqXHR, arguments); + } + return 'pending'; + } + }); + + // each method returns self object + var _chainMethods = ['setRequestHeader', 'overrideMimeType', 'statusCode', + 'done', 'fail', 'progress', 'complete', 'success', 'error', 'always' ]; + + $.each(_chainMethods, function(i, methodName) { + proto[methodName] = function() { + return this._call(methodName, slice.call(arguments)) || this._jqXHR; + } + }); + + var _nullMethods = ['getResponseHeader', 'getAllResponseHeaders']; + + $.each(_nullMethods, function(i, methodName) { + proto[methodName] = function() { + // apply original method if _jqXHR exists + if (this._jqXHR !== null) { + return this._jqXHR[methodName].apply(this, arguments); + } + + // return null if origina method does not exists + return null; + }; + }); + + var _promiseMethods = ['pipe', 'then', 'promise']; + + $.each(_promiseMethods, function(i, methodName) { + proto[methodName] = function() { + return this._deferred[methodName].apply(this._deferred, arguments); + }; + }); + + return Request; + })() + var Queue = (function() { + + var _params = {}, _queueCounter = 0; + + function _runNext(queue, request) { + var + removeIndex = _getStarted(queue).indexOf(request), + nextRequest = _getPending(queue).shift(); + + if (removeIndex !== -1) { + _getStarted(queue).splice(removeIndex, 1); + } + + if (typeof nextRequest !== 'undefined') { + nextRequest + .always($.proxy(_runNext, null, queue, nextRequest)) + .run(); + } + } + + function _ajax(queue, request) { + if (_getStarted(queue).length < _getBandwidth(queue)) { + _getStarted(queue).push(request); + request.always($.proxy(_runNext, null, queue, request)); + request.run(); + } else { + _getPending(queue).push(request) + } + } + + function _getParams(queue) { + return _params[queue.id] || (_params[queue.id] = {}); + } + + function _getParam(queue, name) { + return _getParams(queue)[name]; + } + + function _getStarted(queue) { + return _getParams(queue).started || (_getParams(queue).started = []); + } + + function _getPending(queue) { + return _getParams(queue).pending || (_getParams(queue).pending = []); + } + + function _setBandwidth(queue, bandwidth) { + if ((bandwidth = parseInt(bandwidth || 1, 10)) < 1) throw "Bandwidth can\'t be less then 1"; + _getParams(queue).bandwidth = bandwidth; + } + + function _getBandwidth(queue, bandwidth) { + return _getParams(queue).bandwidth; + } + + function Queue(bandwidth) { + if (typeof bandwidth !== 'undefined' && !isNumeric(bandwidth)) throw "number expected"; + this.id = ++_queueCounter; + _setBandwidth(this, bandwidth); + }; + + $.extend(Queue.prototype, { + ajax: function(url, settings) { + var request = new Request(url, settings); + _ajax(this, request); + return request; + }, + getJSON: function ( url, data, callback ) { + return this.get( url, data, callback, "json" ); + }, + getBandwidth: function() { + return _getBandwidth(this); + } + }); + + $.each(['get', 'post'], function(i, method) { + Queue.prototype[method] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( $.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return this.ajax({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }); + } + }); + + return Queue; + })(); + + if (typeof $.ajaxq !== 'undefined') throw "Namespace $.ajaxq is Alread y busy."; + + var _queue = new Queue(); + + $.ajaxq = function(url, settions) { + return _queue.ajax.apply(_queue, arguments); + }; + + $.each(['get', 'post', 'getJSON'], function(i, methodName) { + $.ajaxq[methodName] = function() { + return _queue[methodName].apply(_queue, arguments); + } + }); + + $.ajaxq.Queue = function(bandwidth) { + return new Queue(bandwidth); + }; + + $.ajaxq.Request = function(url, settings) { + return new Request(url, settings); + } + +})(this); \ No newline at end of file diff --git a/frontend/src/index.js b/frontend/src/index.js index 94a0c07f..1d82af7c 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,7 +1,6 @@ // create global references import _ from 'lodash' import Metamaps from './Metamaps' -import 'jquery.ajaxq' // allow queueing ajax requests so it doesn't overload window._ = _ window.Metamaps = Metamaps diff --git a/package.json b/package.json index 07d633c5..171aa795 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "getScreenMedia": "git://github.com/devvmh/getScreenMedia#patch-1", "hark": "git://github.com/devvmh/hark#patch-1", "howler": "2.0.2", + "jquery": "^3.1.1", "jquery.ajaxq": "^0.5.2", "json-loader": "0.5.4", "lodash": "4.17.2",