mootools.jsPlumb-1.3.2-RC1.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * jsPlumb
  3. *
  4. * Title:jsPlumb 1.3.2
  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 MooTools adapter.
  10. *
  11. * Copyright (c) 2010 - 2011 Simon Porritt (http://jsplumb.org)
  12. *
  13. * http://jsplumb.org
  14. * http://code.google.com/p/jsplumb
  15. *
  16. * Triple licensed under the MIT, GPL2 and Beer licenses.
  17. */
  18. ;(function() {
  19. /*
  20. * overrides the FX class to inject 'step' functionality, which MooTools does not
  21. * offer, and which makes me sad. they don't seem keen to add it, either, despite
  22. * the fact that it could be useful:
  23. *
  24. * https://mootools.lighthouseapp.com/projects/2706/tickets/668
  25. *
  26. */
  27. var jsPlumbMorph = new Class({
  28. Extends:Fx.Morph,
  29. onStep : null,
  30. initialize : function(el, options) {
  31. this.parent(el, options);
  32. if (options['onStep']) {
  33. this.onStep = options['onStep'];
  34. }
  35. },
  36. step : function(now) {
  37. this.parent(now);
  38. if (this.onStep) {
  39. try { this.onStep(); }
  40. catch(e) { }
  41. }
  42. }
  43. });
  44. var _droppables = {},
  45. _droppableOptions = {},
  46. _draggablesByScope = {},
  47. _draggablesById = {},
  48. _droppableScopesById = {};
  49. /*
  50. *
  51. */
  52. var _executeDroppableOption = function(el, dr, event) {
  53. if (dr) {
  54. var id = dr.get("id");
  55. if (id) {
  56. var options = _droppableOptions[id];
  57. if (options) {
  58. if (options[event]) {
  59. options[event](el, dr);
  60. }
  61. }
  62. }
  63. }
  64. };
  65. var _checkHover = function(el, entering) {
  66. if (el) {
  67. var id = el.get("id");
  68. if (id) {
  69. var options = _droppableOptions[id];
  70. if (options) {
  71. if (options['hoverClass']) {
  72. if (entering) el.addClass(options['hoverClass']);
  73. else el.removeClass(options['hoverClass']);
  74. }
  75. }
  76. }
  77. }
  78. };
  79. /**
  80. * adds the given value to the given list, with the given scope. creates the scoped list
  81. * if necessary.
  82. * used by initDraggable and initDroppable.
  83. */
  84. var _add = function(list, scope, value) {
  85. var l = list[scope];
  86. if (!l) {
  87. l = [];
  88. list[scope] = l;
  89. }
  90. l.push(value);
  91. };
  92. /*
  93. * gets an "element object" from the given input. this means an object that is used by the
  94. * underlying library on which jsPlumb is running. 'el' may already be one of these objects,
  95. * in which case it is returned as-is. otherwise, 'el' is a String, the library's lookup
  96. * function is used to find the element, using the given String as the element's id.
  97. */
  98. var _getElementObject = function(el) {
  99. return $(el);
  100. };
  101. jsPlumb.CurrentLibrary = {
  102. /**
  103. * adds the given class to the element object.
  104. */
  105. addClass : function(el, clazz) {
  106. el.addClass(clazz);
  107. },
  108. animate : function(el, properties, options) {
  109. var m = new jsPlumbMorph(el, options);
  110. m.start(properties);
  111. },
  112. appendElement : function(child, parent) {
  113. _getElementObject(parent).grab(child);
  114. },
  115. bind : function(el, event, callback) {
  116. el = _getElementObject(el);
  117. el.addEvent(event, callback);
  118. },
  119. dragEvents : {
  120. 'start':'onStart', 'stop':'onComplete', 'drag':'onDrag', 'step':'onStep',
  121. 'over':'onEnter', 'out':'onLeave','drop':'onDrop', 'complete':'onComplete'
  122. },
  123. /*
  124. * wrapper around the library's 'extend' functionality (which it hopefully has.
  125. * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
  126. * instead. it's not like its hard.
  127. */
  128. extend : function(o1, o2) {
  129. return $extend(o1, o2);
  130. },
  131. /**
  132. * gets the named attribute from the given element object.
  133. */
  134. getAttribute : function(el, attName) {
  135. return el.get(attName);
  136. },
  137. getClientXY : function(eventObject) {
  138. return [eventObject.event.clientX, eventObject.event.clientY];
  139. },
  140. getDragObject : function(eventArgs) {
  141. return eventArgs[0];
  142. },
  143. getDragScope : function(el) {
  144. var id = jsPlumb.getId(el);
  145. var drags = _draggablesById[id];
  146. return drags[0].scope;
  147. },
  148. getDropScope : function(el) {
  149. var id = jsPlumb.getId(el);
  150. return _droppableScopesById[id];
  151. },
  152. getElementObject : _getElementObject,
  153. /*
  154. gets the offset for the element object. this should return a js object like this:
  155. { left:xxx, top: xxx}
  156. */
  157. getOffset : function(el) {
  158. var p = el.getPosition();
  159. return { left:p.x, top:p.y };
  160. },
  161. getPageXY : function(eventObject) {
  162. return [eventObject.event.pageX, eventObject.event.pageY];
  163. },
  164. getParent : function(el) {
  165. return jsPlumb.CurrentLibrary.getElementObject(el).getParent();
  166. },
  167. getScrollLeft : function(el) {
  168. return null;
  169. },
  170. getScrollTop : function(el) {
  171. return null;
  172. },
  173. getSize : function(el) {
  174. var s = el.getSize();
  175. return [s.x, s.y];
  176. },
  177. /*
  178. * takes the args passed to an event function and returns you an object that gives the
  179. * position of the object being moved, as a js object with the same params as the result of
  180. * getOffset, ie: { left: xxx, top: xxx }.
  181. */
  182. getUIPosition : function(eventArgs) {
  183. var ui = eventArgs[0],
  184. p = jsPlumb.CurrentLibrary.getElementObject(ui).getPosition();
  185. return { left:p.x, top:p.y };
  186. },
  187. hasClass : function(el, clazz) {
  188. return el.hasClass(clazz);
  189. },
  190. initDraggable : function(el, options) {
  191. var id = jsPlumb.getId(el);
  192. var drag = _draggablesById[id];
  193. if (!drag) {
  194. var originalZIndex = 0, originalCursor = null;
  195. var dragZIndex = jsPlumb.Defaults.DragOptions.zIndex || 2000;
  196. options['onStart'] = jsPlumb.wrap(options['onStart'], function()
  197. {
  198. originalZIndex = this.element.getStyle('z-index');
  199. this.element.setStyle('z-index', dragZIndex);
  200. if (jsPlumb.Defaults.DragOptions.cursor) {
  201. originalCursor = this.element.getStyle('cursor');
  202. this.element.setStyle('cursor', jsPlumb.Defaults.DragOptions.cursor);
  203. }
  204. });
  205. options['onComplete'] = jsPlumb.wrap(options['onComplete'], function()
  206. {
  207. this.element.setStyle('z-index', originalZIndex);
  208. if (originalCursor) {
  209. this.element.setStyle('cursor', originalCursor);
  210. }
  211. });
  212. // DROPPABLES:
  213. var scope = options['scope'] || jsPlumb.Defaults.Scope;
  214. var filterFunc = function(entry) {
  215. return entry.get("id") != el.get("id");
  216. };
  217. var droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
  218. options['droppables'] = droppables;
  219. options['onLeave'] = jsPlumb.wrap(options['onLeave'], function(el, dr) {
  220. if (dr) {
  221. _checkHover(dr, false);
  222. _executeDroppableOption(el, dr, 'onLeave');
  223. }
  224. });
  225. options['onEnter'] = jsPlumb.wrap(options['onEnter'], function(el, dr) {
  226. if (dr) {
  227. _checkHover(dr, true);
  228. _executeDroppableOption(el, dr, 'onEnter');
  229. }
  230. });
  231. options['onDrop'] = function(el, dr) {
  232. if (dr) {
  233. _checkHover(dr, false);
  234. _executeDroppableOption(el, dr, 'onDrop');
  235. }
  236. };
  237. drag = new Drag.Move(el, options);
  238. drag.scope = scope;
  239. //console.log("drag scope initialized to ", scope);
  240. _add(_draggablesByScope, scope, drag);
  241. _add(_draggablesById, el.get("id"), drag);
  242. // test for disabled.
  243. if (options.disabled) drag.detach();
  244. }
  245. return drag;
  246. },
  247. initDroppable : function(el, options) {
  248. var scope = options['scope'] || jsPlumb.Defaults.Scope;
  249. _add(_droppables, scope, el);
  250. var id = jsPlumb.getId(el);
  251. _droppableOptions[id] = options;
  252. _droppableScopesById[id] = scope;
  253. var filterFunc = function(entry) { return entry.element != el; };
  254. var draggables = _draggablesByScope[scope] ? _draggablesByScope[scope].filter(filterFunc) : [];
  255. for (var i = 0; i < draggables.length; i++) {
  256. draggables[i].droppables.push(el);
  257. }
  258. },
  259. isAlreadyDraggable : function(el) {
  260. return _draggablesById[jsPlumb.getId(el)] != null;
  261. },
  262. isDragSupported : function(el, options) {
  263. return typeof Drag != 'undefined' ;
  264. },
  265. /*
  266. * you need Drag.Move imported to make drop work.
  267. */
  268. isDropSupported : function(el, options) {
  269. return (typeof Drag != undefined && typeof Drag.Move != undefined);
  270. },
  271. /**
  272. * removes the given class from the element object.
  273. */
  274. removeClass : function(el, clazz) {
  275. el.removeClass(clazz);
  276. },
  277. removeElement : function(element, parent) {
  278. _getElementObject(element).dispose(); // ??
  279. },
  280. /**
  281. * sets the named attribute on the given element object.
  282. */
  283. setAttribute : function(el, attName, attValue) {
  284. el.set(attName, attValue);
  285. },
  286. setDraggable : function(el, draggable) {
  287. var draggables = _draggablesById[el.get("id")];
  288. if (draggables) {
  289. draggables.each(function(d) {
  290. if (draggable) d.attach(); else d.detach();
  291. });
  292. }
  293. },
  294. setDragScope : function(el, scope) {
  295. var drag = _draggablesById[el.get("id")];
  296. var filterFunc = function(entry) {
  297. return entry.get("id") != el.get("id");
  298. };
  299. var droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
  300. drag[0].droppables = droppables;
  301. },
  302. setOffset : function(el, o) {
  303. _getElementObject(el).setPosition({x:o.left, y:o.top});
  304. }
  305. };
  306. window.addEvent('domready', jsPlumb.init);
  307. })();