sonata_jqueryui_js_jquery.ui.droppable_5.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*!
  2. * jQuery UI Droppable 1.10.4
  3. * http://jqueryui.com
  4. *
  5. * Copyright 2014 jQuery Foundation and other contributors
  6. * Released under the MIT license.
  7. * http://jquery.org/license
  8. *
  9. * http://api.jqueryui.com/droppable/
  10. *
  11. * Depends:
  12. * jquery.ui.core.js
  13. * jquery.ui.widget.js
  14. * jquery.ui.mouse.js
  15. * jquery.ui.draggable.js
  16. */
  17. (function( $, undefined ) {
  18. function isOverAxis( x, reference, size ) {
  19. return ( x > reference ) && ( x < ( reference + size ) );
  20. }
  21. $.widget("ui.droppable", {
  22. version: "1.10.4",
  23. widgetEventPrefix: "drop",
  24. options: {
  25. accept: "*",
  26. activeClass: false,
  27. addClasses: true,
  28. greedy: false,
  29. hoverClass: false,
  30. scope: "default",
  31. tolerance: "intersect",
  32. // callbacks
  33. activate: null,
  34. deactivate: null,
  35. drop: null,
  36. out: null,
  37. over: null
  38. },
  39. _create: function() {
  40. var proportions,
  41. o = this.options,
  42. accept = o.accept;
  43. this.isover = false;
  44. this.isout = true;
  45. this.accept = $.isFunction(accept) ? accept : function(d) {
  46. return d.is(accept);
  47. };
  48. this.proportions = function( /* valueToWrite */ ) {
  49. if ( arguments.length ) {
  50. // Store the droppable's proportions
  51. proportions = arguments[ 0 ];
  52. } else {
  53. // Retrieve or derive the droppable's proportions
  54. return proportions ?
  55. proportions :
  56. proportions = {
  57. width: this.element[ 0 ].offsetWidth,
  58. height: this.element[ 0 ].offsetHeight
  59. };
  60. }
  61. };
  62. // Add the reference and positions to the manager
  63. $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
  64. $.ui.ddmanager.droppables[o.scope].push(this);
  65. (o.addClasses && this.element.addClass("ui-droppable"));
  66. },
  67. _destroy: function() {
  68. var i = 0,
  69. drop = $.ui.ddmanager.droppables[this.options.scope];
  70. for ( ; i < drop.length; i++ ) {
  71. if ( drop[i] === this ) {
  72. drop.splice(i, 1);
  73. }
  74. }
  75. this.element.removeClass("ui-droppable ui-droppable-disabled");
  76. },
  77. _setOption: function(key, value) {
  78. if(key === "accept") {
  79. this.accept = $.isFunction(value) ? value : function(d) {
  80. return d.is(value);
  81. };
  82. }
  83. $.Widget.prototype._setOption.apply(this, arguments);
  84. },
  85. _activate: function(event) {
  86. var draggable = $.ui.ddmanager.current;
  87. if(this.options.activeClass) {
  88. this.element.addClass(this.options.activeClass);
  89. }
  90. if(draggable){
  91. this._trigger("activate", event, this.ui(draggable));
  92. }
  93. },
  94. _deactivate: function(event) {
  95. var draggable = $.ui.ddmanager.current;
  96. if(this.options.activeClass) {
  97. this.element.removeClass(this.options.activeClass);
  98. }
  99. if(draggable){
  100. this._trigger("deactivate", event, this.ui(draggable));
  101. }
  102. },
  103. _over: function(event) {
  104. var draggable = $.ui.ddmanager.current;
  105. // Bail if draggable and droppable are same element
  106. if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
  107. return;
  108. }
  109. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  110. if(this.options.hoverClass) {
  111. this.element.addClass(this.options.hoverClass);
  112. }
  113. this._trigger("over", event, this.ui(draggable));
  114. }
  115. },
  116. _out: function(event) {
  117. var draggable = $.ui.ddmanager.current;
  118. // Bail if draggable and droppable are same element
  119. if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
  120. return;
  121. }
  122. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  123. if(this.options.hoverClass) {
  124. this.element.removeClass(this.options.hoverClass);
  125. }
  126. this._trigger("out", event, this.ui(draggable));
  127. }
  128. },
  129. _drop: function(event,custom) {
  130. var draggable = custom || $.ui.ddmanager.current,
  131. childrenIntersection = false;
  132. // Bail if draggable and droppable are same element
  133. if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
  134. return false;
  135. }
  136. this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
  137. var inst = $.data(this, "ui-droppable");
  138. if(
  139. inst.options.greedy &&
  140. !inst.options.disabled &&
  141. inst.options.scope === draggable.options.scope &&
  142. inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
  143. $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
  144. ) { childrenIntersection = true; return false; }
  145. });
  146. if(childrenIntersection) {
  147. return false;
  148. }
  149. if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  150. if(this.options.activeClass) {
  151. this.element.removeClass(this.options.activeClass);
  152. }
  153. if(this.options.hoverClass) {
  154. this.element.removeClass(this.options.hoverClass);
  155. }
  156. this._trigger("drop", event, this.ui(draggable));
  157. return this.element;
  158. }
  159. return false;
  160. },
  161. ui: function(c) {
  162. return {
  163. draggable: (c.currentItem || c.element),
  164. helper: c.helper,
  165. position: c.position,
  166. offset: c.positionAbs
  167. };
  168. }
  169. });
  170. $.ui.intersect = function(draggable, droppable, toleranceMode) {
  171. if (!droppable.offset) {
  172. return false;
  173. }
  174. var draggableLeft, draggableTop,
  175. x1 = (draggable.positionAbs || draggable.position.absolute).left,
  176. y1 = (draggable.positionAbs || draggable.position.absolute).top,
  177. x2 = x1 + draggable.helperProportions.width,
  178. y2 = y1 + draggable.helperProportions.height,
  179. l = droppable.offset.left,
  180. t = droppable.offset.top,
  181. r = l + droppable.proportions().width,
  182. b = t + droppable.proportions().height;
  183. switch (toleranceMode) {
  184. case "fit":
  185. return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
  186. case "intersect":
  187. return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
  188. x2 - (draggable.helperProportions.width / 2) < r && // Left Half
  189. t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
  190. y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
  191. case "pointer":
  192. draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
  193. draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
  194. return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
  195. case "touch":
  196. return (
  197. (y1 >= t && y1 <= b) || // Top edge touching
  198. (y2 >= t && y2 <= b) || // Bottom edge touching
  199. (y1 < t && y2 > b) // Surrounded vertically
  200. ) && (
  201. (x1 >= l && x1 <= r) || // Left edge touching
  202. (x2 >= l && x2 <= r) || // Right edge touching
  203. (x1 < l && x2 > r) // Surrounded horizontally
  204. );
  205. default:
  206. return false;
  207. }
  208. };
  209. /*
  210. This manager tracks offsets of draggables and droppables
  211. */
  212. $.ui.ddmanager = {
  213. current: null,
  214. droppables: { "default": [] },
  215. prepareOffsets: function(t, event) {
  216. var i, j,
  217. m = $.ui.ddmanager.droppables[t.options.scope] || [],
  218. type = event ? event.type : null, // workaround for #2317
  219. list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
  220. droppablesLoop: for (i = 0; i < m.length; i++) {
  221. //No disabled and non-accepted
  222. if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
  223. continue;
  224. }
  225. // Filter out elements in the current dragged item
  226. for (j=0; j < list.length; j++) {
  227. if(list[j] === m[i].element[0]) {
  228. m[i].proportions().height = 0;
  229. continue droppablesLoop;
  230. }
  231. }
  232. m[i].visible = m[i].element.css("display") !== "none";
  233. if(!m[i].visible) {
  234. continue;
  235. }
  236. //Activate the droppable if used directly from draggables
  237. if(type === "mousedown") {
  238. m[i]._activate.call(m[i], event);
  239. }
  240. m[ i ].offset = m[ i ].element.offset();
  241. m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
  242. }
  243. },
  244. drop: function(draggable, event) {
  245. var dropped = false;
  246. // Create a copy of the droppables in case the list changes during the drop (#9116)
  247. $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
  248. if(!this.options) {
  249. return;
  250. }
  251. if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
  252. dropped = this._drop.call(this, event) || dropped;
  253. }
  254. if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  255. this.isout = true;
  256. this.isover = false;
  257. this._deactivate.call(this, event);
  258. }
  259. });
  260. return dropped;
  261. },
  262. dragStart: function( draggable, event ) {
  263. //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
  264. draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
  265. if( !draggable.options.refreshPositions ) {
  266. $.ui.ddmanager.prepareOffsets( draggable, event );
  267. }
  268. });
  269. },
  270. drag: function(draggable, event) {
  271. //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
  272. if(draggable.options.refreshPositions) {
  273. $.ui.ddmanager.prepareOffsets(draggable, event);
  274. }
  275. //Run through all droppables and check their positions based on specific tolerance options
  276. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  277. if(this.options.disabled || this.greedyChild || !this.visible) {
  278. return;
  279. }
  280. var parentInstance, scope, parent,
  281. intersects = $.ui.intersect(draggable, this, this.options.tolerance),
  282. c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
  283. if(!c) {
  284. return;
  285. }
  286. if (this.options.greedy) {
  287. // find droppable parents with same scope
  288. scope = this.options.scope;
  289. parent = this.element.parents(":data(ui-droppable)").filter(function () {
  290. return $.data(this, "ui-droppable").options.scope === scope;
  291. });
  292. if (parent.length) {
  293. parentInstance = $.data(parent[0], "ui-droppable");
  294. parentInstance.greedyChild = (c === "isover");
  295. }
  296. }
  297. // we just moved into a greedy child
  298. if (parentInstance && c === "isover") {
  299. parentInstance.isover = false;
  300. parentInstance.isout = true;
  301. parentInstance._out.call(parentInstance, event);
  302. }
  303. this[c] = true;
  304. this[c === "isout" ? "isover" : "isout"] = false;
  305. this[c === "isover" ? "_over" : "_out"].call(this, event);
  306. // we just moved out of a greedy child
  307. if (parentInstance && c === "isout") {
  308. parentInstance.isout = false;
  309. parentInstance.isover = true;
  310. parentInstance._over.call(parentInstance, event);
  311. }
  312. });
  313. },
  314. dragStop: function( draggable, event ) {
  315. draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
  316. //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
  317. if( !draggable.options.refreshPositions ) {
  318. $.ui.ddmanager.prepareOffsets( draggable, event );
  319. }
  320. }
  321. };
  322. })(jQuery);