1/** 2 * Differrent helper functions 3 * 4 * @author Ilya Lebedev <ilya@lebedev.net> 5 * @license LGPL 6 */ 7//----------------------------------------------------------------------------- 8// Variable/property checks 9//----------------------------------------------------------------------------- 10/** 11 * Checks if property is undefined 12 * 13 * @param {Object} prop value to check 14 * @return {Boolean} true if matched 15 * @scope public 16 */ 17function isUndefined (prop /* :Object */) /* :Boolean */ { 18 return (typeof prop == 'undefined'); 19} 20/** 21 * Checks if property is function 22 * 23 * @param {Object} prop value to check 24 * @return {Boolean} true if matched 25 * @scope public 26 */ 27function isFunction (prop /* :Object */) /* :Boolean */ { 28 return (typeof prop == 'function'); 29} 30/** 31 * Checks if property is string 32 * 33 * @param {Object} prop value to check 34 * @return {Boolean} true if matched 35 * @scope public 36 */ 37function isString (prop /* :Object */) /* :Boolean */ { 38 return (typeof prop == 'string'); 39} 40/** 41 * Checks if property is number 42 * 43 * @param {Object} prop value to check 44 * @return {Boolean} true if matched 45 * @scope public 46 */ 47function isNumber (prop /* :Object */) /* :Boolean */ { 48 return (typeof prop == 'number'); 49} 50/** 51 * Checks if property is the calculable number 52 * 53 * @param {Object} prop value to check 54 * @return {Boolean} true if matched 55 * @scope public 56 */ 57function isNumeric (prop /* :Object */) /* :Boolean */ { 58 return isNumber(prop)&&!isNaN(prop)&&isFinite(prop); 59} 60/** 61 * Checks if property is array 62 * 63 * @param {Object} prop value to check 64 * @return {Boolean} true if matched 65 * @scope public 66 */ 67function isArray (prop /* :Object */) /* :Boolean */ { 68 return (prop instanceof Array); 69} 70/** 71 * Checks if property is regexp 72 * 73 * @param {Object} prop value to check 74 * @return {Boolean} true if matched 75 * @scope public 76 */ 77function isRegExp (prop /* :Object */) /* :Boolean */ { 78 return (prop instanceof RegExp); 79} 80/** 81 * Checks if property is a boolean value 82 * 83 * @param {Object} prop value to check 84 * @return {Boolean} true if matched 85 * @scope public 86 */ 87function isBoolean (prop /* :Object */) /* :Boolean */ { 88 return ('boolean' == typeof prop); 89} 90/** 91 * Checks if property is a scalar value (value that could be used as the hash key) 92 * 93 * @param {Object} prop value to check 94 * @return {Boolean} true if matched 95 * @scope public 96 */ 97function isScalar (prop /* :Object */) /* :Boolean */ { 98 return isNumeric(prop)||isString(prop); 99} 100/** 101 * Checks if property is empty 102 * 103 * @param {Object} prop value to check 104 * @return {Boolean} true if matched 105 * @scope public 106 */ 107function isEmpty (prop /* :Object */) /* :Boolean */ { 108 if (isBoolean(prop)) return false; 109 if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) return true; 110 if (isString(prop) || isNumber(prop)) return !prop; 111 if (Boolean(prop)&&false != prop) { 112 for (var i in prop) if(prop.hasOwnProperty(i)) return false; 113 } 114 return true; 115} 116 117/** 118 * Checks if property is derived from prototype, applies method if it is not exists 119 * 120 * @param string property name 121 * @return bool true if prototyped 122 * @access public 123 */ 124if ('undefined' == typeof Object.hasOwnProperty) { 125 Object.prototype.hasOwnProperty = function (prop) { 126 return !('undefined' == typeof this[prop] || this.constructor && this.constructor.prototype[prop] && this[prop] === this.constructor.prototype[prop]); 127 }; 128} 129 130/** 131 * Very simplistic Flash plugin check, probably works for Flash 8 and higher only 132 */ 133function hasFlash(version){ 134 var ver = 0; 135 try{ 136 if(navigator.plugins != null && navigator.plugins.length > 0){ 137 ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0]; 138 }else{ 139 var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); 140 ver = axo.GetVariable("$version").split(' ')[1].split(',')[0]; 141 } 142 }catch(e){ } 143 144 if(ver >= version) return true; 145 return false; 146} 147 148/** 149 * A PHP-style substr_replace 150 * 151 * Supports negative start and length and omitting length, but not 152 * str and replace arrays. 153 * See http://php.net/substr-replace for further documentation. 154 */ 155function substr_replace(str, replace, start, length) { 156 var a2, b1; 157 a2 = (start < 0 ? str.length : 0) + start; 158 if (typeof length === 'undefined') { 159 length = str.length - a2; 160 } else if (length < 0 && start < 0 && length <= start) { 161 length = 0; 162 } 163 b1 = (length < 0 ? str.length : a2) + length; 164 return str.substring(0, a2) + replace + str.substring(b1); 165} 166 167/** 168 * Bind variables to a function call creating a closure 169 * 170 * Use this to circumvent variable scope problems when creating closures 171 * inside a loop 172 * 173 * @author Adrian Lang <lang@cosmocode.de> 174 * @link http://www.cosmocode.de/en/blog/gohr/2009-10/15-javascript-fixing-the-closure-scope-in-loops 175 * @param functionref fnc - the function to be called 176 * @param mixed - any arguments to be passed to the function 177 * @returns functionref 178 */ 179function bind(fnc/*, ... */) { 180 var Aps = Array.prototype.slice; 181 // Store passed arguments in this scope. 182 // Since arguments is no Array nor has an own slice method, 183 // we have to apply the slice method from the Array.prototype 184 var static_args = Aps.call(arguments, 1); 185 186 // Return a function evaluating the passed function with the 187 // given args and optional arguments passed on invocation. 188 return function (/* ... */) { 189 // Same here, but we use Array.prototype.slice solely for 190 // converting arguments to an Array. 191 return fnc.apply(this, 192 static_args.concat(Aps.call(arguments, 0))); 193 }; 194} 195