reservation plugin - unbound request (unclean
[unfold.git] / portal / static / unbound_reservation_static / src / mootools.jsPlumb.js
diff --git a/portal/static/unbound_reservation_static/src/mootools.jsPlumb.js b/portal/static/unbound_reservation_static/src/mootools.jsPlumb.js
new file mode 100644 (file)
index 0000000..4dd18db
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * jsPlumb
+ * 
+ * Title:jsPlumb 1.5.5
+ * 
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.  
+ * 
+ * This file contains the MooTools adapter.
+ *
+ * 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() {
+       
+       /*
+        * overrides the FX class to inject 'step' functionality, which MooTools does not
+        * offer, and which makes me sad.  they don't seem keen to add it, either, despite
+        * the fact that it could be useful:
+        * 
+        * https://mootools.lighthouseapp.com/projects/2706/tickets/668
+        * 
+        */
+       var jsPlumbMorph = new Class({
+               Extends:Fx.Morph,
+               onStep : null,
+               initialize : function(el, options) {
+                       this.parent(el, options);
+                       if (options.onStep) {
+                               this.onStep = options.onStep;
+                       }
+               },
+               step : function(now) {
+                       this.parent(now);
+                       if (this.onStep) { 
+                               try { this.onStep(); } 
+                               catch(e) { } 
+                       }
+               }
+       });
+       
+       var _droppables = {},
+       _droppableOptions = {},
+       _draggablesByScope = {},
+       _draggablesById = {},
+       _droppableScopesById = {};
+       /*
+        * 
+        */
+       var _executeDroppableOption = function(el, dr, event, originalEvent) {
+               if (dr) {
+                       var id = dr.get("id");
+                       if (id) {
+                               var options = _droppableOptions[id];
+                               if (options) {
+                                       if (options[event]) {
+                                               options[event](el, dr, originalEvent);
+                                       }
+                               }
+                       }
+               }
+       };      
+       
+       var _checkHover = function(el, entering) {
+               if (el) {
+                       var id = el.get("id");
+                       if (id) {
+                               var options = _droppableOptions[id];
+                               if (options) {
+                                       if (options.hoverClass) {
+                                               if (entering) el.addClass(options.hoverClass);
+                                               else el.removeClass(options.hoverClass);
+                                       }
+                               }
+                       }
+               }
+       };
+
+       /**
+        * adds the given value to the given list, with the given scope. creates the scoped list
+        * if necessary.
+        * used by initDraggable and initDroppable.
+        */
+       var _add = function(list, _scope, value) {
+               var l = list[_scope];
+               if (!l) {
+                       l = [];
+                       list[_scope] = l;
+               }
+               l.push(value);
+       };
+       
+       /*
+        * gets an "element object" from the given input.  this means an object that is used by the
+        * underlying library on which jsPlumb is running.  'el' may already be one of these objects,
+        * in which case it is returned as-is.  otherwise, 'el' is a String, the library's lookup 
+        * function is used to find the element, using the given String as the element's id.
+        */
+       var _getElementObject = function(el) {
+         return $(el);
+       };
+               
+       jsPlumb.CurrentLibrary = {                              
+               
+               /**
+                * adds the given class to the element object.
+                */
+               addClass : function(el, clazz) {
+                       el = jsPlumb.CurrentLibrary.getElementObject(el);
+                       try {
+                               if (el.className.constructor == SVGAnimatedString) {
+                                       jsPlumbUtil.svg.addClass(el, clazz);
+                               }
+                               else el.addClass(clazz);
+                       }
+                       catch (e) {                             
+                               // SVGAnimatedString not supported; no problem.
+                               el.addClass(clazz);
+                       }                                               
+               },      
+                       
+               animate : function(el, properties, options) {                   
+                       var m = new jsPlumbMorph(el, options);
+                       m.start(properties);
+               },
+               
+               appendElement : function(child, parent) {
+                       _getElementObject(parent).grab(child);                  
+               },
+               
+               bind : function(el, event, callback) {
+                       var els = jsPlumbUtil.isString(el) || typeof el.length == "undefined" ? [ _getElementObject(el) ] : $$(el);
+                       //el = _getElementObject(el);
+                       for (var i = 0; i < els.length; i++)
+                               els[i].addEvent(event, callback);
+               },
+
+               destroyDraggable : function(el) {
+                       // TODO
+                       var id = jsPlumb.getId(el), d = _draggablesById[id];
+                       if (d) {
+                               for (var i = 0; i < d.length; i++)
+                                       d[i].detach();
+
+                               delete _draggablesById[id];
+                       }
+               },
+
+               destroyDroppable : function(el) {
+                       // TODO
+               },
+               
+               dragEvents : {
+                       'start':'onStart', 'stop':'onComplete', 'drag':'onDrag', 'step':'onStep',
+                       'over':'onEnter', 'out':'onLeave','drop':'onDrop', 'complete':'onComplete'
+               },
+
+               /*
+                * wrapper around the library's 'extend' functionality (which it hopefully has.
+                * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
+                * instead.  it's not like its hard.
+                */
+               extend : function(o1, o2) {
+                       return $extend(o1, o2);
+               },
+               
+               getClientXY : function(eventObject) {
+                       return [eventObject.event.clientX, eventObject.event.clientY];
+               },
+               
+               getDragObject : function(eventArgs) {
+                       return eventArgs[0];
+               },
+               
+               getDragScope : function(el) {
+                       var id = jsPlumb.getId(el),
+                           drags = _draggablesById[id];
+                       return drags[0].scope;
+               },
+       
+               getDropEvent : function(args) {                 
+                       return args[2];
+               },
+               
+               getDropScope : function(el) {
+                       var id = jsPlumb.getId(el);
+                       return _droppableScopesById[id];
+               },
+               
+               getDOMElement : function(el) { 
+                       if (el == null) return null;
+                       // MooTools just decorates the DOM elements. so we have either an ID or an Element here.
+                       return typeof(el) == "string" ? document.getElementById(el) : el; 
+               },
+                                                       
+               getElementObject : _getElementObject,
+               
+               /*
+                 gets the offset for the element object.  this should return a js object like this:
+                 
+                 { left:xxx, top: xxx}
+                */
+               getOffset : function(el) {
+                       var p = el.getPosition();
+                       return { left:p.x, top:p.y };
+               },      
+               
+               getOriginalEvent : function(e) {
+                       return e.event;
+               },                      
+               
+               getPageXY : function(eventObject) {
+                       return [eventObject.event.pageX, eventObject.event.pageY];
+               },
+               
+               getParent : function(el) {
+                       return jsPlumb.CurrentLibrary.getElementObject(el).getParent();
+               },
+               
+               getScrollLeft : function(el) {
+                       return null;
+               },
+               
+               getScrollTop : function(el) {
+                       return null;
+               },
+               
+               getSelector : function(context, spec) {
+            if (arguments.length == 2) {
+                return jsPlumb.CurrentLibrary.getElementObject(context).getElements(spec);
+            }
+            else
+                            return $$(context);
+               },
+               
+               getSize : function(el) {
+                       var s = el.getSize();
+                       return [s.x, s.y];
+               },
+
+        getTagName : function(el) {
+            var e = jsPlumb.CurrentLibrary.getElementObject(el);
+            return e != null ? e.tagName : null;
+        },
+               
+               /*
+                * takes the args passed to an event function and returns you an object that gives the
+                * position of the object being moved, as a js object with the same params as the result of
+                * getOffset, ie: { left: xxx, top: xxx }.
+                */
+               getUIPosition : function(eventArgs, zoom) {
+                 var ui = eventArgs[0],
+                         el = jsPlumb.CurrentLibrary.getElementObject(ui),
+                         p = el.getPosition();
+                       
+                 zoom = zoom || 1;               
+                       
+                 return { left:p.x / zoom, top:p.y / zoom};
+               },              
+               
+               hasClass : function(el, clazz) {
+                       return el.hasClass(clazz);
+               },
+               
+               initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) {
+                       var id = jsPlumb.getId(el);
+                       var drag = _draggablesById[id];
+                       if (!drag) {
+                               var originalZIndex = 0,
+                    originalCursor = null,
+                                   dragZIndex = jsPlumb.Defaults.DragOptions.zIndex || 2000;
+                
+                               options.onStart = jsPlumbUtil.wrap(options.onStart, function() {
+                    originalZIndex = this.element.getStyle('z-index');
+                                       this.element.setStyle('z-index', dragZIndex);
+                    drag.originalZIndex = originalZIndex;
+                                       if (jsPlumb.Defaults.DragOptions.cursor) {
+                                               originalCursor = this.element.getStyle('cursor');
+                                               this.element.setStyle('cursor', jsPlumb.Defaults.DragOptions.cursor);
+                                       }
+                                       $(document.body).addClass(_jsPlumb.dragSelectClass);
+                               });
+                               
+                               options.onComplete = jsPlumbUtil.wrap(options.onComplete, function() {
+                                       this.element.setStyle('z-index', originalZIndex);
+                                       if (originalCursor) {
+                                               this.element.setStyle('cursor', originalCursor);
+                                       }                    
+                                       $(document.body).removeClass(_jsPlumb.dragSelectClass);
+                               });
+                               
+                               // DROPPABLES - only relevant if this is a plumbed component, ie. not just the result of the user making some DOM element
+                // draggable.  this is the only library adapter that has to care about this parameter.
+                               var scope = "" + (options.scope || jsPlumb.Defaults.Scope),
+                                   filterFunc = function(entry) {
+                                           return entry.get("id") != el.get("id");
+                                   },
+                                   droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
+
+                if (isPlumbedComponent) {
+
+                                   options.droppables = droppables;
+                                   options.onLeave = jsPlumbUtil.wrap(options.onLeave, function(el, dr) {
+                                       if (dr) {
+                                               _checkHover(dr, false);
+                                               _executeDroppableOption(el, dr, 'onLeave');
+                                           }
+                                   });
+                                   options.onEnter = jsPlumbUtil.wrap(options.onEnter, function(el, dr) {
+                                           if (dr) {
+                                                   _checkHover(dr, true);
+                                                   _executeDroppableOption(el, dr, 'onEnter');
+                                           }
+                                   });
+                                   options.onDrop = function(el, dr, event) {
+                                           if (dr) {
+                                                   _checkHover(dr, false);
+                                                   _executeDroppableOption(el, dr, 'onDrop', event);
+                                           }
+                                   };
+                }
+                else
+                    options.droppables = [];
+                               
+                               drag = new Drag.Move(el, options);
+                               drag.scope = scope;
+                drag.originalZIndex = originalZIndex;
+                _add(_draggablesById, el.get("id"), drag);
+                               // again, only keep a record of this for scope stuff if this is a plumbed component (an endpoint)
+                if (isPlumbedComponent) {
+                                   _add(_draggablesByScope, scope, drag);
+                }
+                               // test for disabled.
+                               if (options.disabled) drag.detach();
+                       }
+                       return drag;
+               },
+               
+               initDroppable : function(el, options, isPlumbedComponent, isPermanent) {
+                       var scope = options.scope;
+            _add(_droppables, scope, el);
+                       var id = jsPlumb.getId(el);
+
+            el.setAttribute("_isPermanentDroppable", isPermanent);  // we use this to clear out droppables on drag complete.
+                       _droppableOptions[id] = options;
+                       _droppableScopesById[id] = scope;
+                       var filterFunc = function(entry) { return entry.element != el; },
+                           draggables = _draggablesByScope[scope] ? _draggablesByScope[scope].filter(filterFunc) : [];
+                       for (var i = 0; i < draggables.length; i++) {
+                               draggables[i].droppables.push(el);
+                       }
+               },
+               
+               isAlreadyDraggable : function(el) {
+                       return _draggablesById[jsPlumb.getId(el)] != null;
+               },                                                                              
+               
+               isDragSupported : function(el, options) {
+                       return typeof Drag != 'undefined' ;
+               },      
+               
+               /*
+                * you need Drag.Move imported to make drop work.
+                */
+               isDropSupported : function(el, options) {
+                       return (typeof Drag !== undefined && typeof Drag.Move !== undefined);
+               },
+               
+               /**
+                * removes the given class from the element object.
+                */
+               removeClass : function(el, clazz) {
+                       el = jsPlumb.CurrentLibrary.getElementObject(el);
+                       try {
+                               if (el.className.constructor == SVGAnimatedString) {
+                                       jsPlumbUtil.svg.removeClass(el, clazz);
+                               }
+                               else el.removeClass(clazz);
+                       }
+                       catch (e) {                             
+                               // SVGAnimatedString not supported; no problem.
+                               el.removeClass(clazz);
+                       }
+               },
+               
+               removeElement : function(element, parent) {
+            var el = _getElementObject(element);
+                       if (el) el.dispose();  // ??
+               },
+
+               setDragFilter : function(el, filter) {
+                       jsPlumbUtil.log("NOT IMPLEMENTED: setDragFilter");
+               },
+               
+               setDraggable : function(el, draggable) {
+                       var draggables = _draggablesById[el.get("id")];
+                       if (draggables) {
+                               draggables.each(function(d) {
+                                       if (draggable) d.attach(); else d.detach();
+                               });
+                       }
+               },
+               
+               setDragScope : function(el, scope) {
+                       var drag = _draggablesById[el.get("id")];
+                       var filterFunc = function(entry) {
+                               return entry.get("id") != el.get("id");
+                       };
+                       var droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
+                       drag[0].droppables = droppables;
+               },
+               
+               setOffset : function(el, o) {
+                       _getElementObject(el).setPosition({x:o.left, y:o.top});
+               },
+
+        stopDrag : function() {
+            for (var i in _draggablesById) {
+                for (var j = 0; j < _draggablesById[i].length; j++) {
+                    var d = _draggablesById[i][j];
+                    d.stop();
+                    if (d.originalZIndex !== 0)
+                        d.element.setStyle("z-index", d.originalZIndex);
+                }
+            }
+        },
+               
+               /**
+                * note that jquery ignores the name of the event you wanted to trigger, and figures it out for itself.
+                * the other libraries do not.  yui, in fact, cannot even pass an original event.  we have to pull out stuff
+                * from the originalEvent to put in an options object for YUI. 
+                * @param el
+                * @param event
+                * @param originalEvent
+                */
+               trigger : function(el, event, originalEvent) {
+                       originalEvent.stopPropagation();
+                       _getElementObject(el).fireEvent(event, originalEvent);
+               },
+               
+               unbind : function(el, event, callback) {
+                       el = _getElementObject(el);
+                       el.removeEvent(event, callback);
+               }
+       };
+       
+       window.addEvent('domready', jsPlumb.init);
+})();