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