mootools.jsPlumb-1.2-RC1.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. (function() {
  2. /*
  3. * overrides the FX class to inject 'step' functionality, which MooTools does not
  4. * offer, and which makes me sad. they don't seem keen to add it, either, despite
  5. * the fact that it could be useful:
  6. *
  7. * https://mootools.lighthouseapp.com/projects/2706/tickets/668
  8. *
  9. */
  10. var jsPlumbMorph = new Class({
  11. Extends:Fx.Morph,
  12. onStep : null,
  13. initialize : function(el, options) {
  14. this.parent(el, options);
  15. if (options['onStep']) {
  16. this.onStep = options['onStep'];
  17. }
  18. },
  19. step : function() {
  20. this.parent();
  21. if (this.onStep) {
  22. try { this.onStep(); }
  23. catch(e) { }
  24. }
  25. }
  26. });
  27. var _droppables = {};
  28. var _droppableOptions = {};
  29. var _draggablesByScope = {};
  30. var _draggablesById = {};
  31. /*
  32. *
  33. */
  34. var _executeDroppableOption = function(el, dr, event) {
  35. if (dr) {
  36. var id = dr.get("id");
  37. if (id) {
  38. var options = _droppableOptions[id];
  39. if (options) {
  40. if (options[event]) {
  41. options[event](el, dr);
  42. }
  43. }
  44. }
  45. }
  46. };
  47. var _checkHover = function(el, entering) {
  48. if (el) {
  49. var id = el.get("id");
  50. if (id) {
  51. var options = _droppableOptions[id];
  52. if (options) {
  53. if (options['hoverClass']) {
  54. if (entering) el.addClass(options['hoverClass']);
  55. else el.removeClass(options['hoverClass']);
  56. }
  57. }
  58. }
  59. }
  60. };
  61. /**
  62. * adds the given value to the given list, with the given scope. creates the scoped list
  63. * if necessary.
  64. * used by initDraggable and initDroppable.
  65. */
  66. var _add = function(list, scope, value) {
  67. var l = list[scope];
  68. if (!l) {
  69. l = [];
  70. list[scope] = l;
  71. }
  72. l.push(value);
  73. };
  74. jsPlumb.CurrentLibrary = {
  75. dragEvents : {
  76. 'start':'onStart', 'stop':'onComplete', 'drag':'onDrag', 'step':'onStep',
  77. 'over':'onEnter', 'out':'onLeave','drop':'onDrop', 'complete':'onComplete'
  78. },
  79. /*
  80. * wrapper around the library's 'extend' functionality (which it hopefully has.
  81. * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
  82. * instead. it's not like its hard.
  83. */
  84. extend : function(o1, o2) {
  85. return $extend(o1, o2);
  86. },
  87. /*
  88. * gets an "element object" from the given input. this means an object that is used by the
  89. * underlying library on which jsPlumb is running. 'el' may already be one of these objects,
  90. * in which case it is returned as-is. otherwise, 'el' is a String, the library's lookup
  91. * function is used to find the element, using the given String as the element's id.
  92. */
  93. getElementObject : function(el) {
  94. return $(el);
  95. },
  96. /*
  97. gets the offset for the element object. this should return a js object like this:
  98. { left:xxx, top: xxx}
  99. */
  100. getOffset : function(el) {
  101. var p = el.getPosition();
  102. return { left:p.x, top:p.y };
  103. },
  104. getSize : function(el) {
  105. var s = el.getSize();
  106. return [s.x, s.y];
  107. },
  108. /**
  109. * gets the named attribute from the given element object.
  110. */
  111. getAttribute : function(el, attName) {
  112. return el.get(attName);
  113. },
  114. /**
  115. * sets the named attribute on the given element object.
  116. */
  117. setAttribute : function(el, attName, attValue) {
  118. el.set(attName, attValue);
  119. },
  120. /**
  121. * adds the given class to the element object.
  122. */
  123. addClass : function(el, clazz) {
  124. el.addClass(clazz);
  125. },
  126. initDraggable : function(el, options) {
  127. var drag = _draggablesById[el.get("id")];
  128. if (!drag) {
  129. var originalZIndex = 0, originalCursor = null;
  130. var dragZIndex = jsPlumb.Defaults.DragOptions.zIndex || 2000;
  131. options['onStart'] = jsPlumb.wrap(options['onStart'], function()
  132. {
  133. originalZIndex = this.element.getStyle('z-index');
  134. this.element.setStyle('z-index', dragZIndex);
  135. if (jsPlumb.Defaults.DragOptions.cursor) {
  136. originalCursor = this.element.getStyle('cursor');
  137. this.element.setStyle('cursor', jsPlumb.Defaults.DragOptions.cursor);
  138. }
  139. });
  140. options['onComplete'] = jsPlumb.wrap(options['onComplete'], function()
  141. {
  142. this.element.setStyle('z-index', originalZIndex);
  143. if (originalCursor) {
  144. this.element.setStyle('cursor', originalCursor);
  145. }
  146. });
  147. // DROPPABLES:
  148. var scope = options['scope'] || jsPlumb.Defaults.Scope;
  149. var filterFunc = function(entry) {
  150. return entry.get("id") != el.get("id");
  151. };
  152. var droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
  153. options['droppables'] = droppables;
  154. options['onLeave'] = jsPlumb.wrap(options['onLeave'], function(el, dr) {
  155. if (dr) {
  156. _checkHover(dr, false);
  157. _executeDroppableOption(el, dr, 'onLeave');
  158. }
  159. });
  160. options['onEnter'] = jsPlumb.wrap(options['onEnter'], function(el, dr) {
  161. if (dr) {
  162. _checkHover(dr, true);
  163. _executeDroppableOption(el, dr, 'onEnter');
  164. }
  165. });
  166. options['onDrop'] = function(el, dr) {
  167. if (dr) {
  168. _checkHover(dr, false);
  169. _executeDroppableOption(el, dr, 'onDrop');
  170. }
  171. };
  172. drag = new Drag.Move(el, options);
  173. _add(_draggablesByScope, scope, drag);
  174. _add(_draggablesById, el.get("id"), drag);
  175. // test for disabled.
  176. if (options.disabled) drag.detach();
  177. }
  178. return drag;
  179. },
  180. isDragSupported : function(el, options) {
  181. return typeof Drag != 'undefined' ;
  182. },
  183. setDraggable : function(el, draggable) {
  184. var draggables = _draggablesById[el.get("id")];
  185. if (draggables) {
  186. draggables.each(function(d) {
  187. if (draggable) d.attach(); else d.detach();
  188. });
  189. }
  190. },
  191. initDroppable : function(el, options) {
  192. var scope = options['scope'] || jsPlumb.Defaults.Scope;
  193. _add(_droppables, scope, el);
  194. _droppableOptions[el.get("id")] = options;
  195. var filterFunc = function(entry) {
  196. return entry.element != el;
  197. };
  198. var draggables = _draggablesByScope[scope] ? _draggablesByScope[scope].filter(filterFunc) : [];
  199. for (var i = 0; i < draggables.length; i++) {
  200. draggables[i].droppables.push(el);
  201. }
  202. },
  203. /*
  204. * you need Drag.Move imported to make drop work.
  205. */
  206. isDropSupported : function(el, options) {
  207. if (typeof Drag != undefined)
  208. return typeof Drag.Move != undefined;
  209. return false;
  210. },
  211. animate : function(el, properties, options) {
  212. var m = new jsPlumbMorph(el, options);
  213. m.start(properties);
  214. },
  215. /*
  216. * takes the args passed to an event function and returns you an object that gives the
  217. * position of the object being moved, as a js object with the same params as the result of
  218. * getOffset, ie: { left: xxx, top: xxx }.
  219. */
  220. getUIPosition : function(eventArgs) {
  221. var ui = eventArgs[0];
  222. return { left: ui.offsetLeft, top: ui.offsetTop };
  223. },
  224. getDragObject : function(eventArgs) {
  225. return eventArgs[0];
  226. }
  227. };
  228. })();