reservation plugin - unbound request (unclean
[unfold.git] / portal / static / unbound_reservation_static / src / jquery.jsPlumb.js
1 /*
2  * jsPlumb
3  * 
4  * Title:jsPlumb 1.5.5
5  * 
6  * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
7  * elements, or VML.  
8  * 
9  * This file contains the jQuery adapter.
10  *
11  * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
12  * 
13  * http://jsplumb.org
14  * http://github.com/sporritt/jsplumb
15  * http://code.google.com/p/jsplumb
16  * 
17  * Dual licensed under the MIT and GPL2 licenses.
18  */ 
19 /* 
20  * the library specific functions, such as find offset, get id, get attribute, extend etc.  
21  * the full list is:
22  * 
23  * addClass                             adds a class to the given element
24  * animate                              calls the underlying library's animate functionality
25  * appendElement                appends a child element to a parent element.
26  * bind                                 binds some event to an element
27  * dragEvents                   a dictionary of event names
28  * extend                               extend some js object with another.  probably not overly necessary; jsPlumb could just do this internally.
29  * getDragObject                gets the object that is being dragged, by extracting it from the arguments passed to a drag callback
30  * getDragScope                 gets the drag scope for a given element.
31  * getDropScope                 gets the drop scope for a given element.
32  * getElementObject             turns an id or dom element into an element object of the underlying library's type.
33  * getOffset                    gets an element's offset
34  * getOriginalEvent     gets the original browser event from some wrapper event
35  * getPageXY                    gets the page event's xy location.
36  * getParent                    gets the parent of some element.
37  * getScrollLeft                gets an element's scroll left.  TODO: is this actually used?  will it be?
38  * getScrollTop                 gets an element's scroll top.  TODO: is this actually used?  will it be?
39  * getSize                              gets an element's size.
40  * getUIPosition                gets the position of some element that is currently being dragged, by extracting it from the arguments passed to a drag callback.
41  * hasClass                             returns whether or not the given element has the given class.
42  * initDraggable                initializes an element to be draggable 
43  * initDroppable                initializes an element to be droppable
44  * isDragSupported              returns whether or not drag is supported for some element.
45  * isDropSupported              returns whether or not drop is supported for some element.
46  * removeClass                  removes a class from a given element.
47  * removeElement                removes some element completely from the DOM. 
48  * setDragFilter                sets a filter for some element that indicates areas of the element that should not respond to dragging.
49  * setDraggable                 sets whether or not some element should be draggable.
50  * setDragScope                 sets the drag scope for a given element.
51  * setOffset                    sets the offset of some element.
52  * trigger                              triggers some event on an element.
53  * unbind                               unbinds some listener from some element.
54  */
55 (function($) {  
56         
57         //var getBoundingClientRectSupported = "getBoundingClientRect" in document.documentElement;
58
59         var _getElementObject = function(el) {                  
60                 return typeof(el) == "string" ? $("#" + el) : $(el);
61         };
62
63         jsPlumb.CurrentLibrary = {                                              
64                 
65                 /**
66                  * adds the given class to the element object.
67                  */
68                 addClass : function(el, clazz) {
69                         el = _getElementObject(el);
70                         try {
71                                 if (el[0].className.constructor == SVGAnimatedString) {
72                                         jsPlumbUtil.svg.addClass(el[0], clazz);                    
73                                 }
74                         }
75                         catch (e) {
76                                 // SVGAnimatedString not supported; no problem.
77                         }
78             try {                
79                 el.addClass(clazz);
80             }
81             catch (e) {
82                 // you probably have jQuery 1.9 and Firefox.  
83             }
84                 },
85                 
86                 /**
87                  * animates the given element.
88                  */
89                 animate : function(el, properties, options) {
90                         el.animate(properties, options);
91                 },                              
92                 
93                 /**
94                  * appends the given child to the given parent.
95
96 TODO: REMOVE!
97
98                  */
99                 appendElement : function(child, parent) {
100                         _getElementObject(parent).append(child);                        
101                 },   
102
103                 /**
104                 * executes an ajax call.
105                 */
106                 ajax : function(params) {
107                         params = params || {};
108                         params.type = params.type || "get";
109                         $.ajax(params);
110                 },
111                 
112                 /**
113                  * event binding wrapper.  it just so happens that jQuery uses 'bind' also.  yui3, for example,
114                  * uses 'on'.
115                  */
116                 bind : function(el, event, callback) {
117                         el = _getElementObject(el);
118                         el.bind(event, callback);
119                 },
120
121                 destroyDraggable : function(el) {
122                         if ($(el).data("draggable"))
123                                 $(el).draggable("destroy");
124                 },
125
126                 destroyDroppable : function(el) {
127                         if ($(el).data("droppable"))
128                                 $(el).droppable("destroy");
129                 },
130                 
131                 /**
132          * mapping of drag events for jQuery
133          */
134                 dragEvents : {
135                         'start':'start', 'stop':'stop', 'drag':'drag', 'step':'step',
136                         'over':'over', 'out':'out', 'drop':'drop', 'complete':'complete'
137                 },
138                                 
139                 /**
140                  * wrapper around the library's 'extend' functionality (which it hopefully has.
141                  * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
142                  * instead.  it's not like its hard.
143                  */
144                 extend : function(o1, o2) {
145                         return $.extend(o1, o2);
146                 },              
147                 
148                 getClientXY : function(eventObject) {
149                         return [eventObject.clientX, eventObject.clientY];
150                 },
151                 
152                 /**
153                  * takes the args passed to an event function and returns you an object representing that which is being dragged.
154                  */
155                 getDragObject : function(eventArgs) {
156                         return eventArgs[1].draggable || eventArgs[1].helper;
157                 },
158                 
159                 getDragScope : function(el) {
160                         return $(el).draggable("option", "scope");
161                 },
162
163                 getDropEvent : function(args) {
164                         return args[0];
165                 },
166                 
167                 getDropScope : function(el) {
168                         return $(el).droppable("option", "scope");              
169                 },
170
171                 /**
172                 * gets a DOM element from the given input, which might be a string (in which case we just do document.getElementById),
173                 * a selector (in which case we return el[0]), or a DOM element already (we assume this if it's not either of the other
174                 * two cases).  this is the opposite of getElementObject below.
175                 */
176                 getDOMElement : function(el) {
177                         if (el == null) return null;
178                         if (typeof(el) == "string") return document.getElementById(el);
179                         else if (el.context || el.length != null) return el[0];
180                         else return el;
181                 },
182         
183                 /**
184                  * gets an "element object" from the given input.  this means an object that is used by the
185                  * underlying library on which jsPlumb is running.  'el' may already be one of these objects,
186                  * in which case it is returned as-is.  otherwise, 'el' is a String, the library's lookup 
187                  * function is used to find the element, using the given String as the element's id.
188                  * 
189                  */             
190                 getElementObject : _getElementObject,
191                 
192                 /**
193                   * gets the offset for the element object.  this should return a js object like this:
194                   *
195                   * { left:xxx, top: xxx }
196                  */
197                 getOffset : function(el) {
198                         return el.offset();
199                 },
200
201                 getOriginalEvent : function(e) {
202                         return e.originalEvent;
203                 },
204                 
205                 getPageXY : function(eventObject) {
206                         return [eventObject.pageX, eventObject.pageY];
207                 },
208                 
209                 getParent : function(el) {
210                         return _getElementObject(el).parent();
211                 },
212                                                                                                                 
213                 getScrollLeft : function(el) {
214                         return el.scrollLeft();
215                 },
216                 
217                 getScrollTop : function(el) {
218                         return el.scrollTop();
219                 },
220                 
221                 getSelector : function(context, spec) {
222             if (arguments.length == 2)
223                 return _getElementObject(context).find(spec);
224             else
225                 return $(context);
226                 },
227                 
228                 /**
229                  * gets the size for the element object, in an array : [ width, height ].
230                  */
231                 getSize : function(el) {
232                         el = $(el);
233                         return [el.outerWidth(), el.outerHeight()];
234                 },
235
236         getTagName : function(el) {
237             var e = _getElementObject(el);
238             return e.length > 0 ? e[0].tagName : null;
239         },
240                 
241                 /**
242                  * takes the args passed to an event function and returns you an object that gives the
243                  * position of the object being moved, as a js object with the same params as the result of
244                  * getOffset, ie: { left: xxx, top: xxx }.
245                  * 
246                  * different libraries have different signatures for their event callbacks.  
247                  * see getDragObject as well
248                  */
249                 getUIPosition : function(eventArgs, zoom) {
250                         
251                         zoom = zoom || 1;
252                         // this code is a workaround for the case that the element being dragged has a margin set on it. jquery UI passes
253                         // in the wrong offset if the element has a margin (it doesn't take the margin into account).  the getBoundingClientRect
254                         // method, which is in pretty much all browsers now, reports the right numbers.  but it introduces a noticeable lag, which
255                         // i don't like.
256             
257                         /*if ( getBoundingClientRectSupported ) {
258                                 var r = eventArgs[1].helper[0].getBoundingClientRect();
259                                 return { left : r.left, top: r.top };
260                         } else {*/
261                         if (eventArgs.length == 1) {
262                                 ret = { left: eventArgs[0].pageX, top:eventArgs[0].pageY };
263                         }
264                         else {
265                                 var ui = eventArgs[1],
266                                   _offset = ui.offset;
267                                   
268                                 ret = _offset || ui.absolutePosition;
269                                 
270                                 // adjust ui position to account for zoom, because jquery ui does not do this.
271                                 ui.position.left /= zoom;
272                                 ui.position.top /= zoom;
273                         }
274             return { left:ret.left / zoom, top: ret.top / zoom };
275                 },              
276                 
277                 hasClass : function(el, clazz) {
278                         return el.hasClass(clazz);
279                 },
280                 
281                 /**
282                  * initialises the given element to be draggable.
283                  */
284                 initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) {
285                         options = options || {};
286                         el = $(el);
287
288                         options.start = jsPlumbUtil.wrap(options.start, function() {
289                                 $("body").addClass(_jsPlumb.dragSelectClass);
290                         }, false);
291
292                         options.stop = jsPlumbUtil.wrap(options.stop, function() {
293                                 $("body").removeClass(_jsPlumb.dragSelectClass);
294                         });
295
296                         // remove helper directive if present and no override
297                         if (!options.doNotRemoveHelper)
298                                 options.helper = null;
299                         if (isPlumbedComponent)
300                                 options.scope = options.scope || jsPlumb.Defaults.Scope;
301                         el.draggable(options);
302                 },
303                 
304                 /**
305                  * initialises the given element to be droppable.
306                  */
307                 initDroppable : function(el, options) {
308                         options.scope = options.scope || jsPlumb.Defaults.Scope;
309                         $(el).droppable(options);
310                 },
311                 
312                 isAlreadyDraggable : function(el) {
313                         return $(el).hasClass("ui-draggable");
314                 },
315                 
316                 /**
317                  * returns whether or not drag is supported (by the library, not whether or not it is disabled) for the given element.
318                  */
319                 isDragSupported : function(el, options) {
320                         return $(el).draggable;
321                 },                              
322                                                 
323                 /**
324                  * returns whether or not drop is supported (by the library, not whether or not it is disabled) for the given element.
325                  */
326                 isDropSupported : function(el, options) {
327                         return $(el).droppable;
328                 },                                                      
329                 
330                 /**
331                  * removes the given class from the element object.
332                  */
333                 removeClass : function(el, clazz) {
334                         el = _getElementObject(el);
335                         try {
336                                 if (el[0].className.constructor == SVGAnimatedString) {
337                                         jsPlumbUtil.svg.removeClass(el[0], clazz);
338                     return;
339                                 }
340                         }
341                         catch (e) {
342                                 // SVGAnimatedString not supported; no problem.
343                         }
344                         el.removeClass(clazz);
345                 },
346                 
347                 removeElement : function(element) {                     
348                         _getElementObject(element).remove();
349                 },              
350
351                 setDragFilter : function(el, filter) {
352                         if (jsPlumb.CurrentLibrary.isAlreadyDraggable(el))
353                                 el.draggable("option", "cancel", filter);
354                 },
355                 
356                 setDraggable : function(el, draggable) {
357                         el.draggable("option", "disabled", !draggable);
358                 },
359                 
360                 setDragScope : function(el, scope) {
361                         el.draggable("option", "scope", scope);
362                 },
363                 
364                 setOffset : function(el, o) {
365                         _getElementObject(el).offset(o);
366                 },
367                 
368                 /**
369                  * note that jquery ignores the name of the event you wanted to trigger, and figures it out for itself.
370                  * the other libraries do not.  yui, in fact, cannot even pass an original event.  we have to pull out stuff
371                  * from the originalEvent to put in an options object for YUI. 
372                  * @param el
373                  * @param event
374                  * @param originalEvent
375                  */
376                 trigger : function(el, event, originalEvent) {
377                         var h = jQuery._data(_getElementObject(el)[0], "handle");
378             h(originalEvent);
379                 },
380                 
381                 unbind : function(el, event, callback) {
382                         el = _getElementObject(el);
383                         el.unbind(event, callback);
384                 }
385         };
386         
387         $(document).ready(jsPlumb.init);
388         
389 })(jQuery);
390