1 // $Id$ 2 3 /** 4 * @namespace A unique namespace for the AJAX Solr library. 5 */ 6 AjaxSolr = function () {}; 7 8 /** 9 * @namespace Baseclass for all classes 10 */ 11 AjaxSolr.Class = function () {}; 12 13 /** 14 * A class 'extends' itself into a subclass. 15 * 16 * @static 17 * @param properties The properties of the subclass. 18 * @returns A function that represents the subclass. 19 */ 20 AjaxSolr.Class.extend = function (properties) { 21 var klass = this; // Safari dislikes 'class' 22 // The subclass is just a function that when called, instantiates itself. 23 // Nothing is _actually_ shared between _instances_ of the same class. 24 var subClass = function (options) { 25 // 'this' refers to the subclass, which starts life as an empty object. 26 // Add its parent's properties, its own properties, and any passed options. 27 AjaxSolr.extend(this, new klass(options), properties, options); 28 } 29 // Allow the subclass to extend itself into further subclasses. 30 subClass.extend = this.extend; 31 return subClass; 32 }; 33 34 /** 35 * @static 36 * @param {Object} obj Any object. 37 * @returns {Number} the number of properties on an object. 38 * @see http://stackoverflow.com/questions/5223/length-of-javascript-associative-array 39 */ 40 AjaxSolr.size = function (obj) { 41 var size = 0; 42 for (var key in obj) { 43 if (obj.hasOwnProperty(key)) { 44 size++; 45 } 46 } 47 return size; 48 }; 49 50 /** 51 * @static 52 * @param foo A value. 53 * @param bar A value. 54 * @returns {Boolean} Whether the two given values are equal. 55 */ 56 AjaxSolr.equals = function (foo, bar) { 57 if (AjaxSolr.isArray(foo) && AjaxSolr.isArray(bar)) { 58 if (foo.length !== bar.length) { 59 return false; 60 } 61 for (var i = 0, l = foo.length; i < l; i++) { 62 if (foo[i] !== bar[i]) { 63 return false; 64 } 65 } 66 return true; 67 } 68 else if (AjaxSolr.isRegExp(foo) && AjaxSolr.isString(bar)) { 69 return bar.match(foo); 70 } 71 else if (AjaxSolr.isRegExp(bar) && AjaxSolr.isString(foo)) { 72 return foo.match(bar); 73 } 74 else { 75 return foo === bar; 76 } 77 }; 78 79 /** 80 * @static 81 * @param value A value. 82 * @param array An array. 83 * @returns {Boolean} Whether value exists in the array. 84 */ 85 AjaxSolr.inArray = function (value, array) { 86 if (array) { 87 for (var i = 0, l = array.length; i < l; i++) { 88 if (AjaxSolr.equals(array[i], value)) { 89 return i; 90 } 91 } 92 } 93 return -1; 94 }; 95 96 /** 97 * A copy of MooTools' Array.flatten function. 98 * 99 * @static 100 * @see http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools.js 101 */ 102 AjaxSolr.flatten = function(array) { 103 var ret = []; 104 for (var i = 0, l = array.length; i < l; i++) { 105 ret = ret.concat(AjaxSolr.isArray(array[i]) ? AjaxSolr.flatten(array[i]) : array[i]); 106 } 107 return ret; 108 }; 109 110 /** 111 * A copy of jQuery's jQuery.grep function. 112 * 113 * @static 114 * @see http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js 115 */ 116 AjaxSolr.grep = function(array, callback) { 117 var ret = []; 118 for (var i = 0, l = array.length; i < l; i++) { 119 if (!callback(array[i], i) === false) { 120 ret.push(array[i]); 121 } 122 } 123 return ret; 124 } 125 126 /** 127 * Equivalent to Ruby's Array#compact. 128 */ 129 AjaxSolr.compact = function(array) { 130 return AjaxSolr.grep(array, function (item) { 131 return item.toString(); 132 }); 133 } 134 135 /** 136 * Can't use toString.call(obj) === "[object Array]", as it may return 137 * "[xpconnect wrapped native prototype]", which is undesirable. 138 * 139 * @static 140 * @see http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ 141 * @see http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js 142 */ 143 AjaxSolr.isArray = function (obj) { 144 return obj != null && typeof obj == 'object' && 'splice' in obj && 'join' in obj; 145 }; 146 147 /** 148 * @param obj Any object. 149 * @returns {Boolean} Whether the object is a RegExp object. 150 */ 151 AjaxSolr.isRegExp = function (obj) { 152 return obj != null && (typeof obj == 'object' || typeof obj == 'function') && 'ignoreCase' in obj; 153 }; 154 155 /** 156 * @param obj Any object. 157 * @returns {Boolean} Whether the object is a String object. 158 */ 159 AjaxSolr.isString = function (obj) { 160 return obj != null && typeof obj == 'string'; 161 }; 162 163 /** 164 * Define theme functions to separate, as much as possible, your HTML from your 165 * JavaScript. Theme functions provided by AJAX Solr are defined in the 166 * AjaxSolr.theme.prototype namespace, e.g. AjaxSolr.theme.prototype.select_tag. 167 * 168 * To override a theme function provided by AJAX Solr, define a function of the 169 * same name in the AjaxSolr.theme namespace, e.g. AjaxSolr.theme.select_tag. 170 * 171 * To retrieve the HTML output by AjaxSolr.theme.prototype.select_tag(...), call 172 * AjaxSolr.theme('select_tag', ...). 173 * 174 * @param {String} func 175 * The name of the theme function to call. 176 * @param ... 177 * Additional arguments to pass along to the theme function. 178 * @returns 179 * Any data the theme function returns. This could be a plain HTML string, 180 * but also a complex object. 181 * 182 * @static 183 * @throws Exception if the theme function is not defined. 184 * @see http://cvs.drupal.org/viewvc.py/drupal/drupal/misc/drupal.js?revision=1.58 185 */ 186 AjaxSolr.theme = function (func) { 187 if (AjaxSolr.theme[func] || AjaxSolr.theme.prototype[func] == undefined) { 188 console.log('Theme function "' + func + '" is not defined.'); 189 } 190 else { 191 for (var i = 1, args = []; i < arguments.length; i++) { 192 args.push(arguments[i]); 193 } 194 return (AjaxSolr.theme[func] || AjaxSolr.theme.prototype[func]).apply(this, args); 195 } 196 }; 197 198 /** 199 * A simplified version of jQuery's extend function. 200 * 201 * @static 202 * @see http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js 203 */ 204 AjaxSolr.extend = function () { 205 var target = arguments[0] || {}, i = 1, length = arguments.length, options; 206 for (; i < length; i++) { 207 if ((options = arguments[i]) != null) { 208 for (var name in options) { 209 var src = target[name], copy = options[name]; 210 if (target === copy) { 211 continue; 212 } 213 if (copy && typeof copy == 'object' && !copy.nodeType) { 214 target[name] = AjaxSolr.extend(src || (copy.length != null ? [] : {}), copy); 215 } 216 else if (copy && src && typeof copy == 'function' && typeof src == 'function') { 217 target[name] = (function(superfn, fn) { 218 return function () { 219 var tmp = this._super, ret; 220 this._super = superfn; 221 ret = fn.apply(this, arguments); 222 this._super = tmp; 223 return ret; 224 }; 225 })(src, copy); 226 } 227 else if (copy !== undefined) { 228 target[name] = copy; 229 } 230 } 231 } 232 } 233 return target; 234 }; 235