1 /**
  2  * All content on this website (including text, images, source
  3  * code and any other original works), unless otherwise noted,
  4  * is licensed under a Creative Commons License.
  5  * 
  6  * http://creativecommons.org/licenses/by-nc-sa/2.5/
  7  * 
  8  * Copyright (C) 2009 Open-Xchange, Inc.
  9  * Mail: info@open-xchange.com 
 10  * 
 11  * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 12  */
 13 
 14 /**
 15  * Creates the prototype object of a subclass.
 16  * @param {Function} parent The constructor function of the superclass.
 17  * @param {Object} prototype The prototype object of the subclass, containing
 18  * only new and overridden members.
 19  * @type Object
 20  * @return The prototype object with all inherited members added to it.
 21  */
 22 function extend(parent, prototype) {
 23     for (var i in parent.prototype)
 24         if (!(i in prototype)) prototype[i] = parent.prototype[i];
 25     return prototype;
 26 }
 27 
 28 /**
 29  * Empty function. Does nothing.
 30  */
 31 function emptyFunction() {}
 32 
 33 /**
 34  * Identity function. Returns its first parameter.
 35  */
 36 function identity(x) { return x; }
 37 
 38 /**
 39  * Constant function.
 40  * Returns a new function which returns the first parameter of this function.
 41  * @param x
 42  * @type Function
 43  * @return A function which returns x.
 44  */
 45 function constant(x) { return function() { return x; }; }
 46 
 47 /**
 48  * Returns whether an object is empty.
 49  * @param {Object} x The tested object
 50  * @type Boolean
 51  * @return True if the object does not have enumerable properties,
 52  * false otherwise.
 53  */
 54 function isEmpty(x) {
 55     for (var i in x) return false;
 56     return true;
 57 }
 58 
 59 /** @ignore */
 60 function assert(value) { if (!value) alert("Assertion failed"); }
 61 
 62 /**
 63  * Internet Explorer version number, or undefined if using a real browser.
 64  * Since comparisons with undefined always return false, checks involving this
 65  * variable should use the "<" or "<=" operators, e. g. "if (IE < 8)".
 66  */
 67 var IE = (navigator.appName != "Microsoft Internet Explorer") ? undefined
 68     : Number(navigator.appVersion.match(/MSIE (\d+\.\d+)/)[1]);
 69 
 70 /**
 71  * Boolean indicating the MacOS platform. If true, selections use the Meta key
 72  * instead of the Ctrl key.
 73  */
 74 var Mac = navigator.platform.substring(0, 3) == "Mac";
 75 
 76 /**
 77  * Creates a function which can add or remove a CSS class to a DOM node.
 78  * When adding, a class name is not duplicated if already present.
 79  * When removing, all instances of a class name are removed if present multiple
 80  * times.
 81  * @param {String} name The class name to add or remove. It must not contain any
 82  * characters which have special meaning in regular expressions.
 83  * @type Function
 84  * @return A function which accepts two parameters:<ul> 
 85  * <li>{DOM node} node The DOM node to which the class name is applied.</li>
 86  * <li>{Boolean} set Whether the class name should be added (true) or
 87  * removed (false).</li>
 88  * @ignore
 89  */
 90 function classNameSetter(name) {
 91     var regex = new RegExp("(\\s)\\s*" + name + "\\s+|\\s*" + name + "\\s*",
 92                            "g");
 93     return function (node, set) {
 94         var c = String(node.className);
 95         regex.lastIndex = 0;
 96         if (set) {
 97             if (!regex.test(c)) c = c ? c + " " + name : name;
 98         } else {
 99             c = c.replace(regex, "$1");
100         }
101         node.className = c;
102         return c;
103     };
104 }
105