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