mootools.jsPlumb-1.3.0-RC1.js 8.8 KB

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