Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dd-ddm-drop-debug.js 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('dd-ddm-drop', function(Y) {
  9. /**
  10. * Extends the dd-ddm Class to add support for the placement of Drop Target shims inside the viewport shim. It also handles all Drop Target related events and interactions.
  11. * @module dd
  12. * @submodule dd-ddm-drop
  13. * @for DDM
  14. * @namespace DD
  15. */
  16. //TODO CSS class name for the bestMatch..
  17. Y.mix(Y.DD.DDM, {
  18. /**
  19. * @private
  20. * @property _noShim
  21. * @description This flag turns off the use of the mouseover/mouseout shim. It should not be used unless you know what you are doing.
  22. * @type {Boolean}
  23. */
  24. _noShim: false,
  25. /**
  26. * @private
  27. * @property _activeShims
  28. * @description Placeholder for all active shims on the page
  29. * @type {Array}
  30. */
  31. _activeShims: [],
  32. /**
  33. * @private
  34. * @method _hasActiveShim
  35. * @description This method checks the _activeShims Object to see if there is a shim active.
  36. * @return {Boolean}
  37. */
  38. _hasActiveShim: function() {
  39. if (this._noShim) {
  40. return true;
  41. }
  42. return this._activeShims.length;
  43. },
  44. /**
  45. * @private
  46. * @method _addActiveShim
  47. * @description Adds a Drop Target to the list of active shims
  48. * @param {Object} d The Drop instance to add to the list.
  49. */
  50. _addActiveShim: function(d) {
  51. this._activeShims[this._activeShims.length] = d;
  52. },
  53. /**
  54. * @private
  55. * @method _removeActiveShim
  56. * @description Removes a Drop Target to the list of active shims
  57. * @param {Object} d The Drop instance to remove from the list.
  58. */
  59. _removeActiveShim: function(d) {
  60. var s = [];
  61. Y.each(this._activeShims, function(v, k) {
  62. if (v._yuid !== d._yuid) {
  63. s[s.length] = v;
  64. }
  65. });
  66. this._activeShims = s;
  67. },
  68. /**
  69. * @method syncActiveShims
  70. * @description This method will sync the position of the shims on the Drop Targets that are currently active.
  71. * @param {Boolean} force Resize/sync all Targets.
  72. */
  73. syncActiveShims: function(force) {
  74. Y.later(0, this, function(force) {
  75. var drops = ((force) ? this.targets : this._lookup());
  76. Y.each(drops, function(v, k) {
  77. v.sizeShim.call(v);
  78. }, this);
  79. }, force);
  80. },
  81. /**
  82. * @private
  83. * @property mode
  84. * @description The mode that the drag operations will run in 0 for Point, 1 for Intersect, 2 for Strict
  85. * @type Number
  86. */
  87. mode: 0,
  88. /**
  89. * @private
  90. * @property POINT
  91. * @description In point mode, a Drop is targeted by the cursor being over the Target
  92. * @type Number
  93. */
  94. POINT: 0,
  95. /**
  96. * @private
  97. * @property INTERSECT
  98. * @description In intersect mode, a Drop is targeted by "part" of the drag node being over the Target
  99. * @type Number
  100. */
  101. INTERSECT: 1,
  102. /**
  103. * @private
  104. * @property STRICT
  105. * @description In strict mode, a Drop is targeted by the "entire" drag node being over the Target
  106. * @type Number
  107. */
  108. STRICT: 2,
  109. /**
  110. * @property useHash
  111. * @description Should we only check targets that are in the viewport on drags (for performance), default: true
  112. * @type {Boolean}
  113. */
  114. useHash: true,
  115. /**
  116. * @property activeDrop
  117. * @description A reference to the active Drop Target
  118. * @type {Object}
  119. */
  120. activeDrop: null,
  121. /**
  122. * @property validDrops
  123. * @description An array of the valid Drop Targets for this interaction.
  124. * @type {Array}
  125. */
  126. //TODO Change array/object literals to be in sync..
  127. validDrops: [],
  128. /**
  129. * @property otherDrops
  130. * @description An object literal of Other Drop Targets that we encountered during this interaction (in the case of overlapping Drop Targets)
  131. * @type {Object}
  132. */
  133. otherDrops: {},
  134. /**
  135. * @property targets
  136. * @description All of the Targets
  137. * @type {Array}
  138. */
  139. targets: [],
  140. /**
  141. * @private
  142. * @method _addValid
  143. * @description Add a Drop Target to the list of Valid Targets. This list get's regenerated on each new drag operation.
  144. * @param {Object} drop
  145. * @return {Self}
  146. * @chainable
  147. */
  148. _addValid: function(drop) {
  149. this.validDrops[this.validDrops.length] = drop;
  150. return this;
  151. },
  152. /**
  153. * @private
  154. * @method _removeValid
  155. * @description Removes a Drop Target from the list of Valid Targets. This list get's regenerated on each new drag operation.
  156. * @param {Object} drop
  157. * @return {Self}
  158. * @chainable
  159. */
  160. _removeValid: function(drop) {
  161. var drops = [];
  162. Y.each(this.validDrops, function(v, k) {
  163. if (v !== drop) {
  164. drops[drops.length] = v;
  165. }
  166. });
  167. this.validDrops = drops;
  168. return this;
  169. },
  170. /**
  171. * @method isOverTarget
  172. * @description Check to see if the Drag element is over the target, method varies on current mode
  173. * @param {Object} drop The drop to check against
  174. * @return {Boolean}
  175. */
  176. isOverTarget: function(drop) {
  177. if (this.activeDrag && drop) {
  178. var xy = this.activeDrag.mouseXY, r, dMode = this.activeDrag.get('dragMode'),
  179. aRegion, node = drop.shim;
  180. if (xy && this.activeDrag) {
  181. aRegion = this.activeDrag.region;
  182. if (dMode == this.STRICT) {
  183. return this.activeDrag.get('dragNode').inRegion(drop.region, true, aRegion);
  184. } else {
  185. if (drop && drop.shim) {
  186. if ((dMode == this.INTERSECT) && this._noShim) {
  187. r = ((aRegion) ? aRegion : this.activeDrag.get('node'));
  188. return drop.get('node').intersect(r, drop.region).inRegion;
  189. } else {
  190. if (this._noShim) {
  191. node = drop.get('node');
  192. }
  193. return node.intersect({
  194. top: xy[1],
  195. bottom: xy[1],
  196. left: xy[0],
  197. right: xy[0]
  198. }, drop.region).inRegion;
  199. }
  200. } else {
  201. return false;
  202. }
  203. }
  204. } else {
  205. return false;
  206. }
  207. } else {
  208. return false;
  209. }
  210. },
  211. /**
  212. * @method clearCache
  213. * @description Clears the cache data used for this interaction.
  214. */
  215. clearCache: function() {
  216. this.validDrops = [];
  217. this.otherDrops = {};
  218. this._activeShims = [];
  219. },
  220. /**
  221. * @private
  222. * @method _activateTargets
  223. * @description Clear the cache and activate the shims of all the targets
  224. */
  225. _activateTargets: function() {
  226. this._noShim = true;
  227. this.clearCache();
  228. Y.each(this.targets, function(v, k) {
  229. v._activateShim([]);
  230. if (v.get('noShim') == true) {
  231. this._noShim = false;
  232. }
  233. }, this);
  234. this._handleTargetOver();
  235. },
  236. /**
  237. * @method getBestMatch
  238. * @description This method will gather the area for all potential targets and see which has the hightest covered area and return it.
  239. * @param {Array} drops An Array of drops to scan for the best match.
  240. * @param {Boolean} all If present, it returns an Array. First item is best match, second is an Array of the other items in the original Array.
  241. * @return {Object or Array}
  242. */
  243. getBestMatch: function(drops, all) {
  244. var biggest = null, area = 0, out;
  245. Y.each(drops, function(v, k) {
  246. var inter = this.activeDrag.get('dragNode').intersect(v.get('node'));
  247. v.region.area = inter.area;
  248. if (inter.inRegion) {
  249. if (inter.area > area) {
  250. area = inter.area;
  251. biggest = v;
  252. }
  253. }
  254. }, this);
  255. if (all) {
  256. out = [];
  257. //TODO Sort the others in numeric order by area covered..
  258. Y.each(drops, function(v, k) {
  259. if (v !== biggest) {
  260. out[out.length] = v;
  261. }
  262. }, this);
  263. return [biggest, out];
  264. } else {
  265. return biggest;
  266. }
  267. },
  268. /**
  269. * @private
  270. * @method _deactivateTargets
  271. * @description This method fires the drop:hit, drag:drophit, drag:dropmiss methods and deactivates the shims..
  272. */
  273. _deactivateTargets: function() {
  274. var other = [], tmp,
  275. activeDrag = this.activeDrag,
  276. activeDrop = this.activeDrop;
  277. //TODO why is this check so hard??
  278. if (activeDrag && activeDrop && this.otherDrops[activeDrop]) {
  279. if (!activeDrag.get('dragMode')) {
  280. //TODO otherDrops -- private..
  281. other = this.otherDrops;
  282. delete other[activeDrop];
  283. } else {
  284. tmp = this.getBestMatch(this.otherDrops, true);
  285. activeDrop = tmp[0];
  286. other = tmp[1];
  287. }
  288. activeDrag.get('node').removeClass(this.CSS_PREFIX + '-drag-over');
  289. if (activeDrop) {
  290. activeDrop.fire('drop:hit', { drag: activeDrag, drop: activeDrop, others: other });
  291. activeDrag.fire('drag:drophit', { drag: activeDrag, drop: activeDrop, others: other });
  292. }
  293. } else if (activeDrag && activeDrag.get('dragging')) {
  294. activeDrag.get('node').removeClass(this.CSS_PREFIX + '-drag-over');
  295. activeDrag.fire('drag:dropmiss', { pageX: activeDrag.lastXY[0], pageY: activeDrag.lastXY[1] });
  296. } else {
  297. }
  298. this.activeDrop = null;
  299. Y.each(this.targets, function(v, k) {
  300. v._deactivateShim([]);
  301. }, this);
  302. },
  303. /**
  304. * @private
  305. * @method _dropMove
  306. * @description This method is called when the move method is called on the Drag Object.
  307. */
  308. _dropMove: function() {
  309. if (this._hasActiveShim()) {
  310. this._handleTargetOver();
  311. } else {
  312. Y.each(this.otherDrops, function(v, k) {
  313. v._handleOut.apply(v, []);
  314. });
  315. }
  316. },
  317. /**
  318. * @private
  319. * @method _lookup
  320. * @description Filters the list of Drops down to those in the viewport.
  321. * @return {Array} The valid Drop Targets that are in the viewport.
  322. */
  323. _lookup: function() {
  324. if (!this.useHash || this._noShim) {
  325. return this.validDrops;
  326. }
  327. var drops = [];
  328. //Only scan drop shims that are in the Viewport
  329. Y.each(this.validDrops, function(v, k) {
  330. if (v.shim && v.shim.inViewportRegion(false, v.region)) {
  331. drops[drops.length] = v;
  332. }
  333. });
  334. return drops;
  335. },
  336. /**
  337. * @private
  338. * @method _handleTargetOver
  339. * @description This method execs _handleTargetOver on all valid Drop Targets
  340. */
  341. _handleTargetOver: function() {
  342. var drops = this._lookup();
  343. Y.each(drops, function(v, k) {
  344. v._handleTargetOver.call(v);
  345. }, this);
  346. },
  347. /**
  348. * @private
  349. * @method _regTarget
  350. * @description Add the passed in Target to the targets collection
  351. * @param {Object} t The Target to add to the targets collection
  352. */
  353. _regTarget: function(t) {
  354. this.targets[this.targets.length] = t;
  355. },
  356. /**
  357. * @private
  358. * @method _unregTarget
  359. * @description Remove the passed in Target from the targets collection
  360. * @param {Object} drop The Target to remove from the targets collection
  361. */
  362. _unregTarget: function(drop) {
  363. var targets = [], vdrops;
  364. Y.each(this.targets, function(v, k) {
  365. if (v != drop) {
  366. targets[targets.length] = v;
  367. }
  368. }, this);
  369. this.targets = targets;
  370. vdrops = [];
  371. Y.each(this.validDrops, function(v, k) {
  372. if (v !== drop) {
  373. vdrops[vdrops.length] = v;
  374. }
  375. });
  376. this.validDrops = vdrops;
  377. },
  378. /**
  379. * @method getDrop
  380. * @description Get a valid Drop instance back from a Node or a selector string, false otherwise
  381. * @param {String/Object} node The Node instance or Selector string to check for a valid Drop Object
  382. * @return {Object}
  383. */
  384. getDrop: function(node) {
  385. var drop = false,
  386. n = Y.one(node);
  387. if (n instanceof Y.Node) {
  388. Y.each(this.targets, function(v, k) {
  389. if (n.compareTo(v.get('node'))) {
  390. drop = v;
  391. }
  392. });
  393. }
  394. return drop;
  395. }
  396. }, true);
  397. }, '3.4.0' ,{skinnable:false, requires:['dd-ddm']});