1 /**
  2  * @namespace A unique namespace for the AJAX Solr library.
  3  */
  4 AjaxSolr = function () {};
  5 
  6 /**
  7  * @namespace Baseclass for all classes
  8  * @see https://github.com/documentcloud/backbone/blob/51eed189bf4d25877be4acdf51e0a4c6039583c5/backbone.js#L243
  9  */
 10 AjaxSolr.Class = function(attributes) {
 11   AjaxSolr.extend(this, attributes);
 12 };
 13 
 14 /**
 15  * A class 'extends' itself into a subclass.
 16  *
 17  * @static
 18  * @param protoProps The properties of the subclass.
 19  * @returns A function that represents the subclass.
 20  * @see https://github.com/documentcloud/backbone/blob/51eed189bf4d25877be4acdf51e0a4c6039583c5/backbone.js#L1516
 21  */
 22 AjaxSolr.Class.extend = function (protoProps, staticProps) {
 23   var parent = this;
 24   var child;
 25 
 26   // The constructor function for the new subclass is either defined by you
 27   // (the "constructor" property in your `extend` definition), or defaulted
 28   // by us to simply call the parent's constructor.
 29   if (protoProps && Object.prototype.hasOwnProperty.call(protoProps, 'constructor')) {
 30     child = protoProps.constructor;
 31   } else {
 32     child = function(){ return parent.apply(this, arguments); };
 33   }
 34 
 35   // Add static properties to the constructor function, if supplied.
 36   AjaxSolr.extend(child, parent, staticProps);
 37 
 38   // Set the prototype chain to inherit from `parent`, without calling
 39   // `parent`'s constructor function.
 40   var Surrogate = function(){ this.constructor = child; };
 41   Surrogate.prototype = parent.prototype;
 42   child.prototype = new Surrogate;
 43 
 44   // Add prototype properties (instance properties) to the subclass,
 45   // if supplied.
 46   if (protoProps) AjaxSolr.extend(child.prototype, protoProps);
 47 
 48   // Set a convenience property in case the parent's prototype is needed
 49   // later.
 50   child.__super__ = parent.prototype;
 51 
 52   return child;
 53 };
 54 
 55 /**
 56  * @static
 57  * @see https://github.com/documentcloud/underscore/blob/7342e289aa9d91c5aacfb3662ea56e7a6d081200/underscore.js#L789
 58 */
 59 AjaxSolr.extend = function (child) {
 60   // From _.extend
 61   var obj = Array.prototype.slice.call(arguments, 1);
 62 
 63   // From _.extend
 64   var iterator = function(source) {
 65     if (source) {
 66       for (var prop in source) {
 67         child[prop] = source[prop];
 68       }
 69     }
 70   };
 71 
 72   // From _.each
 73   if (obj == null) return;
 74   if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
 75     obj.forEach(iterator);
 76   } else if (obj.length === +obj.length) {
 77     for (var i = 0, l = obj.length; i < l; i++) {
 78       iterator.call(undefined, obj[i], i, obj);
 79     }
 80   } else {
 81     for (var key in obj) {
 82       if (Object.prototype.hasOwnProperty.call(obj, key)) {
 83         iterator.call(undefined, obj[key], key, obj);
 84       }
 85     }
 86   }
 87 
 88   return child;
 89 };
 90 
 91 /**
 92  * @static
 93  * @param value A value.
 94  * @param array An array.
 95  * @returns {Boolean} Whether value exists in the array.
 96  */
 97 AjaxSolr.inArray = function (value, array) {
 98   if (array) {
 99     for (var i = 0, l = array.length; i < l; i++) {
100       if (AjaxSolr.equals(array[i], value)) {
101         return i;
102       }
103     }
104   }
105   return -1;
106 };
107 
108 /**
109  * @static
110  * @param foo A value.
111  * @param bar A value.
112  * @returns {Boolean} Whether the two given values are equal.
113  */
114 AjaxSolr.equals = function (foo, bar) {
115   if (AjaxSolr.isArray(foo) && AjaxSolr.isArray(bar)) {
116     if (foo.length !== bar.length) {
117       return false;
118     }
119     for (var i = 0, l = foo.length; i < l; i++) {
120       if (foo[i] !== bar[i]) {
121         return false;
122       }
123     }
124     return true;
125   }
126   else if (AjaxSolr.isRegExp(foo) && AjaxSolr.isString(bar)) {
127     return bar.match(foo);
128   }
129   else if (AjaxSolr.isRegExp(bar) && AjaxSolr.isString(foo)) {
130     return foo.match(bar);
131   }
132   else {
133     return foo === bar;
134   }
135 };
136 
137 /**
138  * Can't use toString.call(obj) === "[object Array]", as it may return
139  * "[xpconnect wrapped native prototype]", which is undesirable.
140  *
141  * @static
142  * @see http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
143  * @see https://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js
144  */
145 AjaxSolr.isArray = function (obj) {
146   return obj != null && typeof obj == 'object' && 'splice' in obj && 'join' in obj;
147 };
148 
149 /**
150  * @param obj Any object.
151  * @returns {Boolean} Whether the object is a RegExp object.
152  */
153 AjaxSolr.isRegExp = function (obj) {
154   return obj != null && (typeof obj == 'object' || typeof obj == 'function') && 'ignoreCase' in obj;
155 };
156 
157 /**
158  * @param obj Any object.
159  * @returns {Boolean} Whether the object is a String object.
160  */
161 AjaxSolr.isString = function (obj) {
162   return obj != null && typeof obj == 'string';
163 };
164