katavorio-0.4.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. /**
  2. drag/drop functionality for use with jsPlumb but with
  3. no knowledge of jsPlumb. supports multiple scopes (separated by whitespace), dragging
  4. multiple elements, constrain to parent, drop filters, drag start filters, custom
  5. css classes.
  6. a lot of the functionality of this script is expected to be plugged in:
  7. addClass
  8. removeClass
  9. addEvent
  10. removeEvent
  11. getPosition
  12. setPosition
  13. getSize
  14. indexOf
  15. intersects
  16. the name came from here:
  17. http://mrsharpoblunto.github.io/foswig.js/
  18. copyright 2014 jsPlumb
  19. */
  20. ;(function() {
  21. "use strict";
  22. var getOffsetRect = function (elem) {
  23. // (1)
  24. var box = elem.getBoundingClientRect();
  25. var body = document.body;
  26. var docElem = document.documentElement;
  27. // (2)
  28. var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
  29. var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
  30. // (3)
  31. var clientTop = docElem.clientTop || body.clientTop || 0;
  32. var clientLeft = docElem.clientLeft || body.clientLeft || 0;
  33. // (4)
  34. var top = box.top + scrollTop - clientTop;
  35. var left = box.left + scrollLeft - clientLeft;
  36. return { top: Math.round(top), left: Math.round(left) };
  37. };
  38. var matchesSelector = function(el, selector, ctx) {
  39. ctx = ctx || el.parentNode;
  40. var possibles = ctx.querySelectorAll(selector);
  41. for (var i = 0; i < possibles.length; i++) {
  42. if (possibles[i] === el)
  43. return true;
  44. }
  45. return false;
  46. };
  47. var iev = (function() {
  48. var rv = -1;
  49. if (navigator.appName == 'Microsoft Internet Explorer') {
  50. var ua = navigator.userAgent,
  51. re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
  52. if (re.exec(ua) != null)
  53. rv = parseFloat(RegExp.$1);
  54. }
  55. return rv;
  56. })(),
  57. isIELT9 = iev > -1 && iev < 9,
  58. _pl = function(e) {
  59. if (isIELT9) {
  60. return [ e.clientX + document.documentElement.scrollLeft, e.clientY + document.documentElement.scrollTop ];
  61. }
  62. else {
  63. var ts = _touches(e), t = _getTouch(ts, 0);
  64. // this is for iPad. may not fly for Android.
  65. return [t.pageX, t.pageY];
  66. }
  67. },
  68. _getTouch = function(touches, idx) { return touches.item ? touches.item(idx) : touches[idx]; },
  69. _touches = function(e) {
  70. return e.touches && e.touches.length > 0 ? e.touches :
  71. e.changedTouches && e.changedTouches.length > 0 ? e.changedTouches :
  72. e.targetTouches && e.targetTouches.length > 0 ? e.targetTouches :
  73. [ e ];
  74. },
  75. _classes = {
  76. draggable:"katavorio-draggable", // draggable elements
  77. droppable:"katavorio-droppable", // droppable elements
  78. drag : "katavorio-drag", // elements currently being dragged
  79. selected:"katavorio-drag-selected", // elements in current drag selection
  80. active : "katavorio-drag-active", // droppables that are targets of a currently dragged element
  81. hover : "katavorio-drag-hover", // droppables over which a matching drag element is hovering
  82. noSelect : "katavorio-drag-no-select" // added to the body to provide a hook to suppress text selection
  83. },
  84. _defaultScope = "katavorio-drag-scope",
  85. _events = [ "stop", "start", "drag", "drop", "over", "out" ],
  86. _devNull = function() {},
  87. _true = function() { return true; },
  88. _foreach = function(l, fn, from) {
  89. for (var i = 0; i < l.length; i++) {
  90. if (l[i] != from)
  91. fn(l[i]);
  92. }
  93. },
  94. _setDroppablesActive = function(dd, val, andHover, drag) {
  95. _foreach(dd, function(e) {
  96. e.setActive(val);
  97. if (val) e.updatePosition();
  98. if (andHover) e.setHover(drag, val);
  99. });
  100. },
  101. _each = function(obj, fn) {
  102. if (obj == null) return;
  103. obj = (typeof obj !== "string") && (obj.tagName == null && obj.length != null) ? obj : [ obj ];
  104. for (var i = 0; i < obj.length; i++)
  105. fn.apply(obj[i], [ obj[i] ]);
  106. },
  107. _consume = function(e) {
  108. if (e.stopPropagation) {
  109. e.stopPropagation();
  110. e.preventDefault();
  111. }
  112. else {
  113. e.returnValue = false;
  114. }
  115. },
  116. _defaultInputFilterSelector = "input,textarea,select,button",
  117. //
  118. // filters out events on all input elements, like textarea, checkbox, input, select.
  119. _inputFilter = function(e, el, _katavorio) {
  120. var t = e.srcElement || e.target;
  121. return !matchesSelector(t, _katavorio.getInputFilterSelector(), el);
  122. };
  123. var Super = function(el, params, css, scope) {
  124. this.params = params || {};
  125. this.el = el;
  126. this.params.addClass(this.el, this._class);
  127. var enabled = true;
  128. this.setEnabled = function(e) { enabled = e; };
  129. this.isEnabled = function() { return enabled; };
  130. this.toggleEnabled = function() { enabled = !enabled; };
  131. this.setScope = function(scopes) {
  132. this.scopes = scopes ? scopes.split(/\s+/) : [ scope ];
  133. };
  134. this.addScope = function(scopes) {
  135. var m = {};
  136. _each(this.scopes, function(s) { m[s] = true;});
  137. _each(scopes ? scopes.split(/\s+/) : [], function(s) { m[s] = true;});
  138. this.scopes = [];
  139. for (var i in m) this.scopes.push(i);
  140. };
  141. this.removeScope = function(scopes) {
  142. var m = {};
  143. _each(this.scopes, function(s) { m[s] = true;});
  144. _each(scopes ? scopes.split(/\s+/) : [], function(s) { delete m[s];});
  145. this.scopes = [];
  146. for (var i in m) this.scopes.push(i);
  147. };
  148. this.toggleScope = function(scopes) {
  149. var m = {};
  150. _each(this.scopes, function(s) { m[s] = true;});
  151. _each(scopes ? scopes.split(/\s+/) : [], function(s) {
  152. if (m[s]) delete m[s];
  153. else m[s] = true;
  154. });
  155. this.scopes = [];
  156. for (var i in m) this.scopes.push(i);
  157. };
  158. this.setScope(params.scope);
  159. this.k = params.katavorio;
  160. return params.katavorio;
  161. };
  162. var Drag = function(el, params, css, scope) {
  163. this._class = css.draggable;
  164. var k = Super.apply(this, arguments);
  165. this.rightButtonCanDrag = this.params.rightButtonCanDrag;
  166. var downAt = [0,0], posAtDown = null, moving = false,
  167. consumeStartEvent = this.params.consumeStartEvent !== false,
  168. dragEl = this.el,
  169. clone = this.params.clone;
  170. this.toGrid = function(pos) {
  171. return this.params.grid == null ? pos :
  172. [
  173. this.params.grid[0] * Math.floor(pos[0] / this.params.grid[0]),
  174. this.params.grid[1] * Math.floor(pos[1] / this.params.grid[1])
  175. ];
  176. };
  177. this.constrain = typeof this.params.constrain === "function" ? this.params.constrain : (this.params.constrain || this.params.containment) ? function(pos) {
  178. return [
  179. Math.max(0, Math.min(constrainRect.w - this.size[0], pos[0])),
  180. Math.max(0, Math.min(constrainRect.h - this.size[1], pos[1]))
  181. ];
  182. } : function(pos) { return pos; };
  183. var filter = _true,
  184. filterSpec = "",
  185. filterExclude = this.params.filterExclude !== false,
  186. _setFilter = this.setFilter = function(f, _exclude) {
  187. if (f) {
  188. filterSpec = f;
  189. filterExclude = _exclude !== false;
  190. filter = function(e) {
  191. var t = e.srcElement || e.target, ms = matchesSelector(t, f, el);
  192. return filterExclude ? !ms : ms;
  193. };
  194. }
  195. };
  196. this.canDrag = this.params.canDrag || _true;
  197. var constrainRect,
  198. matchingDroppables = [], intersectingDroppables = [];
  199. this.downListener = function(e) {
  200. var isNotRightClick = this.rightButtonCanDrag || (e.which !== 3 && e.button !== 2);
  201. if (isNotRightClick && this.isEnabled() && this.canDrag()) {
  202. var _f = filter(e) && _inputFilter(e, this.el, this.k);
  203. if (_f) {
  204. if (!clone)
  205. dragEl = this.el;
  206. else {
  207. dragEl = this.el.cloneNode(true);
  208. dragEl.setAttribute("id", null);
  209. dragEl.style.position = "absolute";
  210. // the clone node is added to the body; getOffsetRect gives us a value
  211. // relative to the body.
  212. var b = getOffsetRect(this.el);
  213. dragEl.style.left = b.left + "px";
  214. dragEl.style.top = b.top + "px";
  215. document.body.appendChild(dragEl);
  216. }
  217. consumeStartEvent && _consume(e);
  218. downAt = _pl(e);
  219. //
  220. this.params.bind(document, "mousemove", this.moveListener);
  221. this.params.bind(document, "mouseup", this.upListener);
  222. k.markSelection(this);
  223. this.params.addClass(document.body, css.noSelect);
  224. }
  225. else if (this.params.consumeFilteredEvents) {
  226. _consume(e);
  227. }
  228. }
  229. }.bind(this);
  230. this.moveListener = function(e) {
  231. if (downAt) {
  232. if (!moving) {
  233. this.params.events["start"]({el:this.el, pos:posAtDown, e:e, drag:this});
  234. this.mark();
  235. moving = true;
  236. }
  237. intersectingDroppables.length = 0;
  238. var pos = _pl(e), dx = pos[0] - downAt[0], dy = pos[1] - downAt[1],
  239. z = this.params.ignoreZoom ? 1 : k.getZoom();
  240. dx /= z;
  241. dy /= z;
  242. this.moveBy(dx, dy, e);
  243. k.updateSelection(dx, dy, this);
  244. }
  245. }.bind(this);
  246. this.upListener = function(e) {
  247. downAt = null;
  248. moving = false;
  249. this.params.unbind(document, "mousemove", this.moveListener);
  250. this.params.unbind(document, "mouseup", this.upListener);
  251. this.params.removeClass(document.body, css.noSelect);
  252. this.unmark(e);
  253. k.unmarkSelection(this, e);
  254. this.stop(e);
  255. k.notifySelectionDragStop(this, e);
  256. if (clone) {
  257. dragEl && dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
  258. dragEl = null;
  259. }
  260. }.bind(this);
  261. this.getFilter = function() { return filterSpec; };
  262. this.isFilterExclude = function() { return filterExclude; };
  263. this.abort = function() {
  264. if (downAt != null)
  265. this.upListener();
  266. };
  267. this.getDragElement = function() {
  268. return dragEl || this.el;
  269. };
  270. this.stop = function(e) {
  271. this.params.events["stop"]({el:dragEl, pos:this.params.getPosition(dragEl), e:e, drag:this});
  272. };
  273. this.mark = function() {
  274. posAtDown = this.params.getPosition(dragEl);
  275. this.size = this.params.getSize(dragEl);
  276. matchingDroppables = k.getMatchingDroppables(this);
  277. _setDroppablesActive(matchingDroppables, true, false, this);
  278. this.params.addClass(dragEl, this.params.dragClass || css.drag);
  279. if (this.params.constrain || this.params.containment) {
  280. var cs = this.params.getSize(dragEl.parentNode);
  281. constrainRect = { w:cs[0], h:cs[1] };
  282. }
  283. };
  284. this.unmark = function(e) {
  285. _setDroppablesActive(matchingDroppables, false, true, this);
  286. matchingDroppables.length = 0;
  287. for (var i = 0; i < intersectingDroppables.length; i++)
  288. intersectingDroppables[i].drop(this, e);
  289. };
  290. this.moveBy = function(dx, dy, e) {
  291. intersectingDroppables.length = 0;
  292. var cPos = this.constrain(this.toGrid(([posAtDown[0] + dx, posAtDown[1] + dy])), dragEl),
  293. rect = { x:cPos[0], y:cPos[1], w:this.size[0], h:this.size[1]};
  294. this.params.setPosition(dragEl, cPos);
  295. for (var i = 0; i < matchingDroppables.length; i++) {
  296. var r2 = { x:matchingDroppables[i].position[0], y:matchingDroppables[i].position[1], w:matchingDroppables[i].size[0], h:matchingDroppables[i].size[1]};
  297. if (this.params.intersects(rect, r2) && matchingDroppables[i].canDrop(this)) {
  298. intersectingDroppables.push(matchingDroppables[i]);
  299. matchingDroppables[i].setHover(this, true, e);
  300. }
  301. else if (matchingDroppables[i].el._katavorioDragHover) {
  302. matchingDroppables[i].setHover(this, false, e);
  303. }
  304. }
  305. this.params.events["drag"]({el:this.el, pos:cPos, e:e, drag:this});
  306. };
  307. this.destroy = function() {
  308. this.params.unbind(this.el, "mousedown", this.downListener);
  309. this.params.unbind(document, "mousemove", this.moveListener);
  310. this.params.unbind(document, "mouseup", this.upListener);
  311. this.downListener = null;
  312. this.upListener = null;
  313. this.moveListener = null;
  314. //this.params = null;
  315. //this.el = null;
  316. //dragEl = null;
  317. };
  318. // init:register mousedown, and perhaps set a filter
  319. this.params.bind(this.el, "mousedown", this.downListener);
  320. // if handle provded, use that. otherwise, try to set a filter.
  321. // note that a `handle` selector always results in filterExclude being set to false, ie.
  322. // the selector defines the handle element(s).
  323. if (this.params.handle)
  324. _setFilter(this.params.handle, false);
  325. else
  326. _setFilter(this.params.filter, this.params.filterExclude);
  327. };
  328. var Drop = function(el, params, css, scope) {
  329. this._class = css.droppable;
  330. this.params = params || {};
  331. this._activeClass = params.activeClass || css.active;
  332. this._hoverClass = params.hoverClass || css.hover;
  333. Super.apply(this, arguments)
  334. var hover = false;
  335. this.setActive = function(val) {
  336. this.params[val ? "addClass" : "removeClass"](this.el, this._activeClass);
  337. };
  338. this.updatePosition = function() {
  339. this.position = this.params.getPosition(this.el);
  340. this.size = this.params.getSize(this.el);
  341. };
  342. this.canDrop = this.params.canDrop || function(drag) {
  343. return true;
  344. };
  345. this.setHover = function(drag, val, e) {
  346. // if turning off hover but this was not the drag that caused the hover, ignore.
  347. if (val || this.el._katavorioDragHover == null || this.el._katavorioDragHover == drag.el._katavorio) {
  348. this.params[val ? "addClass" : "removeClass"](this.el, this._hoverClass);
  349. this.el._katavorioDragHover = val ? drag.el._katavorio : null;
  350. if (hover !== val)
  351. this.params.events[val ? "over" : "out"]({el:this.el, e:e, drag:drag, drop:this});
  352. hover = val;
  353. }
  354. };
  355. this.drop = function(drag, event) {
  356. this.params.events["drop"]({ drag:drag, e:event, drop:this });
  357. };
  358. this.destroy = function() {
  359. this._class = null;
  360. this._activeClass = null;
  361. this._hoverClass = null;
  362. //this.params = null;
  363. hover = null;
  364. //this.el = null;
  365. };
  366. };
  367. var _uuid = function() {
  368. return ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  369. var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  370. return v.toString(16);
  371. }));
  372. };
  373. var _gel = function(el) {
  374. if (el == null) return null;
  375. el = typeof el === "string" ? document.getElementById(el) : el;
  376. if (el == null) return null;
  377. el._katavorio = el._katavorio || _uuid();
  378. return el;
  379. };
  380. this.Katavorio = function(katavorioParams) {
  381. var _selection = [],
  382. _selectionMap = {};
  383. this._dragsByScope = {};
  384. this._dropsByScope = {};
  385. var _zoom = 1,
  386. _reg = function(obj, map) {
  387. for(var i = 0; i < obj.scopes.length; i++) {
  388. map[obj.scopes[i]] = map[obj.scopes[i]] || [];
  389. map[obj.scopes[i]].push(obj);
  390. }
  391. },
  392. _unreg = function(obj, map) {
  393. var c = 0;
  394. for(var i = 0; i < obj.scopes.length; i++) {
  395. if (map[obj.scopes[i]]) {
  396. var idx = katavorioParams.indexOf(map[obj.scopes[i]], obj);
  397. if (idx != -1) {
  398. map[obj.scopes[i]].splice(idx, 1);
  399. c++;
  400. }
  401. }
  402. }
  403. return c > 0 ;
  404. },
  405. _getMatchingDroppables = this.getMatchingDroppables = function(drag) {
  406. var dd = [], _m = {};
  407. for (var i = 0; i < drag.scopes.length; i++) {
  408. var _dd = this._dropsByScope[drag.scopes[i]];
  409. if (_dd) {
  410. for (var j = 0; j < _dd.length; j++) {
  411. if (_dd[j].canDrop(drag) && !_m[_dd[j].el._katavorio] && _dd[j].el !== drag.el) {
  412. _m[_dd[j].el._katavorio] = true;
  413. dd.push(_dd[j]);
  414. }
  415. }
  416. }
  417. }
  418. return dd;
  419. },
  420. _prepareParams = function(p) {
  421. p = p || {};
  422. var _p = {
  423. events:{}
  424. };
  425. for (var i in katavorioParams) _p[i] = katavorioParams[i];
  426. for (var i in p) _p[i] = p[i];
  427. // events
  428. for (var i = 0; i < _events.length; i++) {
  429. _p.events[_events[i]] = p[_events[i]] || _devNull;
  430. }
  431. _p.katavorio = this;
  432. return _p;
  433. }.bind(this),
  434. _css = {},
  435. overrideCss = katavorioParams.css || {},
  436. _scope = katavorioParams.scope || _defaultScope;
  437. // prepare map of css classes based on defaults frst, then optional overrides
  438. for (var i in _classes) _css[i] = _classes[i];
  439. for (var i in overrideCss) _css[i] = overrideCss[i];
  440. var inputFilterSelector = katavorioParams.inputFilterSelector || _defaultInputFilterSelector;
  441. /**
  442. * Gets the selector identifying which input elements to filter from drag events.
  443. * @method getInputFilterSelector
  444. * @return {String} Current input filter selector.
  445. */
  446. this.getInputFilterSelector = function() { return inputFilterSelector; };
  447. /**
  448. * Sets the selector identifying which input elements to filter from drag events.
  449. * @method setInputFilterSelector
  450. * @param {String} selector Input filter selector to set.
  451. * @return {Katavorio} Current instance; method may be chained.
  452. */
  453. this.setInputFilterSelector = function(selector) {
  454. inputFilterSelector = selector;
  455. return this;
  456. };
  457. this.draggable = function(el, params) {
  458. var o = [];
  459. _each(el, function(_el) {
  460. _el = _gel(_el);
  461. if (_el != null) {
  462. var p = _prepareParams(params);
  463. _el._katavorioDrag = new Drag(_el, p, _css, _scope);
  464. _reg(_el._katavorioDrag, this._dragsByScope);
  465. o.push(_el._katavorioDrag);
  466. katavorioParams.addClass(_el, _css.draggable);
  467. }
  468. }.bind(this));
  469. return o;
  470. };
  471. this.droppable = function(el, params) {
  472. var o = [];
  473. _each(el, function(_el) {
  474. _el = _gel(_el);
  475. if (_el != null) {
  476. _el._katavorioDrop = new Drop(_el, _prepareParams(params), _css, _scope);
  477. _reg(_el._katavorioDrop, this._dropsByScope);
  478. o.push(_el._katavorioDrop);
  479. katavorioParams.addClass(_el, _css.droppable);
  480. }
  481. }.bind(this));
  482. return o;
  483. };
  484. /**
  485. * @name Katavorio#select
  486. * @function
  487. * @desc Adds an element to the current selection (for multiple node drag)
  488. * @param {Element|String} DOM element - or id of the element - to add.
  489. */
  490. this.select = function(el) {
  491. _each(el, function() {
  492. var _el = _gel(this);
  493. if (_el && _el._katavorioDrag) {
  494. if (!_selectionMap[_el._katavorio]) {
  495. _selection.push(_el._katavorioDrag);
  496. _selectionMap[_el._katavorio] = [ _el, _selection.length - 1 ];
  497. katavorioParams.addClass(_el, _css.selected);
  498. }
  499. }
  500. });
  501. return this;
  502. };
  503. /**
  504. * @name Katavorio#deselect
  505. * @function
  506. * @desc Removes an element from the current selection (for multiple node drag)
  507. * @param {Element|String} DOM element - or id of the element - to remove.
  508. */
  509. this.deselect = function(el) {
  510. _each(el, function() {
  511. var _el = _gel(this);
  512. if (_el && _el._katavorio) {
  513. var e = _selectionMap[_el._katavorio];
  514. if (e) {
  515. var _s = [];
  516. for (var i = 0; i < _selection.length; i++)
  517. if (_selection[i].el !== _el) _s.push(_selection[i]);
  518. _selection = _s;
  519. delete _selectionMap[_el._katavorio];
  520. katavorioParams.removeClass(_el, _css.selected);
  521. }
  522. }
  523. });
  524. return this;
  525. };
  526. this.deselectAll = function() {
  527. for (var i in _selectionMap) {
  528. var d = _selectionMap[i];
  529. katavorioParams.removeClass(d[0], _css.selected);
  530. }
  531. _selection.length = 0;
  532. _selectionMap = {};
  533. };
  534. this.markSelection = function(drag) {
  535. _foreach(_selection, function(e) { e.mark(); }, drag);
  536. };
  537. this.unmarkSelection = function(drag, event) {
  538. _foreach(_selection, function(e) { e.unmark(event); }, drag);
  539. };
  540. this.getSelection = function() { return _selection.slice(0); };
  541. this.updateSelection = function(dx, dy, drag) {
  542. _foreach(_selection, function(e) { e.moveBy(dx, dy); }, drag);
  543. };
  544. this.notifySelectionDragStop = function(drag, evt) {
  545. _foreach(_selection, function(e) { e.stop(evt); }, drag);
  546. };
  547. this.setZoom = function(z) { _zoom = z; };
  548. this.getZoom = function() { return _zoom; };
  549. // does the work of changing scopes
  550. var _scopeManip = function(kObj, scopes, map, fn) {
  551. if (kObj != null) {
  552. _unreg(kObj, map); // deregister existing scopes
  553. kObj[fn](scopes); // set scopes
  554. _reg(kObj, map); // register new ones
  555. }
  556. };
  557. _each([ "set", "add", "remove", "toggle"], function(v) {
  558. this[v + "Scope"] = function(el, scopes) {
  559. _scopeManip(el._katavorioDrag, scopes, this._dragsByScope, v + "Scope");
  560. _scopeManip(el._katavorioDrop, scopes, this._dropsByScope, v + "Scope");
  561. }.bind(this);
  562. this[v + "DragScope"] = function(el, scopes) {
  563. _scopeManip(el._katavorioDrag, scopes, this._dragsByScope, v + "Scope");
  564. }.bind(this);
  565. this[v + "DropScope"] = function(el, scopes) {
  566. _scopeManip(el._katavorioDrop, scopes, this._dropsByScope, v + "Scope");
  567. }.bind(this);
  568. }.bind(this));
  569. this.getDragsForScope = function(s) { return this._dragsByScope[s]; };
  570. this.getDropsForScope = function(s) { return this._dropsByScope[s]; };
  571. var _destroy = function(el, type, map) {
  572. el = _gel(el);
  573. if (el[type]) {
  574. if (_unreg(el[type], map))
  575. el[type].destroy();
  576. el[type] = null;
  577. }
  578. };
  579. this.elementRemoved = function(el) {
  580. this.destroyDraggable(el);
  581. this.destroyDroppable(el);
  582. };
  583. this.destroyDraggable = function(el) {
  584. _destroy(el, "_katavorioDrag", this._dragsByScope);
  585. };
  586. this.destroyDroppable = function(el) {
  587. _destroy(el, "_katavorioDrop", this._dropsByScope);
  588. };
  589. };
  590. }).call(this);