xref: /dokuwiki/lib/scripts/helpers.js (revision 5b812846ce6a2e72e388adbb0dcaadbc0137b173)
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