jquery.jsPlumb-1.3.7-RC1.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. * jsPlumb
  3. *
  4. * Title:jsPlumb 1.3.7
  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 - 2012 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. * getAttribute gets some attribute from an element
  30. * getDragObject gets the object that is being dragged, by extracting it from the arguments passed to a drag callback
  31. * getDragScope gets the drag scope for a given element.
  32. * getDropScope gets the drop scope for a given element.
  33. * getElementObject turns an id or dom element into an element object of the underlying library's type.
  34. * getOffset gets an element's offset
  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. * setAttribute sets an attribute on some element.
  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. //var getBoundingClientRectSupported = "getBoundingClientRect" in document.documentElement;
  57. jsPlumb.CurrentLibrary = {
  58. /**
  59. * adds the given class to the element object.
  60. */
  61. addClass : function(el, clazz) {
  62. el = jsPlumb.CurrentLibrary.getElementObject(el);
  63. try {
  64. if (el[0].className.constructor == SVGAnimatedString) {
  65. jsPlumb.util.svg.addClass(el[0], clazz);
  66. }
  67. }
  68. catch (e) {
  69. // SVGAnimatedString not supported; no problem.
  70. }
  71. el.addClass(clazz);
  72. },
  73. /**
  74. * animates the given element.
  75. */
  76. animate : function(el, properties, options) {
  77. el.animate(properties, options);
  78. },
  79. /**
  80. * appends the given child to the given parent.
  81. */
  82. appendElement : function(child, parent) {
  83. jsPlumb.CurrentLibrary.getElementObject(parent).append(child);
  84. },
  85. /**
  86. * event binding wrapper. it just so happens that jQuery uses 'bind' also. yui3, for example,
  87. * uses 'on'.
  88. */
  89. bind : function(el, event, callback) {
  90. el = jsPlumb.CurrentLibrary.getElementObject(el);
  91. el.bind(event, callback);
  92. },
  93. /**
  94. * mapping of drag events for jQuery
  95. */
  96. dragEvents : {
  97. 'start':'start', 'stop':'stop', 'drag':'drag', 'step':'step',
  98. 'over':'over', 'out':'out', 'drop':'drop', 'complete':'complete'
  99. },
  100. /**
  101. * wrapper around the library's 'extend' functionality (which it hopefully has.
  102. * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
  103. * instead. it's not like its hard.
  104. */
  105. extend : function(o1, o2) {
  106. return $.extend(o1, o2);
  107. },
  108. /**
  109. * gets the named attribute from the given element object.
  110. */
  111. getAttribute : function(el, attName) {
  112. return el.attr(attName);
  113. },
  114. getClientXY : function(eventObject) {
  115. return [eventObject.clientX, eventObject.clientY];
  116. },
  117. getDocumentElement : function() { return document; },
  118. /**
  119. * takes the args passed to an event function and returns you an object representing that which is being dragged.
  120. */
  121. getDragObject : function(eventArgs) {
  122. return eventArgs[1].draggable;
  123. },
  124. getDragScope : function(el) {
  125. return el.draggable("option", "scope");
  126. },
  127. getDropEvent : function(args) {
  128. return args[0];
  129. },
  130. getDropScope : function(el) {
  131. return el.droppable("option", "scope");
  132. },
  133. /**
  134. * gets a DOM element from the given input, which might be a string (in which case we just do document.getElementById),
  135. * 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
  136. * two cases). this is the opposite of getElementObject below.
  137. */
  138. getDOMElement : function(el) {
  139. if (typeof(el) == "string") return document.getElementById(el);
  140. else if (el.context) return el[0];
  141. else return el;
  142. },
  143. /**
  144. * gets an "element object" from the given input. this means an object that is used by the
  145. * underlying library on which jsPlumb is running. 'el' may already be one of these objects,
  146. * in which case it is returned as-is. otherwise, 'el' is a String, the library's lookup
  147. * function is used to find the element, using the given String as the element's id.
  148. *
  149. */
  150. getElementObject : function(el) {
  151. return typeof(el) == "string" ? $("#" + el) : $(el);
  152. },
  153. /**
  154. * gets the offset for the element object. this should return a js object like this:
  155. *
  156. * { left:xxx, top: xxx }
  157. */
  158. getOffset : function(el) {
  159. return el.offset();
  160. },
  161. getPageXY : function(eventObject) {
  162. return [eventObject.pageX, eventObject.pageY];
  163. },
  164. getParent : function(el) {
  165. return jsPlumb.CurrentLibrary.getElementObject(el).parent();
  166. },
  167. getScrollLeft : function(el) {
  168. return el.scrollLeft();
  169. },
  170. getScrollTop : function(el) {
  171. return el.scrollTop();
  172. },
  173. getSelector : function(spec) {
  174. return $(spec);
  175. },
  176. /**
  177. * gets the size for the element object, in an array : [ width, height ].
  178. */
  179. getSize : function(el) {
  180. return [el.outerWidth(), el.outerHeight()];
  181. },
  182. getTagName : function(el) {
  183. var e = jsPlumb.CurrentLibrary.getElementObject(el);
  184. return e.length > 0 ? e[0].tagName : null;
  185. },
  186. /**
  187. * takes the args passed to an event function and returns you an object that gives the
  188. * position of the object being moved, as a js object with the same params as the result of
  189. * getOffset, ie: { left: xxx, top: xxx }.
  190. *
  191. * different libraries have different signatures for their event callbacks.
  192. * see getDragObject as well
  193. */
  194. getUIPosition : function(eventArgs) {
  195. // this code is a workaround for the case that the element being dragged has a margin set on it. jquery UI passes
  196. // in the wrong offset if the element has a margin (it doesn't take the margin into account). the getBoundingClientRect
  197. // method, which is in pretty much all browsers now, reports the right numbers. but it introduces a noticeable lag, which
  198. // i don't like.
  199. /*if ( getBoundingClientRectSupported ) {
  200. var r = eventArgs[1].helper[0].getBoundingClientRect();
  201. return { left : r.left, top: r.top };
  202. } else {*/
  203. if (eventArgs.length == 1) {
  204. ret = { left: eventArgs[0].pageX, top:eventArgs[0].pageY };
  205. }
  206. else {
  207. var ui = eventArgs[1], _offset = ui.offset;
  208. ret = _offset || ui.absolutePosition;
  209. }
  210. return ret;
  211. },
  212. hasClass : function(el, clazz) {
  213. return el.hasClass(clazz);
  214. },
  215. /**
  216. * initialises the given element to be draggable.
  217. */
  218. initDraggable : function(el, options) {
  219. options = options || {};
  220. // remove helper directive if present.
  221. options.helper = null;
  222. options['scope'] = options['scope'] || jsPlumb.Defaults.Scope;
  223. el.draggable(options);
  224. },
  225. /**
  226. * initialises the given element to be droppable.
  227. */
  228. initDroppable : function(el, options) {
  229. options['scope'] = options['scope'] || jsPlumb.Defaults.Scope;
  230. el.droppable(options);
  231. },
  232. isAlreadyDraggable : function(el) {
  233. el = jsPlumb.CurrentLibrary.getElementObject(el);
  234. return el.hasClass("ui-draggable");
  235. },
  236. /**
  237. * returns whether or not drag is supported (by the library, not whether or not it is disabled) for the given element.
  238. */
  239. isDragSupported : function(el, options) {
  240. return el.draggable;
  241. },
  242. /**
  243. * returns whether or not drop is supported (by the library, not whether or not it is disabled) for the given element.
  244. */
  245. isDropSupported : function(el, options) {
  246. return el.droppable;
  247. },
  248. /**
  249. * removes the given class from the element object.
  250. */
  251. removeClass : function(el, clazz) {
  252. el = jsPlumb.CurrentLibrary.getElementObject(el);
  253. try {
  254. if (el[0].className.constructor == SVGAnimatedString) {
  255. jsPlumb.util.svg.removeClass(el[0], clazz);
  256. }
  257. }
  258. catch (e) {
  259. // SVGAnimatedString not supported; no problem.
  260. }
  261. el.removeClass(clazz);
  262. },
  263. removeElement : function(element, parent) {
  264. jsPlumb.CurrentLibrary.getElementObject(element).remove();
  265. },
  266. /**
  267. * sets the named attribute on the given element object.
  268. */
  269. setAttribute : function(el, attName, attValue) {
  270. el.attr(attName, attValue);
  271. },
  272. /**
  273. * sets the draggable state for the given element
  274. */
  275. setDraggable : function(el, draggable) {
  276. el.draggable("option", "disabled", !draggable);
  277. },
  278. /**
  279. * sets the drag scope. probably time for a setDragOption method (roll this and the one above together)
  280. * @param el
  281. * @param scope
  282. */
  283. setDragScope : function(el, scope) {
  284. el.draggable("option", "scope", scope);
  285. },
  286. setOffset : function(el, o) {
  287. jsPlumb.CurrentLibrary.getElementObject(el).offset(o);
  288. },
  289. /**
  290. * note that jquery ignores the name of the event you wanted to trigger, and figures it out for itself.
  291. * the other libraries do not. yui, in fact, cannot even pass an original event. we have to pull out stuff
  292. * from the originalEvent to put in an options object for YUI.
  293. * @param el
  294. * @param event
  295. * @param originalEvent
  296. */
  297. trigger : function(el, event, originalEvent) {
  298. //originalEvent.stopPropagation();
  299. //jsPlumb.CurrentLibrary.getElementObject(el).trigger(originalEvent);
  300. var h = jQuery._data(jsPlumb.CurrentLibrary.getElementObject(el)[0], "handle");
  301. h(originalEvent);
  302. //originalEvent.stopPropagation();
  303. },
  304. /**
  305. * event unbinding wrapper. it just so happens that jQuery uses 'unbind' also. yui3, for example,
  306. * uses..something else.
  307. */
  308. unbind : function(el, event, callback) {
  309. el = jsPlumb.CurrentLibrary.getElementObject(el);
  310. el.unbind(event, callback);
  311. }
  312. };
  313. $(document).ready(jsPlumb.init);
  314. })(jQuery);