/javascripts/lib/src/dd/DDCore.js

https://bitbucket.org/ksokmesa/sina-asian · JavaScript · 3158 lines · 1132 code · 380 blank · 1646 comment · 232 complexity · 6352ccaa30807bab7b5f15d830e833c0 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*!
  2. * Ext JS Library 3.2.1
  3. * Copyright(c) 2006-2010 Ext JS, Inc.
  4. * licensing@extjs.com
  5. * http://www.extjs.com/license
  6. */
  7. /*
  8. * These classes are derivatives of the similarly named classes in the YUI Library.
  9. * The original license:
  10. * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
  11. * Code licensed under the BSD License:
  12. * http://developer.yahoo.net/yui/license.txt
  13. */
  14. (function() {
  15. var Event=Ext.EventManager;
  16. var Dom=Ext.lib.Dom;
  17. /**
  18. * @class Ext.dd.DragDrop
  19. * Defines the interface and base operation of items that that can be
  20. * dragged or can be drop targets. It was designed to be extended, overriding
  21. * the event handlers for startDrag, onDrag, onDragOver and onDragOut.
  22. * Up to three html elements can be associated with a DragDrop instance:
  23. * <ul>
  24. * <li>linked element: the element that is passed into the constructor.
  25. * This is the element which defines the boundaries for interaction with
  26. * other DragDrop objects.</li>
  27. * <li>handle element(s): The drag operation only occurs if the element that
  28. * was clicked matches a handle element. By default this is the linked
  29. * element, but there are times that you will want only a portion of the
  30. * linked element to initiate the drag operation, and the setHandleElId()
  31. * method provides a way to define this.</li>
  32. * <li>drag element: this represents the element that would be moved along
  33. * with the cursor during a drag operation. By default, this is the linked
  34. * element itself as in {@link Ext.dd.DD}. setDragElId() lets you define
  35. * a separate element that would be moved, as in {@link Ext.dd.DDProxy}.
  36. * </li>
  37. * </ul>
  38. * This class should not be instantiated until the onload event to ensure that
  39. * the associated elements are available.
  40. * The following would define a DragDrop obj that would interact with any
  41. * other DragDrop obj in the "group1" group:
  42. * <pre>
  43. * dd = new Ext.dd.DragDrop("div1", "group1");
  44. * </pre>
  45. * Since none of the event handlers have been implemented, nothing would
  46. * actually happen if you were to run the code above. Normally you would
  47. * override this class or one of the default implementations, but you can
  48. * also override the methods you want on an instance of the class...
  49. * <pre>
  50. * dd.onDragDrop = function(e, id) {
  51. * &nbsp;&nbsp;alert("dd was dropped on " + id);
  52. * }
  53. * </pre>
  54. * @constructor
  55. * @param {String} id of the element that is linked to this instance
  56. * @param {String} sGroup the group of related DragDrop objects
  57. * @param {object} config an object containing configurable attributes
  58. * Valid properties for DragDrop:
  59. * padding, isTarget, maintainOffset, primaryButtonOnly
  60. */
  61. Ext.dd.DragDrop = function(id, sGroup, config) {
  62. if(id) {
  63. this.init(id, sGroup, config);
  64. }
  65. };
  66. Ext.dd.DragDrop.prototype = {
  67. /**
  68. * Set to false to enable a DragDrop object to fire drag events while dragging
  69. * over its own Element. Defaults to true - DragDrop objects do not by default
  70. * fire drag events to themselves.
  71. * @property ignoreSelf
  72. * @type Boolean
  73. */
  74. /**
  75. * The id of the element associated with this object. This is what we
  76. * refer to as the "linked element" because the size and position of
  77. * this element is used to determine when the drag and drop objects have
  78. * interacted.
  79. * @property id
  80. * @type String
  81. */
  82. id: null,
  83. /**
  84. * Configuration attributes passed into the constructor
  85. * @property config
  86. * @type object
  87. */
  88. config: null,
  89. /**
  90. * The id of the element that will be dragged. By default this is same
  91. * as the linked element, but could be changed to another element. Ex:
  92. * Ext.dd.DDProxy
  93. * @property dragElId
  94. * @type String
  95. * @private
  96. */
  97. dragElId: null,
  98. /**
  99. * The ID of the element that initiates the drag operation. By default
  100. * this is the linked element, but could be changed to be a child of this
  101. * element. This lets us do things like only starting the drag when the
  102. * header element within the linked html element is clicked.
  103. * @property handleElId
  104. * @type String
  105. * @private
  106. */
  107. handleElId: null,
  108. /**
  109. * An object who's property names identify HTML tags to be considered invalid as drag handles.
  110. * A non-null property value identifies the tag as invalid. Defaults to the
  111. * following value which prevents drag operations from being initiated by &lt;a> elements:<pre><code>
  112. {
  113. A: "A"
  114. }</code></pre>
  115. * @property invalidHandleTypes
  116. * @type Object
  117. */
  118. invalidHandleTypes: null,
  119. /**
  120. * An object who's property names identify the IDs of elements to be considered invalid as drag handles.
  121. * A non-null property value identifies the ID as invalid. For example, to prevent
  122. * dragging from being initiated on element ID "foo", use:<pre><code>
  123. {
  124. foo: true
  125. }</code></pre>
  126. * @property invalidHandleIds
  127. * @type Object
  128. */
  129. invalidHandleIds: null,
  130. /**
  131. * An Array of CSS class names for elements to be considered in valid as drag handles.
  132. * @property invalidHandleClasses
  133. * @type Array
  134. */
  135. invalidHandleClasses: null,
  136. /**
  137. * The linked element's absolute X position at the time the drag was
  138. * started
  139. * @property startPageX
  140. * @type int
  141. * @private
  142. */
  143. startPageX: 0,
  144. /**
  145. * The linked element's absolute X position at the time the drag was
  146. * started
  147. * @property startPageY
  148. * @type int
  149. * @private
  150. */
  151. startPageY: 0,
  152. /**
  153. * The group defines a logical collection of DragDrop objects that are
  154. * related. Instances only get events when interacting with other
  155. * DragDrop object in the same group. This lets us define multiple
  156. * groups using a single DragDrop subclass if we want.
  157. * @property groups
  158. * @type object An object in the format {'group1':true, 'group2':true}
  159. */
  160. groups: null,
  161. /**
  162. * Individual drag/drop instances can be locked. This will prevent
  163. * onmousedown start drag.
  164. * @property locked
  165. * @type boolean
  166. * @private
  167. */
  168. locked: false,
  169. /**
  170. * Lock this instance
  171. * @method lock
  172. */
  173. lock: function() {
  174. this.locked = true;
  175. },
  176. /**
  177. * When set to true, other DD objects in cooperating DDGroups do not receive
  178. * notification events when this DD object is dragged over them. Defaults to false.
  179. * @property moveOnly
  180. * @type boolean
  181. */
  182. moveOnly: false,
  183. /**
  184. * Unlock this instace
  185. * @method unlock
  186. */
  187. unlock: function() {
  188. this.locked = false;
  189. },
  190. /**
  191. * By default, all instances can be a drop target. This can be disabled by
  192. * setting isTarget to false.
  193. * @property isTarget
  194. * @type boolean
  195. */
  196. isTarget: true,
  197. /**
  198. * The padding configured for this drag and drop object for calculating
  199. * the drop zone intersection with this object.
  200. * @property padding
  201. * @type int[] An array containing the 4 padding values: [top, right, bottom, left]
  202. */
  203. padding: null,
  204. /**
  205. * Cached reference to the linked element
  206. * @property _domRef
  207. * @private
  208. */
  209. _domRef: null,
  210. /**
  211. * Internal typeof flag
  212. * @property __ygDragDrop
  213. * @private
  214. */
  215. __ygDragDrop: true,
  216. /**
  217. * Set to true when horizontal contraints are applied
  218. * @property constrainX
  219. * @type boolean
  220. * @private
  221. */
  222. constrainX: false,
  223. /**
  224. * Set to true when vertical contraints are applied
  225. * @property constrainY
  226. * @type boolean
  227. * @private
  228. */
  229. constrainY: false,
  230. /**
  231. * The left constraint
  232. * @property minX
  233. * @type int
  234. * @private
  235. */
  236. minX: 0,
  237. /**
  238. * The right constraint
  239. * @property maxX
  240. * @type int
  241. * @private
  242. */
  243. maxX: 0,
  244. /**
  245. * The up constraint
  246. * @property minY
  247. * @type int
  248. * @private
  249. */
  250. minY: 0,
  251. /**
  252. * The down constraint
  253. * @property maxY
  254. * @type int
  255. * @private
  256. */
  257. maxY: 0,
  258. /**
  259. * Maintain offsets when we resetconstraints. Set to true when you want
  260. * the position of the element relative to its parent to stay the same
  261. * when the page changes
  262. *
  263. * @property maintainOffset
  264. * @type boolean
  265. */
  266. maintainOffset: false,
  267. /**
  268. * Array of pixel locations the element will snap to if we specified a
  269. * horizontal graduation/interval. This array is generated automatically
  270. * when you define a tick interval.
  271. * @property xTicks
  272. * @type int[]
  273. */
  274. xTicks: null,
  275. /**
  276. * Array of pixel locations the element will snap to if we specified a
  277. * vertical graduation/interval. This array is generated automatically
  278. * when you define a tick interval.
  279. * @property yTicks
  280. * @type int[]
  281. */
  282. yTicks: null,
  283. /**
  284. * By default the drag and drop instance will only respond to the primary
  285. * button click (left button for a right-handed mouse). Set to true to
  286. * allow drag and drop to start with any mouse click that is propogated
  287. * by the browser
  288. * @property primaryButtonOnly
  289. * @type boolean
  290. */
  291. primaryButtonOnly: true,
  292. /**
  293. * The available property is false until the linked dom element is accessible.
  294. * @property available
  295. * @type boolean
  296. */
  297. available: false,
  298. /**
  299. * By default, drags can only be initiated if the mousedown occurs in the
  300. * region the linked element is. This is done in part to work around a
  301. * bug in some browsers that mis-report the mousedown if the previous
  302. * mouseup happened outside of the window. This property is set to true
  303. * if outer handles are defined.
  304. *
  305. * @property hasOuterHandles
  306. * @type boolean
  307. * @default false
  308. */
  309. hasOuterHandles: false,
  310. /**
  311. * Code that executes immediately before the startDrag event
  312. * @method b4StartDrag
  313. * @private
  314. */
  315. b4StartDrag: function(x, y) { },
  316. /**
  317. * Abstract method called after a drag/drop object is clicked
  318. * and the drag or mousedown time thresholds have beeen met.
  319. * @method startDrag
  320. * @param {int} X click location
  321. * @param {int} Y click location
  322. */
  323. startDrag: function(x, y) { /* override this */ },
  324. /**
  325. * Code that executes immediately before the onDrag event
  326. * @method b4Drag
  327. * @private
  328. */
  329. b4Drag: function(e) { },
  330. /**
  331. * Abstract method called during the onMouseMove event while dragging an
  332. * object.
  333. * @method onDrag
  334. * @param {Event} e the mousemove event
  335. */
  336. onDrag: function(e) { /* override this */ },
  337. /**
  338. * Abstract method called when this element fist begins hovering over
  339. * another DragDrop obj
  340. * @method onDragEnter
  341. * @param {Event} e the mousemove event
  342. * @param {String|DragDrop[]} id In POINT mode, the element
  343. * id this is hovering over. In INTERSECT mode, an array of one or more
  344. * dragdrop items being hovered over.
  345. */
  346. onDragEnter: function(e, id) { /* override this */ },
  347. /**
  348. * Code that executes immediately before the onDragOver event
  349. * @method b4DragOver
  350. * @private
  351. */
  352. b4DragOver: function(e) { },
  353. /**
  354. * Abstract method called when this element is hovering over another
  355. * DragDrop obj
  356. * @method onDragOver
  357. * @param {Event} e the mousemove event
  358. * @param {String|DragDrop[]} id In POINT mode, the element
  359. * id this is hovering over. In INTERSECT mode, an array of dd items
  360. * being hovered over.
  361. */
  362. onDragOver: function(e, id) { /* override this */ },
  363. /**
  364. * Code that executes immediately before the onDragOut event
  365. * @method b4DragOut
  366. * @private
  367. */
  368. b4DragOut: function(e) { },
  369. /**
  370. * Abstract method called when we are no longer hovering over an element
  371. * @method onDragOut
  372. * @param {Event} e the mousemove event
  373. * @param {String|DragDrop[]} id In POINT mode, the element
  374. * id this was hovering over. In INTERSECT mode, an array of dd items
  375. * that the mouse is no longer over.
  376. */
  377. onDragOut: function(e, id) { /* override this */ },
  378. /**
  379. * Code that executes immediately before the onDragDrop event
  380. * @method b4DragDrop
  381. * @private
  382. */
  383. b4DragDrop: function(e) { },
  384. /**
  385. * Abstract method called when this item is dropped on another DragDrop
  386. * obj
  387. * @method onDragDrop
  388. * @param {Event} e the mouseup event
  389. * @param {String|DragDrop[]} id In POINT mode, the element
  390. * id this was dropped on. In INTERSECT mode, an array of dd items this
  391. * was dropped on.
  392. */
  393. onDragDrop: function(e, id) { /* override this */ },
  394. /**
  395. * Abstract method called when this item is dropped on an area with no
  396. * drop target
  397. * @method onInvalidDrop
  398. * @param {Event} e the mouseup event
  399. */
  400. onInvalidDrop: function(e) { /* override this */ },
  401. /**
  402. * Code that executes immediately before the endDrag event
  403. * @method b4EndDrag
  404. * @private
  405. */
  406. b4EndDrag: function(e) { },
  407. /**
  408. * Fired when we are done dragging the object
  409. * @method endDrag
  410. * @param {Event} e the mouseup event
  411. */
  412. endDrag: function(e) { /* override this */ },
  413. /**
  414. * Code executed immediately before the onMouseDown event
  415. * @method b4MouseDown
  416. * @param {Event} e the mousedown event
  417. * @private
  418. */
  419. b4MouseDown: function(e) { },
  420. /**
  421. * Event handler that fires when a drag/drop obj gets a mousedown
  422. * @method onMouseDown
  423. * @param {Event} e the mousedown event
  424. */
  425. onMouseDown: function(e) { /* override this */ },
  426. /**
  427. * Event handler that fires when a drag/drop obj gets a mouseup
  428. * @method onMouseUp
  429. * @param {Event} e the mouseup event
  430. */
  431. onMouseUp: function(e) { /* override this */ },
  432. /**
  433. * Override the onAvailable method to do what is needed after the initial
  434. * position was determined.
  435. * @method onAvailable
  436. */
  437. onAvailable: function () {
  438. },
  439. /**
  440. * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}).
  441. * @type Object
  442. */
  443. defaultPadding : {left:0, right:0, top:0, bottom:0},
  444. /**
  445. * Initializes the drag drop object's constraints to restrict movement to a certain element.
  446. *
  447. * Usage:
  448. <pre><code>
  449. var dd = new Ext.dd.DDProxy("dragDiv1", "proxytest",
  450. { dragElId: "existingProxyDiv" });
  451. dd.startDrag = function(){
  452. this.constrainTo("parent-id");
  453. };
  454. </code></pre>
  455. * Or you can initalize it using the {@link Ext.Element} object:
  456. <pre><code>
  457. Ext.get("dragDiv1").initDDProxy("proxytest", {dragElId: "existingProxyDiv"}, {
  458. startDrag : function(){
  459. this.constrainTo("parent-id");
  460. }
  461. });
  462. </code></pre>
  463. * @param {Mixed} constrainTo The element to constrain to.
  464. * @param {Object/Number} pad (optional) Pad provides a way to specify "padding" of the constraints,
  465. * and can be either a number for symmetrical padding (4 would be equal to {left:4, right:4, top:4, bottom:4}) or
  466. * an object containing the sides to pad. For example: {right:10, bottom:10}
  467. * @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders)
  468. */
  469. constrainTo : function(constrainTo, pad, inContent){
  470. if(Ext.isNumber(pad)){
  471. pad = {left: pad, right:pad, top:pad, bottom:pad};
  472. }
  473. pad = pad || this.defaultPadding;
  474. var b = Ext.get(this.getEl()).getBox(),
  475. ce = Ext.get(constrainTo),
  476. s = ce.getScroll(),
  477. c,
  478. cd = ce.dom;
  479. if(cd == document.body){
  480. c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
  481. }else{
  482. var xy = ce.getXY();
  483. c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
  484. }
  485. var topSpace = b.y - c.y,
  486. leftSpace = b.x - c.x;
  487. this.resetConstraints();
  488. this.setXConstraint(leftSpace - (pad.left||0), // left
  489. c.width - leftSpace - b.width - (pad.right||0), //right
  490. this.xTickSize
  491. );
  492. this.setYConstraint(topSpace - (pad.top||0), //top
  493. c.height - topSpace - b.height - (pad.bottom||0), //bottom
  494. this.yTickSize
  495. );
  496. },
  497. /**
  498. * Returns a reference to the linked element
  499. * @method getEl
  500. * @return {HTMLElement} the html element
  501. */
  502. getEl: function() {
  503. if (!this._domRef) {
  504. this._domRef = Ext.getDom(this.id);
  505. }
  506. return this._domRef;
  507. },
  508. /**
  509. * Returns a reference to the actual element to drag. By default this is
  510. * the same as the html element, but it can be assigned to another
  511. * element. An example of this can be found in Ext.dd.DDProxy
  512. * @method getDragEl
  513. * @return {HTMLElement} the html element
  514. */
  515. getDragEl: function() {
  516. return Ext.getDom(this.dragElId);
  517. },
  518. /**
  519. * Sets up the DragDrop object. Must be called in the constructor of any
  520. * Ext.dd.DragDrop subclass
  521. * @method init
  522. * @param id the id of the linked element
  523. * @param {String} sGroup the group of related items
  524. * @param {object} config configuration attributes
  525. */
  526. init: function(id, sGroup, config) {
  527. this.initTarget(id, sGroup, config);
  528. Event.on(this.id, "mousedown", this.handleMouseDown, this);
  529. // Event.on(this.id, "selectstart", Event.preventDefault);
  530. },
  531. /**
  532. * Initializes Targeting functionality only... the object does not
  533. * get a mousedown handler.
  534. * @method initTarget
  535. * @param id the id of the linked element
  536. * @param {String} sGroup the group of related items
  537. * @param {object} config configuration attributes
  538. */
  539. initTarget: function(id, sGroup, config) {
  540. // configuration attributes
  541. this.config = config || {};
  542. // create a local reference to the drag and drop manager
  543. this.DDM = Ext.dd.DDM;
  544. // initialize the groups array
  545. this.groups = {};
  546. // assume that we have an element reference instead of an id if the
  547. // parameter is not a string
  548. if (typeof id !== "string") {
  549. id = Ext.id(id);
  550. }
  551. // set the id
  552. this.id = id;
  553. // add to an interaction group
  554. this.addToGroup((sGroup) ? sGroup : "default");
  555. // We don't want to register this as the handle with the manager
  556. // so we just set the id rather than calling the setter.
  557. this.handleElId = id;
  558. // the linked element is the element that gets dragged by default
  559. this.setDragElId(id);
  560. // by default, clicked anchors will not start drag operations.
  561. this.invalidHandleTypes = { A: "A" };
  562. this.invalidHandleIds = {};
  563. this.invalidHandleClasses = [];
  564. this.applyConfig();
  565. this.handleOnAvailable();
  566. },
  567. /**
  568. * Applies the configuration parameters that were passed into the constructor.
  569. * This is supposed to happen at each level through the inheritance chain. So
  570. * a DDProxy implentation will execute apply config on DDProxy, DD, and
  571. * DragDrop in order to get all of the parameters that are available in
  572. * each object.
  573. * @method applyConfig
  574. */
  575. applyConfig: function() {
  576. // configurable properties:
  577. // padding, isTarget, maintainOffset, primaryButtonOnly
  578. this.padding = this.config.padding || [0, 0, 0, 0];
  579. this.isTarget = (this.config.isTarget !== false);
  580. this.maintainOffset = (this.config.maintainOffset);
  581. this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
  582. },
  583. /**
  584. * Executed when the linked element is available
  585. * @method handleOnAvailable
  586. * @private
  587. */
  588. handleOnAvailable: function() {
  589. this.available = true;
  590. this.resetConstraints();
  591. this.onAvailable();
  592. },
  593. /**
  594. * Configures the padding for the target zone in px. Effectively expands
  595. * (or reduces) the virtual object size for targeting calculations.
  596. * Supports css-style shorthand; if only one parameter is passed, all sides
  597. * will have that padding, and if only two are passed, the top and bottom
  598. * will have the first param, the left and right the second.
  599. * @method setPadding
  600. * @param {int} iTop Top pad
  601. * @param {int} iRight Right pad
  602. * @param {int} iBot Bot pad
  603. * @param {int} iLeft Left pad
  604. */
  605. setPadding: function(iTop, iRight, iBot, iLeft) {
  606. // this.padding = [iLeft, iRight, iTop, iBot];
  607. if (!iRight && 0 !== iRight) {
  608. this.padding = [iTop, iTop, iTop, iTop];
  609. } else if (!iBot && 0 !== iBot) {
  610. this.padding = [iTop, iRight, iTop, iRight];
  611. } else {
  612. this.padding = [iTop, iRight, iBot, iLeft];
  613. }
  614. },
  615. /**
  616. * Stores the initial placement of the linked element.
  617. * @method setInitPosition
  618. * @param {int} diffX the X offset, default 0
  619. * @param {int} diffY the Y offset, default 0
  620. */
  621. setInitPosition: function(diffX, diffY) {
  622. var el = this.getEl();
  623. if (!this.DDM.verifyEl(el)) {
  624. return;
  625. }
  626. var dx = diffX || 0;
  627. var dy = diffY || 0;
  628. var p = Dom.getXY( el );
  629. this.initPageX = p[0] - dx;
  630. this.initPageY = p[1] - dy;
  631. this.lastPageX = p[0];
  632. this.lastPageY = p[1];
  633. this.setStartPosition(p);
  634. },
  635. /**
  636. * Sets the start position of the element. This is set when the obj
  637. * is initialized, the reset when a drag is started.
  638. * @method setStartPosition
  639. * @param pos current position (from previous lookup)
  640. * @private
  641. */
  642. setStartPosition: function(pos) {
  643. var p = pos || Dom.getXY( this.getEl() );
  644. this.deltaSetXY = null;
  645. this.startPageX = p[0];
  646. this.startPageY = p[1];
  647. },
  648. /**
  649. * Add this instance to a group of related drag/drop objects. All
  650. * instances belong to at least one group, and can belong to as many
  651. * groups as needed.
  652. * @method addToGroup
  653. * @param sGroup {string} the name of the group
  654. */
  655. addToGroup: function(sGroup) {
  656. this.groups[sGroup] = true;
  657. this.DDM.regDragDrop(this, sGroup);
  658. },
  659. /**
  660. * Remove's this instance from the supplied interaction group
  661. * @method removeFromGroup
  662. * @param {string} sGroup The group to drop
  663. */
  664. removeFromGroup: function(sGroup) {
  665. if (this.groups[sGroup]) {
  666. delete this.groups[sGroup];
  667. }
  668. this.DDM.removeDDFromGroup(this, sGroup);
  669. },
  670. /**
  671. * Allows you to specify that an element other than the linked element
  672. * will be moved with the cursor during a drag
  673. * @method setDragElId
  674. * @param id {string} the id of the element that will be used to initiate the drag
  675. */
  676. setDragElId: function(id) {
  677. this.dragElId = id;
  678. },
  679. /**
  680. * Allows you to specify a child of the linked element that should be
  681. * used to initiate the drag operation. An example of this would be if
  682. * you have a content div with text and links. Clicking anywhere in the
  683. * content area would normally start the drag operation. Use this method
  684. * to specify that an element inside of the content div is the element
  685. * that starts the drag operation.
  686. * @method setHandleElId
  687. * @param id {string} the id of the element that will be used to
  688. * initiate the drag.
  689. */
  690. setHandleElId: function(id) {
  691. if (typeof id !== "string") {
  692. id = Ext.id(id);
  693. }
  694. this.handleElId = id;
  695. this.DDM.regHandle(this.id, id);
  696. },
  697. /**
  698. * Allows you to set an element outside of the linked element as a drag
  699. * handle
  700. * @method setOuterHandleElId
  701. * @param id the id of the element that will be used to initiate the drag
  702. */
  703. setOuterHandleElId: function(id) {
  704. if (typeof id !== "string") {
  705. id = Ext.id(id);
  706. }
  707. Event.on(id, "mousedown",
  708. this.handleMouseDown, this);
  709. this.setHandleElId(id);
  710. this.hasOuterHandles = true;
  711. },
  712. /**
  713. * Remove all drag and drop hooks for this element
  714. * @method unreg
  715. */
  716. unreg: function() {
  717. Event.un(this.id, "mousedown",
  718. this.handleMouseDown);
  719. this._domRef = null;
  720. this.DDM._remove(this);
  721. },
  722. destroy : function(){
  723. this.unreg();
  724. },
  725. /**
  726. * Returns true if this instance is locked, or the drag drop mgr is locked
  727. * (meaning that all drag/drop is disabled on the page.)
  728. * @method isLocked
  729. * @return {boolean} true if this obj or all drag/drop is locked, else
  730. * false
  731. */
  732. isLocked: function() {
  733. return (this.DDM.isLocked() || this.locked);
  734. },
  735. /**
  736. * Fired when this object is clicked
  737. * @method handleMouseDown
  738. * @param {Event} e
  739. * @param {Ext.dd.DragDrop} oDD the clicked dd object (this dd obj)
  740. * @private
  741. */
  742. handleMouseDown: function(e, oDD){
  743. if (this.primaryButtonOnly && e.button != 0) {
  744. return;
  745. }
  746. if (this.isLocked()) {
  747. return;
  748. }
  749. this.DDM.refreshCache(this.groups);
  750. var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
  751. if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
  752. } else {
  753. if (this.clickValidator(e)) {
  754. // set the initial element position
  755. this.setStartPosition();
  756. this.b4MouseDown(e);
  757. this.onMouseDown(e);
  758. this.DDM.handleMouseDown(e, this);
  759. this.DDM.stopEvent(e);
  760. } else {
  761. }
  762. }
  763. },
  764. clickValidator: function(e) {
  765. var target = e.getTarget();
  766. return ( this.isValidHandleChild(target) &&
  767. (this.id == this.handleElId ||
  768. this.DDM.handleWasClicked(target, this.id)) );
  769. },
  770. /**
  771. * Allows you to specify a tag name that should not start a drag operation
  772. * when clicked. This is designed to facilitate embedding links within a
  773. * drag handle that do something other than start the drag.
  774. * @method addInvalidHandleType
  775. * @param {string} tagName the type of element to exclude
  776. */
  777. addInvalidHandleType: function(tagName) {
  778. var type = tagName.toUpperCase();
  779. this.invalidHandleTypes[type] = type;
  780. },
  781. /**
  782. * Lets you to specify an element id for a child of a drag handle
  783. * that should not initiate a drag
  784. * @method addInvalidHandleId
  785. * @param {string} id the element id of the element you wish to ignore
  786. */
  787. addInvalidHandleId: function(id) {
  788. if (typeof id !== "string") {
  789. id = Ext.id(id);
  790. }
  791. this.invalidHandleIds[id] = id;
  792. },
  793. /**
  794. * Lets you specify a css class of elements that will not initiate a drag
  795. * @method addInvalidHandleClass
  796. * @param {string} cssClass the class of the elements you wish to ignore
  797. */
  798. addInvalidHandleClass: function(cssClass) {
  799. this.invalidHandleClasses.push(cssClass);
  800. },
  801. /**
  802. * Unsets an excluded tag name set by addInvalidHandleType
  803. * @method removeInvalidHandleType
  804. * @param {string} tagName the type of element to unexclude
  805. */
  806. removeInvalidHandleType: function(tagName) {
  807. var type = tagName.toUpperCase();
  808. // this.invalidHandleTypes[type] = null;
  809. delete this.invalidHandleTypes[type];
  810. },
  811. /**
  812. * Unsets an invalid handle id
  813. * @method removeInvalidHandleId
  814. * @param {string} id the id of the element to re-enable
  815. */
  816. removeInvalidHandleId: function(id) {
  817. if (typeof id !== "string") {
  818. id = Ext.id(id);
  819. }
  820. delete this.invalidHandleIds[id];
  821. },
  822. /**
  823. * Unsets an invalid css class
  824. * @method removeInvalidHandleClass
  825. * @param {string} cssClass the class of the element(s) you wish to
  826. * re-enable
  827. */
  828. removeInvalidHandleClass: function(cssClass) {
  829. for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
  830. if (this.invalidHandleClasses[i] == cssClass) {
  831. delete this.invalidHandleClasses[i];
  832. }
  833. }
  834. },
  835. /**
  836. * Checks the tag exclusion list to see if this click should be ignored
  837. * @method isValidHandleChild
  838. * @param {HTMLElement} node the HTMLElement to evaluate
  839. * @return {boolean} true if this is a valid tag type, false if not
  840. */
  841. isValidHandleChild: function(node) {
  842. var valid = true;
  843. // var n = (node.nodeName == "#text") ? node.parentNode : node;
  844. var nodeName;
  845. try {
  846. nodeName = node.nodeName.toUpperCase();
  847. } catch(e) {
  848. nodeName = node.nodeName;
  849. }
  850. valid = valid && !this.invalidHandleTypes[nodeName];
  851. valid = valid && !this.invalidHandleIds[node.id];
  852. for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
  853. valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
  854. }
  855. return valid;
  856. },
  857. /**
  858. * Create the array of horizontal tick marks if an interval was specified
  859. * in setXConstraint().
  860. * @method setXTicks
  861. * @private
  862. */
  863. setXTicks: function(iStartX, iTickSize) {
  864. this.xTicks = [];
  865. this.xTickSize = iTickSize;
  866. var tickMap = {};
  867. for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
  868. if (!tickMap[i]) {
  869. this.xTicks[this.xTicks.length] = i;
  870. tickMap[i] = true;
  871. }
  872. }
  873. for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
  874. if (!tickMap[i]) {
  875. this.xTicks[this.xTicks.length] = i;
  876. tickMap[i] = true;
  877. }
  878. }
  879. this.xTicks.sort(this.DDM.numericSort) ;
  880. },
  881. /**
  882. * Create the array of vertical tick marks if an interval was specified in
  883. * setYConstraint().
  884. * @method setYTicks
  885. * @private
  886. */
  887. setYTicks: function(iStartY, iTickSize) {
  888. this.yTicks = [];
  889. this.yTickSize = iTickSize;
  890. var tickMap = {};
  891. for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
  892. if (!tickMap[i]) {
  893. this.yTicks[this.yTicks.length] = i;
  894. tickMap[i] = true;
  895. }
  896. }
  897. for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
  898. if (!tickMap[i]) {
  899. this.yTicks[this.yTicks.length] = i;
  900. tickMap[i] = true;
  901. }
  902. }
  903. this.yTicks.sort(this.DDM.numericSort) ;
  904. },
  905. /**
  906. * By default, the element can be dragged any place on the screen. Use
  907. * this method to limit the horizontal travel of the element. Pass in
  908. * 0,0 for the parameters if you want to lock the drag to the y axis.
  909. * @method setXConstraint
  910. * @param {int} iLeft the number of pixels the element can move to the left
  911. * @param {int} iRight the number of pixels the element can move to the
  912. * right
  913. * @param {int} iTickSize optional parameter for specifying that the
  914. * element
  915. * should move iTickSize pixels at a time.
  916. */
  917. setXConstraint: function(iLeft, iRight, iTickSize) {
  918. this.leftConstraint = iLeft;
  919. this.rightConstraint = iRight;
  920. this.minX = this.initPageX - iLeft;
  921. this.maxX = this.initPageX + iRight;
  922. if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
  923. this.constrainX = true;
  924. },
  925. /**
  926. * Clears any constraints applied to this instance. Also clears ticks
  927. * since they can't exist independent of a constraint at this time.
  928. * @method clearConstraints
  929. */
  930. clearConstraints: function() {
  931. this.constrainX = false;
  932. this.constrainY = false;
  933. this.clearTicks();
  934. },
  935. /**
  936. * Clears any tick interval defined for this instance
  937. * @method clearTicks
  938. */
  939. clearTicks: function() {
  940. this.xTicks = null;
  941. this.yTicks = null;
  942. this.xTickSize = 0;
  943. this.yTickSize = 0;
  944. },
  945. /**
  946. * By default, the element can be dragged any place on the screen. Set
  947. * this to limit the vertical travel of the element. Pass in 0,0 for the
  948. * parameters if you want to lock the drag to the x axis.
  949. * @method setYConstraint
  950. * @param {int} iUp the number of pixels the element can move up
  951. * @param {int} iDown the number of pixels the element can move down
  952. * @param {int} iTickSize optional parameter for specifying that the
  953. * element should move iTickSize pixels at a time.
  954. */
  955. setYConstraint: function(iUp, iDown, iTickSize) {
  956. this.topConstraint = iUp;
  957. this.bottomConstraint = iDown;
  958. this.minY = this.initPageY - iUp;
  959. this.maxY = this.initPageY + iDown;
  960. if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
  961. this.constrainY = true;
  962. },
  963. /**
  964. * resetConstraints must be called if you manually reposition a dd element.
  965. * @method resetConstraints
  966. * @param {boolean} maintainOffset
  967. */
  968. resetConstraints: function() {
  969. // Maintain offsets if necessary
  970. if (this.initPageX || this.initPageX === 0) {
  971. // figure out how much this thing has moved
  972. var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
  973. var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
  974. this.setInitPosition(dx, dy);
  975. // This is the first time we have detected the element's position
  976. } else {
  977. this.setInitPosition();
  978. }
  979. if (this.constrainX) {
  980. this.setXConstraint( this.leftConstraint,
  981. this.rightConstraint,
  982. this.xTickSize );
  983. }
  984. if (this.constrainY) {
  985. this.setYConstraint( this.topConstraint,
  986. this.bottomConstraint,
  987. this.yTickSize );
  988. }
  989. },
  990. /**
  991. * Normally the drag element is moved pixel by pixel, but we can specify
  992. * that it move a number of pixels at a time. This method resolves the
  993. * location when we have it set up like this.
  994. * @method getTick
  995. * @param {int} val where we want to place the object
  996. * @param {int[]} tickArray sorted array of valid points
  997. * @return {int} the closest tick
  998. * @private
  999. */
  1000. getTick: function(val, tickArray) {
  1001. if (!tickArray) {
  1002. // If tick interval is not defined, it is effectively 1 pixel,
  1003. // so we return the value passed to us.
  1004. return val;
  1005. } else if (tickArray[0] >= val) {
  1006. // The value is lower than the first tick, so we return the first
  1007. // tick.
  1008. return tickArray[0];
  1009. } else {
  1010. for (var i=0, len=tickArray.length; i<len; ++i) {
  1011. var next = i + 1;
  1012. if (tickArray[next] && tickArray[next] >= val) {
  1013. var diff1 = val - tickArray[i];
  1014. var diff2 = tickArray[next] - val;
  1015. return (diff2 > diff1) ? tickArray[i] : tickArray[next];
  1016. }
  1017. }
  1018. // The value is larger than the last tick, so we return the last
  1019. // tick.
  1020. return tickArray[tickArray.length - 1];
  1021. }
  1022. },
  1023. /**
  1024. * toString method
  1025. * @method toString
  1026. * @return {string} string representation of the dd obj
  1027. */
  1028. toString: function() {
  1029. return ("DragDrop " + this.id);
  1030. }
  1031. };
  1032. })();
  1033. /*
  1034. * The drag and drop utility provides a framework for building drag and drop
  1035. * applications. In addition to enabling drag and drop for specific elements,
  1036. * the drag and drop elements are tracked by the manager class, and the
  1037. * interactions between the various elements are tracked during the drag and
  1038. * the implementing code is notified about these important moments.
  1039. */
  1040. // Only load the library once. Rewriting the manager class would orphan
  1041. // existing drag and drop instances.
  1042. if (!Ext.dd.DragDropMgr) {
  1043. /**
  1044. * @class Ext.dd.DragDropMgr
  1045. * DragDropMgr is a singleton that tracks the element interaction for
  1046. * all DragDrop items in the window. Generally, you will not call
  1047. * this class directly, but it does have helper methods that could
  1048. * be useful in your DragDrop implementations.
  1049. * @singleton
  1050. */
  1051. Ext.dd.DragDropMgr = function() {
  1052. var Event = Ext.EventManager;
  1053. return {
  1054. /**
  1055. * Two dimensional Array of registered DragDrop objects. The first
  1056. * dimension is the DragDrop item group, the second the DragDrop
  1057. * object.
  1058. * @property ids
  1059. * @type String[]
  1060. * @private
  1061. * @static
  1062. */
  1063. ids: {},
  1064. /**
  1065. * Array of element ids defined as drag handles. Used to determine
  1066. * if the element that generated the mousedown event is actually the
  1067. * handle and not the html element itself.
  1068. * @property handleIds
  1069. * @type String[]
  1070. * @private
  1071. * @static
  1072. */
  1073. handleIds: {},
  1074. /**
  1075. * the DragDrop object that is currently being dragged
  1076. * @property dragCurrent
  1077. * @type DragDrop
  1078. * @private
  1079. * @static
  1080. **/
  1081. dragCurrent: null,
  1082. /**
  1083. * the DragDrop object(s) that are being hovered over
  1084. * @property dragOvers
  1085. * @type Array
  1086. * @private
  1087. * @static
  1088. */
  1089. dragOvers: {},
  1090. /**
  1091. * the X distance between the cursor and the object being dragged
  1092. * @property deltaX
  1093. * @type int
  1094. * @private
  1095. * @static
  1096. */
  1097. deltaX: 0,
  1098. /**
  1099. * the Y distance between the cursor and the object being dragged
  1100. * @property deltaY
  1101. * @type int
  1102. * @private
  1103. * @static
  1104. */
  1105. deltaY: 0,
  1106. /**
  1107. * Flag to determine if we should prevent the default behavior of the
  1108. * events we define. By default this is true, but this can be set to
  1109. * false if you need the default behavior (not recommended)
  1110. * @property preventDefault
  1111. * @type boolean
  1112. * @static
  1113. */
  1114. preventDefault: true,
  1115. /**
  1116. * Flag to determine if we should stop the propagation of the events
  1117. * we generate. This is true by default but you may want to set it to
  1118. * false if the html element contains other features that require the
  1119. * mouse click.
  1120. * @property stopPropagation
  1121. * @type boolean
  1122. * @static
  1123. */
  1124. stopPropagation: true,
  1125. /**
  1126. * Internal flag that is set to true when drag and drop has been
  1127. * intialized
  1128. * @property initialized
  1129. * @private
  1130. * @static
  1131. */
  1132. initialized: false,
  1133. /**
  1134. * All drag and drop can be disabled.
  1135. * @property locked
  1136. * @private
  1137. * @static
  1138. */
  1139. locked: false,
  1140. /**
  1141. * Called the first time an element is registered.
  1142. * @method init
  1143. * @private
  1144. * @static
  1145. */
  1146. init: function() {
  1147. this.initialized = true;
  1148. },
  1149. /**
  1150. * In point mode, drag and drop interaction is defined by the
  1151. * location of the cursor during the drag/drop
  1152. * @property POINT
  1153. * @type int
  1154. * @static
  1155. */
  1156. POINT: 0,
  1157. /**
  1158. * In intersect mode, drag and drop interaction is defined by the
  1159. * overlap of two or more drag and drop objects.
  1160. * @property INTERSECT
  1161. * @type int
  1162. * @static
  1163. */
  1164. INTERSECT: 1,
  1165. /**
  1166. * The current drag and drop mode. Default: POINT
  1167. * @property mode
  1168. * @type int
  1169. * @static
  1170. */
  1171. mode: 0,
  1172. /**
  1173. * Runs method on all drag and drop objects
  1174. * @method _execOnAll
  1175. * @private
  1176. * @static
  1177. */
  1178. _execOnAll: function(sMethod, args) {
  1179. for (var i in this.ids) {
  1180. for (var j in this.ids[i]) {
  1181. var oDD = this.ids[i][j];
  1182. if (! this.isTypeOfDD(oDD)) {
  1183. continue;
  1184. }
  1185. oDD[sMethod].apply(oDD, args);
  1186. }
  1187. }
  1188. },
  1189. /**
  1190. * Drag and drop initialization. Sets up the global event handlers
  1191. * @method _onLoad
  1192. * @private
  1193. * @static
  1194. */
  1195. _onLoad: function() {
  1196. this.init();
  1197. Event.on(document, "mouseup", this.handleMouseUp, this, true);
  1198. Event.on(document, "mousemove", this.handleMouseMove, this, true);
  1199. Event.on(window, "unload", this._onUnload, this, true);
  1200. Event.on(window, "resize", this._onResize, this, true);
  1201. // Event.on(window, "mouseout", this._test);
  1202. },
  1203. /**
  1204. * Reset constraints on all drag and drop objs
  1205. * @method _onResize
  1206. * @private
  1207. * @static
  1208. */
  1209. _onResize: function(e) {
  1210. this._execOnAll("resetConstraints", []);
  1211. },
  1212. /**
  1213. * Lock all drag and drop functionality
  1214. * @method lock
  1215. * @static
  1216. */
  1217. lock: function() { this.locked = true; },
  1218. /**
  1219. * Unlock all drag and drop functionality
  1220. * @method unlock
  1221. * @static
  1222. */
  1223. unlock: function() { this.locked = false; },
  1224. /**
  1225. * Is drag and drop locked?
  1226. * @method isLocked
  1227. * @return {boolean} True if drag and drop is locked, false otherwise.
  1228. * @static
  1229. */
  1230. isLocked: function() { return this.locked; },
  1231. /**
  1232. * Location cache that is set for all drag drop objects when a drag is
  1233. * initiated, cleared when the drag is finished.
  1234. * @property locationCache
  1235. * @private
  1236. * @static
  1237. */
  1238. locationCache: {},
  1239. /**
  1240. * Set useCache to false if you want to force object the lookup of each
  1241. * drag and drop linked element constantly during a drag.
  1242. * @property useCache
  1243. * @type boolean
  1244. * @static
  1245. */
  1246. useCache: true,
  1247. /**
  1248. * The number of pixels that the mouse needs to move after the
  1249. * mousedown before the drag is initiated. Default=3;
  1250. * @property clickPixelThresh
  1251. * @type int
  1252. * @static
  1253. */
  1254. clickPixelThresh: 3,
  1255. /**
  1256. * The number of milliseconds after the mousedown event to initiate the
  1257. * drag if we don't get a mouseup event. Default=350
  1258. * @property clickTimeThresh
  1259. * @type int
  1260. * @static
  1261. */
  1262. clickTimeThresh: 350,
  1263. /**
  1264. * Flag that indicates that either the drag pixel threshold or the
  1265. * mousdown time threshold has been met
  1266. * @property dragThreshMet
  1267. * @type boolean
  1268. * @private
  1269. * @static
  1270. */
  1271. dragThreshMet: false,
  1272. /**
  1273. * Timeout used for the click time threshold
  1274. * @property clickTimeout
  1275. * @type Object
  1276. * @private
  1277. * @static
  1278. */
  1279. clickTimeout: null,
  1280. /**
  1281. * The X position of the mousedown event stored for later use when a
  1282. * drag threshold is met.
  1283. * @property startX
  1284. * @type int
  1285. * @private
  1286. * @static
  1287. */
  1288. startX: 0,
  1289. /**
  1290. * The Y position of the mousedown event stored for later use when a
  1291. * drag threshold is met.
  1292. * @property startY
  1293. * @type int
  1294. * @private
  1295. * @static
  1296. */
  1297. startY: 0,
  1298. /**
  1299. * Each DragDrop instance must be registered with the DragDropMgr.
  1300. * This is executed in DragDrop.init()
  1301. * @method regDragDrop
  1302. * @param {DragDrop} oDD the DragDrop object to register
  1303. * @param {String} sGroup the name of the group this element belongs to
  1304. * @static
  1305. */
  1306. regDragDrop: function(oDD, sGroup) {
  1307. if (!this.initialized) { this.init(); }
  1308. if (!this.ids[sGroup]) {
  1309. this.ids[sGroup] = {};
  1310. }
  1311. this.ids[sGroup][oDD.id] = oDD;
  1312. },
  1313. /**
  1314. * Removes the supplied dd instance from the supplied group. Executed
  1315. * by DragDrop.removeFromGroup, so don't call this function directly.
  1316. * @method removeDDFromGroup
  1317. * @private
  1318. * @static
  1319. */
  1320. removeDDFromGroup: function(oDD, sGroup) {
  1321. if (!this.ids[sGroup]) {
  1322. this.ids[sGroup] = {};
  1323. }
  1324. var obj = this.ids[sGroup];
  1325. if (obj && obj[oDD.id]) {
  1326. delete obj[oDD.id];
  1327. }
  1328. },
  1329. /**
  1330. * Unregisters a drag and drop item. This is executed in
  1331. * DragDrop.unreg, use that method instead of calling this directly.
  1332. * @method _remove
  1333. * @private
  1334. * @static
  1335. */
  1336. _remove: function(oDD) {
  1337. for (var g in oDD.groups) {
  1338. if (g && this.ids[g] && this.ids[g][oDD.id]) {
  1339. delete this.ids[g][oDD.id];
  1340. }
  1341. }
  1342. delete this.handleIds[oDD.id];
  1343. },
  1344. /**
  1345. * Each DragDrop handle element must be registered. This is done
  1346. * automatically when executing DragDrop.setHandleElId()
  1347. * @method regHandle
  1348. * @param {String} sDDId the DragDrop id this element is a handle for
  1349. * @param {String} sHandleId the id of the element that is the drag
  1350. * handle
  1351. * @static
  1352. */
  1353. regHandle: function(sDDId, sHandleId) {
  1354. if (!this.handleIds[sDDId]) {
  1355. this.handleIds[sDDId] = {};
  1356. }
  1357. this.handleIds[sDDId][sHandleId] = sHandleId;
  1358. },
  1359. /**
  1360. * Utility function to determine if a given element has been
  1361. * registered as a drag drop item.
  1362. * @method isDragDrop
  1363. * @param {String} id the element id to check
  1364. * @return {boolean} true if this element is a DragDrop item,
  1365. * false otherwise
  1366. * @static
  1367. */
  1368. isDragDrop: function(id) {
  1369. return ( this.getDDById(id) ) ? true : false;
  1370. },
  1371. /**
  1372. * Returns the drag and drop instances that are in all groups the
  1373. * passed in instance belongs to.
  1374. * @method getRelated
  1375. * @param {DragDrop} p_oDD the obj to get related data for
  1376. * @param {boolean} bTargetsOnly if true, only return targetable objs
  1377. * @return {DragDrop[]} the related instances
  1378. * @static
  1379. */
  1380. getRelated: function(p_oDD, bTargetsOnly) {
  1381. var oDDs = [];
  1382. for (var i in p_oDD.groups) {
  1383. for (var j in this.ids[i]) {
  1384. var dd = this.ids[i][j];
  1385. if (! this.isTypeOfDD(dd)) {
  1386. continue;
  1387. }
  1388. if (!bTargetsOnly || dd.isTarget) {
  1389. oDDs[oDDs.length] = dd;
  1390. }
  1391. }
  1392. }
  1393. return oDDs;
  1394. },
  1395. /**
  1396. * Returns true if the specified dd target is a legal target for
  1397. * the specifice drag obj
  1398. * @method isLegalTarget
  1399. * @param {DragDrop} oDD the drag obj
  1400. * @param {DragDrop} oTargetDD the target
  1401. * @return {boolean} true if the target is a legal target for the
  1402. * dd obj
  1403. * @static
  1404. */
  1405. isLegalTarget: function (oDD, oTargetDD) {
  1406. var targets = this.getRelated(oDD, true);
  1407. for (var i=0, len=targets.length;i<len;++i) {
  1408. if (targets[i].id == oTargetDD.id) {
  1409. return true;
  1410. }
  1411. }
  1412. return false;
  1413. },
  1414. /**
  1415. * My goal is to be able to transparently determine if an object is
  1416. * typeof DragDrop, and the exact subclass of DragDrop. typeof
  1417. * returns "object", oDD.constructor.toString() always returns
  1418. * "DragDrop" and not the name of the subclass. So for now it just
  1419. * evaluates a well-known variable in DragDrop.
  1420. * @method isTypeOfDD
  1421. * @param {Object} the object to evaluate
  1422. * @return {boolean} true if typeof oDD = DragDrop
  1423. * @static
  1424. */
  1425. isTypeOfDD: function (oDD) {
  1426. return (oDD && oDD.__ygDragDrop);
  1427. },
  1428. /**
  1429. * Utility function to determine if a given element has been
  1430. * registered as a drag drop handle for the given Drag Drop object.
  1431. * @method isHandle
  1432. * @param {String} id the element id to check
  1433. * @return {boolean}…