reservation plugin - unbound request (unclean
[unfold.git] / portal / static / unbound_reservation_static / src / util.js
diff --git a/portal/static/unbound_reservation_static/src/util.js b/portal/static/unbound_reservation_static/src/util.js
new file mode 100644 (file)
index 0000000..a7fd49f
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * jsPlumb
+ * 
+ * Title:jsPlumb 1.5.5
+ * 
+ * Provides a way to visually connect elements on an HTML page, using either SVG or VML.  
+ * 
+ * This file contains the util functions
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ * 
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ * 
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+    var _isa = function(a) { return Object.prototype.toString.call(a) === "[object Array]"; },
+        _isnum = function(n) { return Object.prototype.toString.call(n) === "[object Number]"; },
+        _iss = function(s) { return typeof s === "string"; },
+        _isb = function(s) { return typeof s === "boolean"; },
+        _isnull = function(s) { return s == null; },  
+        _iso = function(o) { return o == null ? false : Object.prototype.toString.call(o) === "[object Object]"; },
+        _isd = function(o) { return Object.prototype.toString.call(o) === "[object Date]"; },
+        _isf = function(o) { return Object.prototype.toString.call(o) === "[object Function]"; },
+        _ise = function(o) {
+            for (var i in o) { if (o.hasOwnProperty(i)) return false; }
+            return true;
+        },
+        pointHelper = function(p1, p2, fn) {
+            p1 = _isa(p1) ? p1 : [p1.x, p1.y];
+            p2 = _isa(p2) ? p2 : [p2.x, p2.y];    
+            return fn(p1, p2);
+        };
+    
+    jsPlumbUtil = {        
+        isArray : _isa,        
+        isString : _iss,        
+        isBoolean: _isb,        
+        isNull : _isnull,        
+        isObject : _iso,
+        isDate : _isd,
+        isFunction: _isf,
+        isEmpty:_ise,
+        isNumber:_isnum,
+        clone : function(a) {
+            if (_iss(a)) return "" + a;
+            else if (_isb(a)) return !!a;
+            else if (_isd(a)) return new Date(a.getTime());
+            else if (_isf(a)) return a;
+            else if (_isa(a)) {
+                var b = [];
+                for (var i = 0; i < a.length; i++)
+                    b.push(this.clone(a[i]));
+                return b;
+            }
+            else if (_iso(a)) {
+                var c = {};
+                for (var j in a)
+                    c[j] = this.clone(a[j]);
+                return c;              
+            }
+            else return a;
+        },
+        merge : function(a, b) {               
+            var c = this.clone(a);             
+            for (var i in b) {
+                if (c[i] == null || _iss(b[i]) || _isb(b[i]))
+                    c[i] = b[i];
+                else {
+                    if (_isa(b[i])/* && this.isArray(c[i])*/) {
+                        var ar = [];
+                        // if c's object is also an array we can keep its values.
+                        if (_isa(c[i])) ar.push.apply(ar, c[i]);
+                        ar.push.apply(ar, b[i]);
+                        c[i] = ar;
+                    }
+                    else if(_iso(b[i])) {      
+                        // overwite c's value with an object if it is not already one.
+                        if (!_iso(c[i])) 
+                            c[i] = {};
+                        for (var j in b[i])
+                            c[i][j] = b[i][j];
+                    }
+                }
+            }
+            return c;
+        },
+        copyValues:function(names, from, to) {
+            for (var i = 0; i < names.length; i++)
+                to[names[i]] = from[names[i]];
+        },
+        //
+        // chain a list of functions, supplied by [ object, method name, args ], and return on the first
+        // one that returns the failValue. if none return the failValue, return the successValue.
+        //
+        functionChain : function(successValue, failValue, fns) {        
+            for (var i = 0; i < fns.length; i++) {
+                var o = fns[i][0][fns[i][1]].apply(fns[i][0], fns[i][2]);
+                if (o === failValue) {
+                    return o;
+                }
+            }                
+            return successValue;
+        },
+        // take the given model and expand out any parameters.
+        populate : function(model, values) {           
+            // for a string, see if it has parameter matches, and if so, try to make the substitutions.
+            var getValue = function(fromString) {
+                    var matches = fromString.match(/(\${.*?})/g);
+                    if (matches != null) {
+                        for (var i = 0; i < matches.length; i++) {
+                            var val = values[matches[i].substring(2, matches[i].length - 1)];
+                            if (val != null) {
+                                fromString = fromString.replace(matches[i], val);
+                            }
+                        }                                                      
+                    }
+                    return fromString;
+                },             
+                // process one entry.
+                _one = function(d) {
+                    if (d != null) {
+                        if (_iss(d)) {
+                            return getValue(d);
+                        }
+                        else if (_isa(d)) {
+                            var r = [];        
+                            for (var i = 0; i < d.length; i++)
+                                r.push(_one(d[i]));
+                            return r;
+                        }
+                        else if (_iso(d)) {
+                            var s = {};
+                            for (var j in d) {
+                                s[j] = _one(d[j]);
+                            }
+                            return s;
+                        }
+                        else {
+                            return d;
+                        }
+                    }
+                };
+            
+            return _one(model);        
+        },
+        convertStyle : function(s, ignoreAlpha) {
+            // TODO: jsPlumb should support a separate 'opacity' style member.
+            if ("transparent" === s) return s;
+            var o = s,
+                pad = function(n) { return n.length == 1 ? "0" + n : n; },
+                hex = function(k) { return pad(Number(k).toString(16)); },
+                pattern = /(rgb[a]?\()(.*)(\))/;
+            if (s.match(pattern)) {
+                var parts = s.match(pattern)[2].split(",");
+                o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
+                if (!ignoreAlpha && parts.length == 4) 
+                    o = o + hex(parts[3]);
+            }
+            return o;
+        },
+        findWithFunction : function(a, f) {
+            if (a)
+                for (var i = 0; i < a.length; i++) if (f(a[i])) return i;
+            return -1;
+        },
+        clampToGrid : function(x, y, grid, dontClampX, dontClampY) {
+            var _gridClamp = function(n, g) { 
+                var e = n % g, 
+                    f = Math.floor(n / g), 
+                    inc = e >= (g / 2) ? 1 : 0; 
+                return (f + inc) * g; 
+            };
+            return [
+                dontClampX || grid == null ? x : _gridClamp(x, grid[0]),
+                dontClampY || grid == null ? y : _gridClamp(y, grid[1])
+            ];         
+        },
+        indexOf : function(l, v) {
+            return jsPlumbUtil.findWithFunction(l, function(_v) { return _v == v; });  
+        },
+        removeWithFunction : function(a, f) {
+            var idx = jsPlumbUtil.findWithFunction(a, f);
+            if (idx > -1) a.splice(idx, 1);
+            return idx != -1;
+        },
+        remove : function(l, v) {
+            var idx = jsPlumbUtil.indexOf(l, v);       
+            if (idx > -1) l.splice(idx, 1);
+            return idx != -1;
+        },
+        // TODO support insert index
+        addWithFunction : function(list, item, hashFunction) {
+            if (jsPlumbUtil.findWithFunction(list, hashFunction) == -1) list.push(item);
+        },
+        addToList : function(map, key, value, insertAtStart) {
+            var l = map[key];
+            if (l == null) {
+                l = [];
+                map[key] = l;
+            }
+            l[insertAtStart ? "unshift" : "push"](value);
+            return l;
+        },
+        //
+        // extends the given obj (which can be an array) with the given constructor function, prototype functions, and
+        // class members, any of which may be null.
+        //
+        extend : function(child, parent, _protoFn, _protoAtts) {
+            _protoFn = _protoFn || {};
+            _protoAtts = _protoAtts || {};
+            parent = _isa(parent) ? parent : [ parent ];            
+
+            for (var i = 0; i < parent.length; i++) {
+                for (var j in parent[i].prototype) {
+                    if(parent[i].prototype.hasOwnProperty(j)) {
+                        child.prototype[j] = parent[i].prototype[j];
+                    }
+                }
+            }
+
+            var _makeFn = function(name) {
+                return function() {
+                    for (var i = 0; i < parent.length; i++) {
+                        if (parent[i].prototype[name])
+                            parent[i].prototype[name].apply(this, arguments);
+                    }                    
+                    return _protoFn[name].apply(this, arguments);
+                };
+            };
+
+            for (var k in _protoFn) {
+                child.prototype[k] = _makeFn(k);
+            }
+
+            return child;
+        },
+        uuid : function() {
+            return ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+                var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+                return v.toString(16);
+            }));
+        },
+        logEnabled : true,
+        log : function() {
+            if (jsPlumbUtil.logEnabled && typeof console != "undefined") {
+                try {
+                    var msg = arguments[arguments.length - 1];
+                    console.log(msg);
+                }
+                catch (e) {} 
+            }
+        },
+        group : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.group(g); },
+        groupEnd : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.groupEnd(g); },
+        time : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.time(t); },
+        timeEnd : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.timeEnd(t); },
+        
+        /**
+                * helper to remove an element from the DOM.
+                */
+               removeElement : function(element) {
+                       if (element != null && element.parentNode != null) {
+                               element.parentNode.removeChild(element);
+                       }
+               },
+        /**
+                * helper to remove a list of elements from the DOM.
+                */
+               removeElements : function(elements) {
+                       for ( var i = 0; i < elements.length; i++)
+                               jsPlumbUtil.removeElement(elements[i]);
+               },
+        /*
+         * Function: sizeElement 
+         * Helper to size and position an element. You would typically use
+         * this when writing your own Connector or Endpoint implementation.
+         * 
+         * Parameters: 
+         *  x - [int] x position for the element origin 
+         *  y - [int] y position for the element origin 
+         *  w - [int] width of the element 
+         *  h - [int] height of the element
+         *  
+         */
+        sizeElement : function(el, x, y, w, h) {
+            if (el) {
+                el.style.height = h + "px";
+                el.height = h;
+                el.style.width = w + "px";
+                el.width = w;
+                el.style.left = x + "px";
+                el.style.top = y + "px";
+            }
+        },
+        /**
+        * @name jsPlumbUtil.wrap
+        * @desc Wraps one function with another, creating a placeholder for the
+        * wrapped function if it was null. this is used to wrap the various
+        * drag/drop event functions - to allow jsPlumb to be notified of
+        * important lifecycle events without imposing itself on the user's
+        * drag/drop functionality. 
+        * @param {Function} wrappedFunction original function to wrap; may be null.
+        * @param {Function} newFunction function to wrap the original with.
+        * @param {Object} [returnOnThisValue] Optional. Indicates that the wrappedFunction should 
+        * not be executed if the newFunction returns a value matching 'returnOnThisValue'.
+        * note that this is a simple comparison and only works for primitives right now.
+        */        
+        wrap : function(wrappedFunction, newFunction, returnOnThisValue) {
+            wrappedFunction = wrappedFunction || function() { };
+            newFunction = newFunction || function() { };
+            return function() {
+                var r = null;
+                try {
+                    r = newFunction.apply(this, arguments);
+                } catch (e) {
+                    jsPlumbUtil.log("jsPlumb function failed : " + e);
+                }
+                if (returnOnThisValue == null || (r !== returnOnThisValue)) {
+                    try {
+                        r = wrappedFunction.apply(this, arguments);
+                    } catch (e) {
+                        jsPlumbUtil.log("wrapped function failed : " + e);
+                    }
+                }
+                return r;
+            };
+        }
+    };
+
+    
+    jsPlumbUtil.EventGenerator = function() {
+        var _listeners = {}, eventsSuspended = false;
+        
+        // this is a list of events that should re-throw any errors that occur during their dispatch. as of 1.3.0 this is private to
+        // jsPlumb, but it seems feasible that people might want to manipulate this list.  the thinking is that we don't want event
+        // listeners to bring down jsPlumb - or do we.  i can't make up my mind about this, but i know i want to hear about it if the "ready"
+        // event fails, because then my page has most likely not initialised.  so i have this halfway-house solution.  it will be interesting
+        // to hear what other people think.
+        var eventsToDieOn = [ "ready" ];
+                                        
+        this.bind = function(event, listener, insertAtStart) {
+            jsPlumbUtil.addToList(_listeners, event, listener, insertAtStart);     
+            return this;        
+        };
+                 
+        this.fire = function(event, value, originalEvent) {
+            if (!eventsSuspended && _listeners[event]) {
+                // instead of looping through the array we get a counter and a length, because it is possible
+                // that an event fired from here could cause the object to get cleaned up, which would throw
+                // away the listeners. so after each cycle through the loop we check to ensure we haven't
+                // been nuked.
+                var l = _listeners[event].length, i = 0, _gone = false, ret = null;
+                if (!this.shouldFireEvent || this.shouldFireEvent(event, value, originalEvent)) {
+                    while (!_gone && i < l && ret !== false) {                    
+                    
+                        // doing it this way rather than catching and then possibly re-throwing means that an error propagated by this
+                        // method will have the whole call stack available in the debugger.
+                        if (jsPlumbUtil.findWithFunction(eventsToDieOn, function(e) { return e === event; }) != -1) 
+                            _listeners[event][i](value, originalEvent);
+                        else {
+                            // for events we don't want to die on, catch and log.
+                            try {                            
+                                ret = _listeners[event][i](value, originalEvent);
+                            } catch (e) {
+                                jsPlumbUtil.log("jsPlumb: fire failed for event " + event + " : " + e);
+                            }
+                        }
+                        i++;
+                        if (_listeners == null || _listeners[event] == null) _gone = true;                    
+                    }
+                }
+            }
+            return this;
+        };
+        
+        this.unbind = function(event) {
+            if (event)
+                delete _listeners[event];
+            else {
+                _listeners = {};
+            }
+            return this;
+        };
+        
+        this.getListener = function(forEvent) {
+            return _listeners[forEvent];
+        };              
+        this.setSuspendEvents = function(val) {
+            eventsSuspended = val;    
+        };        
+        this.isSuspendEvents = function() {
+            return eventsSuspended;
+        };        
+        this.cleanupListeners = function() {
+            for (var i in _listeners) {
+                _listeners[i].splice(0);
+                delete _listeners[i];
+            }
+        };
+    };
+
+
+    jsPlumbUtil.EventGenerator.prototype = {
+        cleanup:function() {
+            this.cleanupListeners();
+        }
+    };
+
+
+    // thanks MDC
+    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fbind
+    if (!Function.prototype.bind) {
+      Function.prototype.bind = function (oThis) {
+        if (typeof this !== "function") {
+          // closest thing possible to the ECMAScript 5 internal IsCallable function
+          throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
+        }
+
+        var aArgs = Array.prototype.slice.call(arguments, 1), 
+            fToBind = this, 
+            fNOP = function () {},
+            fBound = function () {
+              return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
+                                   aArgs.concat(Array.prototype.slice.call(arguments)));
+            };
+
+        fNOP.prototype = this.prototype;
+        fBound.prototype = new fNOP();
+
+        return fBound;
+      };
+    }
+
+})();
\ No newline at end of file