xref: /dokuwiki/lib/scripts/compatibility.js (revision 7cb9c0e3233fdc295a05e410a1d7a731301bc2da)
1/**
2 * Mark a JavaScript function as deprecated
3 *
4 * This will print a warning to the JavaScript console (if available) in
5 * Firebug and Chrome and a stack trace (if available) to easily locate the
6 * problematic function call.
7 *
8 * @param msg optional message to print
9 */
10function DEPRECATED(msg){
11    if(!window.console) return;
12    if(!msg) msg = '';
13
14    var func;
15    if(arguments.callee) func = arguments.callee.caller.name;
16    if(func) func = ' '+func+'()';
17    var line = 'DEPRECATED function call'+func+'. '+msg;
18
19    if(console.warn){
20        console.warn(line);
21    }else{
22        console.log(line);
23    }
24
25    if(console.trace) console.trace();
26}
27
28/**
29 * Construct a wrapper function for deprecated function names
30 *
31 * This function returns a wrapper function which just calls DEPRECATED
32 * and the new function.
33 *
34 * @param func    The new function
35 * @param context Optional; The context (`this`) of the call
36 */
37function DEPRECATED_WRAP(func, context) {
38    return function () {
39        DEPRECATED();
40        return func.apply(context || this, arguments);
41    };
42}
43
44/**
45 * Handy shortcut to document.getElementById
46 *
47 * This function was taken from the prototype library
48 *
49 * @link http://prototype.conio.net/
50 */
51function $() {
52    DEPRECATED('Please use the JQuery() function instead.');
53
54    var elements = new Array();
55
56    for (var i = 0; i < arguments.length; i++) {
57        var element = arguments[i];
58        if (typeof element == 'string')
59            element = document.getElementById(element);
60
61        if (arguments.length == 1)
62            return element;
63
64        elements.push(element);
65    }
66
67    return elements;
68}
69
70
71
72
73var index = {
74    throbber_delay: dw_index.throbber_delay,
75    toggle: DEPRECATED_WRAP(dw_index.toggle, dw_index),
76    treeattach: DEPRECATED_WRAP(dw_index.treeattach, dw_index)
77};
78
79var ajax_quicksearch = {
80    init: DEPRECATED_WRAP(dw_qsearch.init, dw_qsearch),
81    clear_results: DEPRECATED_WRAP(dw_qsearch.clear_results, dw_qsearch),
82    onCompletion: DEPRECATED_WRAP(dw_qsearch.onCompletion, dw_qsearch)
83};
84
85var linkwiz = {
86    init: DEPRECATED_WRAP(dw_linkwiz.init, dw_linkwiz),
87    onEntry: DEPRECATED_WRAP(dw_linkwiz.onEntry, dw_linkwiz),
88    getResult: DEPRECATED_WRAP(dw_linkwiz.getResult, dw_linkwiz),
89    select: DEPRECATED_WRAP(dw_linkwiz.select, dw_linkwiz),
90    deselect: DEPRECATED_WRAP(dw_linkwiz.deselect, dw_linkwiz),
91    onResultClick: DEPRECATED_WRAP(dw_linkwiz.onResultClick, dw_linkwiz),
92    resultClick: DEPRECATED_WRAP(dw_linkwiz.resultClick, dw_linkwiz),
93    insertLink: DEPRECATED_WRAP(dw_linkwiz.insertLink, dw_linkwiz),
94    autocomplete: DEPRECATED_WRAP(dw_linkwiz.autocomplete, dw_linkwiz),
95    autocomplete_exec: DEPRECATED_WRAP(dw_linkwiz.autocomplete_exec, dw_linkwiz),
96    show: DEPRECATED_WRAP(dw_linkwiz.show, dw_linkwiz),
97    hide: DEPRECATED_WRAP(dw_linkwiz.hide, dw_linkwiz),
98    toggle: DEPRECATED_WRAP(dw_linkwiz.toggle, dw_linkwiz)
99};
100
101var locktimer = {
102    init: DEPRECATED_WRAP(dw_locktimer.init, dw_locktimer),
103    reset: DEPRECATED_WRAP(dw_locktimer.reset, dw_locktimer),
104    warning: DEPRECATED_WRAP(dw_locktimer.warning, dw_locktimer),
105    clear: DEPRECATED_WRAP(dw_locktimer.clear, dw_locktimer),
106    refresh: DEPRECATED_WRAP(dw_locktimer.refresh, dw_locktimer),
107    refreshed: DEPRECATED_WRAP(dw_locktimer.refreshed, dw_locktimer)
108};
109
110var media_manager = {
111    // treeattach, selectorattach, confirmattach are munched together into
112    // dw_mediamanager.init
113    attachoptions: DEPRECATED_WRAP(dw_mediamanager.attachoptions, dw_mediamanager),
114    togglekeepopen: function (event, cb) {
115        DEPRECATED('Use dw_mediamanager.toggleOption instead');
116        return dw_mediamanager.toggleOption.call(cb, 'keepopen');
117    },
118    togglehide: function (event, cb) {
119        DEPRECATED('Use dw_mediamanager.toggleOption instead');
120        return dw_mediamanager.toggleOption.call(cb, 'hide');
121    },
122    updatehide: DEPRECATED_WRAP(dw_mediamanager.updatehide, dw_mediamanager),
123    select: function (event, link) {
124        DEPRECATED('Use dw_mediamanager.select instead');
125        return dw_mediamanager.select.call(link, event);
126    },
127    initpopup: DEPRECATED_WRAP(dw_mediamanager.initpopup, dw_mediamanager),
128    insert: DEPRECATED_WRAP(dw_mediamanager.insert, dw_mediamanager),
129    list: function (event, link) {
130        DEPRECATED('Use dw_mediamanager.list instead');
131        return dw_mediamanager.list.call(link, event);
132    },
133    // toggle is handled by dw_tree
134    suggest: DEPRECATED_WRAP(dw_mediamanager.suggest, dw_mediamanager),
135    initFlashUpload: DEPRECATED_WRAP(dw_mediamanager.initFlashUpload, dw_mediamanager),
136    closePopup: function () {
137        DEPRECATED();
138        dw_mediamanager.$popup.dialog('close');
139    },
140    setalign: function (event, cb) {
141        DEPRECATED('Use dw_mediamanager.setOpt instead');
142        return dw_mediamanager.setOpt.call(this, 'align', event);
143    },
144    setlink: function (event, cb) {
145        DEPRECATED('Use dw_mediamanager.setOpt instead');
146        return dw_mediamanager.setOpt.call(this, 'link', event);
147    },
148    setsize: function (event, cb) {
149        DEPRECATED('Use dw_mediamanager.setOpt instead');
150        return dw_mediamanager.setOpt.call(this, 'size', event);
151    },
152    outSet: function (id) {
153        DEPRECATED();
154        return jQuery(id).removeClass('selected');
155    },
156    inSet: function (id) {
157        DEPRECATED();
158        return jQuery(id).addClass('selected');
159    }
160};
161
162initSizeCtl = DEPRECATED_WRAP(dw_editor.initSizeCtl);
163sizeCtl = DEPRECATED_WRAP(dw_editor.sizeCtl);
164toggleWrap = DEPRECATED_WRAP(dw_editor.toggleWrap);
165setWrap = DEPRECATED_WRAP(dw_editor.setWrap);
166
167function findPosX(object){
168    DEPRECATED('Use jQuery.position() instead');
169    return jQuery(object).position().left;
170}
171
172function findPosY(object){
173    DEPRECATED('Use jQuery.position() instead');
174    return jQuery(object).position().top;
175}
176
177function getElementsByClass(searchClass,node,tag){
178    DEPRECATED('Use jQuery() instead');
179    if(node == null) node = document;
180    if(typeof tag === 'undefined') tag = '';
181    return jQuery(node).find(tag+'.'+searchClass).toArray();
182}
183
184function prependChild(parent,element) {
185    DEPRECATED('Use jQuery.prepend() instead');
186    jQuery(parent).prepend(element);
187}
188
189function addEvent(element, type, handler) {
190    DEPRECATED('Use jQuery.bind() instead. Note that jQuery’s behaviour' +
191               ' when a handler returns false differs from addEvent’s');
192    jQuery(element).bind(type,{},function (e) {
193        // returning false in an addEvent event handler did not prevent
194        // bubbling but just canceled handlers on this node and prevented
195        // default behavior, so wrap the handler call and mimic that behavior.
196        //
197        // Refer to jQuery.event.handle().
198        var ret = handler.apply(this, Array.prototype.slice.call(arguments, 0));
199        if (typeof ret !== 'undefined') {
200            if ( ret !== false ) {
201                return ret;
202            }
203            // What jQuery does.
204            e.result = ret;
205            e.preventDefault();
206            // Not what jQuery does. This would be: event.stopPropagation();
207            // Hack it so that immediate propagation (other event handlers on
208            // this element) appears stopped without stopping the actual
209            // propagation (bubbling)
210            e.isImmediatePropagationStopped = function () { return true; };
211        }
212    });
213}
214
215function removeEvent(element, type, handler) {
216    DEPRECATED('Use jQuery.unbind() instead.');
217    jQuery(element).unbind(type,handler);
218}
219
220function addInitEvent(func) {
221    DEPRECATED('Use jQuery(<function>) instead');
222    jQuery(func);
223}
224
225
226function jsEscape(text){
227    DEPRECATED('Insert text through jQuery.text() instead of escaping on your own');
228    var re=new RegExp("\\\\","g");
229    text=text.replace(re,"\\\\");
230    re=new RegExp("'","g");
231    text=text.replace(re,"\\'");
232    re=new RegExp('"',"g");
233    text=text.replace(re,'&quot;');
234    re=new RegExp("\\\\\\\\n","g");
235    text=text.replace(re,"\\n");
236    return text;
237}
238
239/**
240 * Simple function to check if a global var is defined
241 *
242 * @author Kae Verens
243 * @link http://verens.com/archives/2005/07/25/isset-for-javascript/#comment-2835
244 */
245function isset(varname){
246    DEPRECATED("Use `typeof var !== 'undefined'` instead");
247    return(typeof(window[varname])!='undefined');
248}
249
250/**
251 * Checks if property is undefined
252 *
253 * @param {Object} prop value to check
254 * @return {Boolean} true if matched
255 * @scope public
256 * @author Ilya Lebedev <ilya@lebedev.net>
257 */
258function isUndefined (prop /* :Object */) /* :Boolean */ {
259    DEPRECATED("Use `typeof var === 'undefined'` instead");
260    return (typeof prop == 'undefined');
261}
262
263/**
264 * Checks if property is function
265 *
266 * @param {Object} prop value to check
267 * @return {Boolean} true if matched
268 * @scope public
269 * @author Ilya Lebedev <ilya@lebedev.net>
270 */
271function isFunction (prop /* :Object */) /* :Boolean */ {
272    DEPRECATED("Use `typeof var === 'function'` instead");
273    return (typeof prop == 'function');
274}
275/**
276 * Checks if property is string
277 *
278 * @param {Object} prop value to check
279 * @return {Boolean} true if matched
280 * @scope public
281 * @author Ilya Lebedev <ilya@lebedev.net>
282 */
283function isString (prop /* :Object */) /* :Boolean */ {
284    DEPRECATED("Use `typeof var === 'string'` instead");
285    return (typeof prop == 'string');
286}
287
288/**
289 * Checks if property is number
290 *
291 * @param {Object} prop value to check
292 * @return {Boolean} true if matched
293 * @scope public
294 * @author Ilya Lebedev <ilya@lebedev.net>
295 */
296function isNumber (prop /* :Object */) /* :Boolean */ {
297    DEPRECATED("Use `typeof var === 'number'` instead");
298    return (typeof prop == 'number');
299}
300
301/**
302 * Checks if property is the calculable number
303 *
304 * @param {Object} prop value to check
305 * @return {Boolean} true if matched
306 * @scope public
307 * @author Ilya Lebedev <ilya@lebedev.net>
308 */
309function isNumeric (prop /* :Object */) /* :Boolean */ {
310    DEPRECATED("Use `typeof var === 'number' && !isNaN(var) && isFinite(var)` instead");
311    return isNumber(prop)&&!isNaN(prop)&&isFinite(prop);
312}
313
314/**
315 * Checks if property is array
316 *
317 * @param {Object} prop value to check
318 * @return {Boolean} true if matched
319 * @scope public
320 * @author Ilya Lebedev <ilya@lebedev.net>
321 */
322function isArray (prop /* :Object */) /* :Boolean */ {
323    DEPRECATED("Use `var instanceof Array` instead");
324    return (prop instanceof Array);
325}
326
327/**
328 *  Checks if property is regexp
329 *
330 * @param {Object} prop value to check
331 * @return {Boolean} true if matched
332 * @scope public
333 * @author Ilya Lebedev <ilya@lebedev.net>
334 */
335function isRegExp (prop /* :Object */) /* :Boolean */ {
336    DEPRECATED("Use `var instanceof RegExp` instead");
337    return (prop instanceof RegExp);
338}
339
340/**
341 * Checks if property is a boolean value
342 *
343 * @param {Object} prop value to check
344 * @return {Boolean} true if matched
345 * @scope public
346 * @author Ilya Lebedev <ilya@lebedev.net>
347 */
348function isBoolean (prop /* :Object */) /* :Boolean */ {
349    DEPRECATED("Use `typeof var === 'boolean'` instead");
350    return ('boolean' == typeof prop);
351}
352
353/**
354 * Checks if property is a scalar value (value that could be used as the hash key)
355 *
356 * @param {Object} prop value to check
357 * @return {Boolean} true if matched
358 * @scope public
359 * @author Ilya Lebedev <ilya@lebedev.net>
360 */
361function isScalar (prop /* :Object */) /* :Boolean */ {
362    DEPRECATED("Use `typeof var === 'string' || (typeof var === 'number' &&" +
363               " !isNaN(var) && isFinite(var))` instead");
364    return isNumeric(prop)||isString(prop);
365}
366
367/**
368 * Checks if property is empty
369 *
370 * @param {Object} prop value to check
371 * @return {Boolean} true if matched
372 * @scope public
373 * @author Ilya Lebedev <ilya@lebedev.net>
374 */
375function isEmpty (prop /* :Object */) /* :Boolean */ {
376    DEPRECATED();
377    var i;
378    if (isBoolean(prop)) {
379        return false;
380    } else if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) {
381        return true;
382    } else if (isString(prop) || isNumber(prop)) {
383        return !prop;
384    } else if (Boolean(prop) && false != prop) {
385        for (i in prop) {
386            if(prop.hasOwnProperty(i)) {
387                return false;
388            }
389        }
390    }
391    return true;
392}
393
394/**
395 * Get the computed style of a node.
396 *
397 * @link https://acidmartin.wordpress.com/2008/08/26/style-get-any-css-property-value-of-an-object/
398 * @link http://svn.dojotoolkit.org/src/dojo/trunk/_base/html.js
399 */
400function gcs(node){
401    DEPRECATED('Use jQuery(node).style() instead');
402    if(node.currentStyle){
403        return node.currentStyle;
404    }else{
405        return node.ownerDocument.defaultView.getComputedStyle(node, null);
406    }
407}
408
409/**
410 * Until 2011-05-25 "Rincewind", a code intended to fix some Safari issue
411 * always declared the global _timer. plugin:sortablejs relies on _timer
412 * being declared.
413 */
414var _timer;
415