xref: /dokuwiki/lib/scripts/helpers.js (revision 7531aa81784e6c7ff828732e1636223a1086faf4)
105835ea2SAndreas Gohr/**
226fc53c6SAndreas Gohr * Various helper functions
305835ea2SAndreas Gohr */
426fc53c6SAndreas Gohr
5d00ec455SAndreas Gohr/**
6c949174aSAdrian Lang * A PHP-style substr_replace
7c949174aSAdrian Lang *
8c949174aSAdrian Lang * Supports negative start and length and omitting length, but not
9c949174aSAdrian Lang * str and replace arrays.
10c949174aSAdrian Lang * See http://php.net/substr-replace for further documentation.
11c949174aSAdrian Lang */
12c949174aSAdrian Langfunction substr_replace(str, replace, start, length) {
13c949174aSAdrian Lang    var a2, b1;
14c949174aSAdrian Lang    a2 = (start < 0 ? str.length : 0) + start;
15c949174aSAdrian Lang    if (typeof length === 'undefined') {
16c949174aSAdrian Lang        length = str.length - a2;
17c949174aSAdrian Lang    } else if (length < 0 && start < 0 && length <= start) {
18c949174aSAdrian Lang        length = 0;
19c949174aSAdrian Lang    }
20c949174aSAdrian Lang    b1 = (length < 0 ? str.length : a2) + length;
21c949174aSAdrian Lang    return str.substring(0, a2) + replace + str.substring(b1);
22c949174aSAdrian Lang}
23b2a330caSAndreas Gohr
24b2a330caSAndreas Gohr/**
25b2a330caSAndreas Gohr * Bind variables to a function call creating a closure
26b2a330caSAndreas Gohr *
27b2a330caSAndreas Gohr * Use this to circumvent variable scope problems when creating closures
28b2a330caSAndreas Gohr * inside a loop
29b2a330caSAndreas Gohr *
30b2a330caSAndreas Gohr * @author  Adrian Lang <[email protected]>
31b2a330caSAndreas Gohr * @link    http://www.cosmocode.de/en/blog/gohr/2009-10/15-javascript-fixing-the-closure-scope-in-loops
32b2a330caSAndreas Gohr * @param   functionref fnc - the function to be called
33b2a330caSAndreas Gohr * @param   mixed - any arguments to be passed to the function
34b2a330caSAndreas Gohr * @returns functionref
35b2a330caSAndreas Gohr */
36b2a330caSAndreas Gohrfunction bind(fnc/*, ... */) {
37cb42e5f1SAdrian Lang    var Aps = Array.prototype.slice,
38b2a330caSAndreas Gohr    // Store passed arguments in this scope.
39b2a330caSAndreas Gohr    // Since arguments is no Array nor has an own slice method,
40b2a330caSAndreas Gohr    // we have to apply the slice method from the Array.prototype
41cb42e5f1SAdrian Lang        static_args = Aps.call(arguments, 1);
42b2a330caSAndreas Gohr
43b2a330caSAndreas Gohr    // Return a function evaluating the passed function with the
44b2a330caSAndreas Gohr    // given args and optional arguments passed on invocation.
45b2a330caSAndreas Gohr    return function (/* ... */) {
46b2a330caSAndreas Gohr        // Same here, but we use Array.prototype.slice solely for
47b2a330caSAndreas Gohr        // converting arguments to an Array.
48b2a330caSAndreas Gohr        return fnc.apply(this,
49b2a330caSAndreas Gohr                         static_args.concat(Aps.call(arguments, 0)));
50b2a330caSAndreas Gohr    };
51b2a330caSAndreas Gohr}
526b0ec830SMichael Hamann
536b0ec830SMichael Hamann/**
546b0ec830SMichael Hamann * Report an error from a JS file to the console
556b0ec830SMichael Hamann *
566b0ec830SMichael Hamann * @param e    The error object
576b0ec830SMichael Hamann * @param file The file in which the error occurred
586b0ec830SMichael Hamann */
596b0ec830SMichael Hamannfunction logError(e, file) {
606b0ec830SMichael Hamann    if (window.console && console.error) {
616b0ec830SMichael Hamann        console.error('The error "%s: %s" occurred in file "%s". ' +
626b0ec830SMichael Hamann            'If this is in a plugin try updating or disabling the plugin, ' +
63c6f665ddSMichael Hamann            'if this is in a template try updating the template or switching to the "dokuwiki" template.',
646b0ec830SMichael Hamann            e.name, e.message, file);
65*7531aa81SAndreas Gohr        if(e.stack) {
66*7531aa81SAndreas Gohr            console.error(e.stack);
67*7531aa81SAndreas Gohr        }
686b0ec830SMichael Hamann    }
696b0ec830SMichael Hamann}
70