2 YUI 3.15.0 (build 834026e)
3 Copyright 2014 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('dd-drag', function (Y, NAME) {
12 * Provides the ability to drag a Node.
17 * Provides the ability to drag a Node.
26 DRAGGING = 'dragging',
27 DRAG_NODE = 'dragNode',
28 OFFSET_HEIGHT = 'offsetHeight',
29 OFFSET_WIDTH = 'offsetWidth',
31 * Handles the mouseup DOM event, does nothing internally just fires.
37 * Handles the mousedown DOM event, checks to see if you have a valid handle then starts the drag timers.
38 * @event drag:mouseDown
39 * @preventable _defMouseDownFn
40 * @param {EventFacade} event An Event Facade object with the following specific property added:
41 * <dl><dt>ev</dt><dd>The original mousedown event.</dd></dl>
45 EV_MOUSE_DOWN = 'drag:mouseDown',
47 * Fires after the mousedown event has been cleared.
48 * @event drag:afterMouseDown
49 * @param {EventFacade} event An Event Facade object with the following specific property added:
50 * <dl><dt>ev</dt><dd>The original mousedown event.</dd></dl>
54 EV_AFTER_MOUSE_DOWN = 'drag:afterMouseDown',
56 * Fires after a handle is removed.
57 * @event drag:removeHandle
58 * @param {EventFacade} event An Event Facade object with the following specific property added:
59 * <dl><dt>handle</dt><dd>The handle that was removed.</dd></dl>
63 EV_REMOVE_HANDLE = 'drag:removeHandle',
65 * Fires after a handle is added.
66 * @event drag:addHandle
67 * @param {EventFacade} event An Event Facade object with the following specific property added:
68 * <dl><dt>handle</dt><dd>The handle that was added.</dd></dl>
72 EV_ADD_HANDLE = 'drag:addHandle',
74 * Fires after an invalid selector is removed.
75 * @event drag:removeInvalid
76 * @param {EventFacade} event An Event Facade object with the following specific property added:
77 * <dl><dt>handle</dt><dd>The handle that was removed.</dd></dl>
81 EV_REMOVE_INVALID = 'drag:removeInvalid',
83 * Fires after an invalid selector is added.
84 * @event drag:addInvalid
85 * @param {EventFacade} event An Event Facade object with the following specific property added:
86 * <dl><dt>handle</dt><dd>The handle that was added.</dd></dl>
90 EV_ADD_INVALID = 'drag:addInvalid',
92 * Fires at the start of a drag operation.
94 * @param {EventFacade} event An Event Facade object with the following specific property added:
96 * <dt>pageX</dt><dd>The original node position X.</dd>
97 * <dt>pageY</dt><dd>The original node position Y.</dd>
98 * <dt>startTime</dt><dd>The startTime of the event. getTime on the current Date object.</dd>
101 * @type {CustomEvent}
103 EV_START = 'drag:start',
105 * Fires at the end of a drag operation.
107 * @param {EventFacade} event An Event Facade object with the following specific property added:
109 * <dt>pageX</dt><dd>The current node position X.</dd>
110 * <dt>pageY</dt><dd>The current node position Y.</dd>
111 * <dt>startTime</dt><dd>The startTime of the event, from the start event.</dd>
112 * <dt>endTime</dt><dd>The endTime of the event. getTime on the current Date object.</dd>
115 * @type {CustomEvent}
119 * Fires every mousemove during a drag operation.
121 * @param {EventFacade} event An Event Facade object with the following specific property added:
123 * <dt>pageX</dt><dd>The current node position X.</dd>
124 * <dt>pageY</dt><dd>The current node position Y.</dd>
125 * <dt>scroll</dt><dd>Should a scroll action occur.</dd>
126 * <dt>info</dt><dd>Object hash containing calculated XY arrays: start, xy, delta, offset</dd>
129 * @type {CustomEvent}
131 EV_DRAG = 'drag:drag',
133 * Fires when this node is aligned.
135 * @preventable _defAlignFn
136 * @param {EventFacade} event An Event Facade object with the following specific property added:
138 * <dt>pageX</dt><dd>The current node position X.</dd>
139 * <dt>pageY</dt><dd>The current node position Y.</dd>
142 * @type {CustomEvent}
144 EV_ALIGN = 'drag:align',
146 * Fires when this node is over a Drop Target. (Fired from dd-drop)
148 * @param {EventFacade} event An Event Facade object with the following specific property added:
150 * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
151 * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
154 * @type {CustomEvent}
157 * Fires when this node enters a Drop Target. (Fired from dd-drop)
159 * @param {EventFacade} event An Event Facade object with the following specific property added:
161 * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
162 * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
165 * @type {CustomEvent}
168 * Fires when this node exits a Drop Target. (Fired from dd-drop)
170 * @param {EventFacade} event An Event Facade object with the following specific property added:
172 * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
175 * @type {CustomEvent}
178 * Fires when this node is dropped on a valid Drop Target. (Fired from dd-ddm-drop)
179 * @event drag:drophit
180 * @param {EventFacade} event An Event Facade object with the following specific property added:
182 * <dt>drop</dt><dd>The best guess on what was dropped on.</dd>
183 * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
184 * <dt>others</dt><dd>An array of all the other drop targets that was dropped on.</dd>
187 * @type {CustomEvent}
190 * Fires when this node is dropped on an invalid Drop Target. (Fired from dd-ddm-drop)
191 * @event drag:dropmiss
192 * @param {EventFacade} event An Event Facade object with the following specific property added:
194 * <dt>pageX</dt><dd>The current node position X.</dd>
195 * <dt>pageY</dt><dd>The current node position Y.</dd>
198 * @type {CustomEvent}
202 this._lazyAddAttrs = false;
203 Drag.superclass.constructor.apply(this, arguments);
205 var valid = DDM._regDrag(this);
207 Y.error('Failed to register node, already in use: ' + o.node);
214 * This property defaults to "mousedown", but when drag-gestures is loaded, it is changed to "gesturemovestart"
216 * @property START_EVENT
218 Drag.START_EVENT = 'mousedown';
222 * Y.Node instance to use as the element to initiate a drag operation
227 setter: function(node) {
228 if (this._canDrag(node)) {
233 Y.error('DD.Drag: Invalid Node Given: ' + node);
239 * Y.Node instance to use as the draggable element, defaults to node
240 * @attribute dragNode
244 setter: function(node) {
245 if (this._canDrag(node)) {
250 Y.error('DD.Drag: Invalid dragNode Given: ' + node);
256 * Offset the drag element by the difference in cursor position: default true
257 * @attribute offsetNode
264 * Center the dragNode to the mouse position on drag:start: default false
265 * @attribute startCentered
272 * The number of pixels to move to start a drag operation, default is 3.
273 * @attribute clickPixelThresh
277 value: DDM.get('clickPixelThresh')
280 * The number of milliseconds a mousedown has to pass to start a drag operation, default is 1000.
281 * @attribute clickTimeThresh
285 value: DDM.get('clickTimeThresh')
288 * Set to lock this drag element so that it can't be dragged: default false.
294 setter: function(lock) {
296 this.get(NODE).addClass(DDM.CSS_PREFIX + '-locked');
298 this.get(NODE).removeClass(DDM.CSS_PREFIX + '-locked');
304 * A payload holder to store arbitrary data about this drag object, can be used to store any value.
312 * If this is false, the drag element will not move with the cursor: default true. Can be used to "resize" the element.
320 * Use the protective shim on all drag operations: default true. Only works with dd-ddm, not dd-ddm-base.
328 * Config option is set by Drag to inform you of which handle fired the drag event (in the case that there are several handles): default false.
329 * @attribute activeHandle
336 * By default a drag operation will only begin if the mousedown occurred with the primary mouse button.
337 * Setting this to false will allow for all mousedown events to trigger a drag.
338 * @attribute primaryButtonOnly
345 * This attribute is not meant to be used by the implementor, it is meant to be used as an Event tracker so you can listen for it to change.
346 * @attribute dragging
356 * This attribute only works if the dd-drop module has been loaded. It will make this node a drop target as well as draggable.
362 setter: function(config) {
363 this._handleTarget(config);
368 * This attribute only works if the dd-drop module is active. It will set the dragMode (point, intersect, strict) of this Drag instance.
369 * @attribute dragMode
374 setter: function(mode) {
375 return DDM._setDragMode(mode);
379 * Array of groups to add this drag into.
391 return Y.Object.keys(this._groups);
393 setter: function(g) {
394 this._groups = Y.Array.hash(g);
399 * Array of valid handles to add. Adding something here will set all handles, even if previously added with addHandle
405 setter: function(g) {
408 Y.Array.each(g, function(v) {
410 if (v instanceof Y.Node || v instanceof Y.NodeList) {
413 this._handles[key] = v;
416 this._handles = null;
422 * Controls the default bubble parent for this Drag instance. Default: Y.DD.DDM. Set to false to disable bubbling. Use bubbleTargets in config
428 setter: function(t) {
434 * Should the mousedown event be halted. Default: true
435 * @attribute haltDown
443 Y.extend(Drag, Y.Base, {
445 * Checks the object for the methods needed to drag the object around.
446 * Normally this would be a node instance, but in the case of Graphics, it
447 * may be an SVG node or something similar.
450 * @param {Object} n The object to check
451 * @return {Boolean} True or false if the Object contains the methods needed to Drag
453 _canDrag: function(n) {
454 if (n && n.setXY && n.getXY && n.test && n.contains) {
460 * The default bubbleTarget for this object. Default: Y.DD.DDM
462 * @property _bubbleTargets
464 _bubbleTargets: Y.DD.DDM,
466 * Add this Drag instance to a group, this should be used for on-the-fly group additions.
468 * @param {String} g The group to add this Drag Instance to.
471 addToGroup: function(g) {
472 this._groups[g] = true;
473 DDM._activateTargets();
477 * Remove this Drag instance from a group, this should be used for on-the-fly group removals.
478 * @method removeFromGroup
479 * @param {String} g The group to remove this Drag Instance from.
482 removeFromGroup: function(g) {
483 delete this._groups[g];
484 DDM._activateTargets();
488 * This will be a reference to the Drop instance associated with this drag if the target: true config attribute is set..
494 * Attribute handler for the target config attribute.
496 * @method _handleTarget
497 * @param {Boolean/Object} config The Config
499 _handleTarget: function(config) {
501 if (config === false) {
503 DDM._unregTarget(this.target);
507 if (!Y.Lang.isObject(config)) {
510 config.bubbleTargets = config.bubbleTargets || this.getTargets();
511 config.node = this.get(NODE);
512 config.groups = config.groups || this.get('groups');
513 this.target = new Y.DD.Drop(config);
518 * Storage Array for the groups this drag belongs to.
525 * This method creates all the events for this Event Target and publishes them so we get Event Bubbling.
527 * @method _createEvents
529 _createEvents: function() {
531 this.publish(EV_MOUSE_DOWN, {
532 defaultFn: this._defMouseDownFn,
539 this.publish(EV_ALIGN, {
540 defaultFn: this._defAlignFn,
547 this.publish(EV_DRAG, {
548 defaultFn: this._defDragFn,
555 this.publish(EV_END, {
556 defaultFn: this._defEndFn,
557 preventedFn: this._prevEndFn,
578 Y.Array.each(ev, function(v) {
590 * A private reference to the mousedown DOM event
593 * @type {EventFacade}
597 * The getTime of the mousedown event. Not used, just here in case someone wants/needs to use it.
599 * @property _startTime
604 * The getTime of the mouseup event. Not used, just here in case someone wants/needs to use it.
611 * A private hash of the valid drag handles
618 * A private hash of the invalid selector strings
620 * @property _invalids
625 * A private hash of the default invalid selector strings: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true}
627 * @property _invalidsDefault
630 _invalidsDefault: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true },
632 * Private flag to see if the drag threshhold was met
634 * @property _dragThreshMet
637 _dragThreshMet: null,
639 * Flag to determine if the drag operation came from a timeout
641 * @property _fromTimeout
646 * Holder for the setTimeout call
648 * @property _clickTimeout
653 * The offset of the mouse position to the element's position
659 * The initial mouse position
665 * The initial element position
671 * The position of the element as it's moving (for offset calculations)
677 * The xy that the node will be set to. Changing this will alter the position as it's dragged.
683 * The real xy position of the node.
689 * The XY coords of the mousemove
695 * A region object associated with this drag, used for checking regions while dragging.
701 * Handler for the mouseup DOM event
703 * @method _handleMouseUp
704 * @param {EventFacade} ev The Event
706 _handleMouseUp: function() {
707 this.fire('drag:mouseup');
708 this._fixIEMouseUp();
709 if (DDM.activeDrag) {
714 * The function we use as the ondragstart handler when we start a drag
715 * in Internet Explorer. This keeps IE from blowing up on images as drag handles.
717 * @method _fixDragStart
718 * @param {Event} e The Event
720 _fixDragStart: function(e) {
721 if (this.validClick(e)) {
726 * The function we use as the onselectstart handler when we start a drag in Internet Explorer
728 * @method _ieSelectFix
730 _ieSelectFix: function() {
734 * We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
736 * @property _ieSelectBack
740 * This method copies the onselectstart listner on the document to the _ieSelectFix property
742 * @method _fixIEMouseDown
744 _fixIEMouseDown: function() {
746 this._ieSelectBack = Y.config.doc.body.onselectstart;
747 Y.config.doc.body.onselectstart = this._ieSelectFix;
751 * This method copies the _ieSelectFix property back to the onselectstart listner on the document.
753 * @method _fixIEMouseUp
755 _fixIEMouseUp: function() {
757 Y.config.doc.body.onselectstart = this._ieSelectBack;
761 * Handler for the mousedown DOM event
763 * @method _handleMouseDownEvent
764 * @param {EventFacade} ev The Event
766 _handleMouseDownEvent: function(ev) {
767 if (this.validClick(ev)) {
770 this.fire(EV_MOUSE_DOWN, { ev: ev });
773 * Handler for the mousedown DOM event
775 * @method _defMouseDownFn
776 * @param {EventFacade} e The Event
778 _defMouseDownFn: function(e) {
781 this._dragThreshMet = false;
784 if (this.get('primaryButtonOnly') && ev.button > 1) {
787 if (this.validClick(ev)) {
788 this._fixIEMouseDown(ev);
789 if (Drag.START_EVENT.indexOf('gesture') !== 0) {
790 //Only do these if it's not a gesture
791 if (this.get('haltDown')) {
798 this._setStartPosition([ev.pageX, ev.pageY]);
800 DDM.activeDrag = this;
802 this._clickTimeout = Y.later(this.get('clickTimeThresh'), this, this._timeoutCheck);
804 this.fire(EV_AFTER_MOUSE_DOWN, { ev: ev });
807 * Method first checks to see if we have handles, if so it validates the click
808 * against the handle. Then if it finds a valid handle, it checks it against
809 * the invalid handles list. Returns true if a good handle was used, false otherwise.
811 * @param {EventFacade} ev The Event
814 validClick: function(ev) {
815 var r = false, n = false,
822 Y.Object.each(this._handles, function(i, n) {
823 if (i instanceof Y.Node || i instanceof Y.NodeList) {
826 if (nlist instanceof Y.Node) {
827 nlist = new Y.NodeList(i._node);
829 nlist.each(function(nl) {
830 if (nl.contains(tar)) {
835 } else if (Y.Lang.isString(n)) {
836 //Am I this or am I inside this
837 if (tar.test(n + ', ' + n + ' *') && !hTest) {
845 if (n.contains(tar) || n.compareTo(tar)) {
850 if (this._invalids) {
851 Y.Object.each(this._invalids, function(i, n) {
852 if (Y.Lang.isString(n)) {
853 //Am I this or am I inside this
854 if (tar.test(n + ', ' + n + ' *')) {
863 els = ev.currentTarget.all(hTest);
865 els.each(function(n) {
866 if ((n.contains(tar) || n.compareTo(tar)) && !set) {
868 this.set('activeHandle', n);
872 this.set('activeHandle', this.get(NODE));
878 * Sets the current position of the Element and calculates the offset
880 * @method _setStartPosition
881 * @param {Array} xy The XY coords to set the position to.
883 _setStartPosition: function(xy) {
886 this.nodeXY = this.lastXY = this.realXY = this.get(NODE).getXY();
888 if (this.get('offsetNode')) {
889 this.deltaXY = [(this.startXY[0] - this.nodeXY[0]), (this.startXY[1] - this.nodeXY[1])];
891 this.deltaXY = [0, 0];
895 * The method passed to setTimeout to determine if the clickTimeThreshold was met.
897 * @method _timeoutCheck
899 _timeoutCheck: function() {
900 if (!this.get('lock') && !this._dragThreshMet && this._ev_md) {
901 this._fromTimeout = this._dragThreshMet = true;
903 this._alignNode([this._ev_md.pageX, this._ev_md.pageY], true);
907 * Remove a Selector added by addHandle
908 * @method removeHandle
909 * @param {String} str The selector for the handle to be removed.
912 removeHandle: function(str) {
914 if (str instanceof Y.Node || str instanceof Y.NodeList) {
917 if (this._handles[key]) {
918 delete this._handles[key];
919 this.fire(EV_REMOVE_HANDLE, { handle: str });
924 * Add a handle to a drag element. Drag only initiates when a mousedown happens on this element.
926 * @param {String} str The selector to test for a valid handle. Must be a child of the element.
929 addHandle: function(str) {
930 if (!this._handles) {
934 if (str instanceof Y.Node || str instanceof Y.NodeList) {
937 this._handles[key] = str;
938 this.fire(EV_ADD_HANDLE, { handle: str });
942 * Remove an invalid handle added by addInvalid
943 * @method removeInvalid
944 * @param {String} str The invalid handle to remove from the internal list.
947 removeInvalid: function(str) {
948 if (this._invalids[str]) {
949 this._invalids[str] = null;
950 delete this._invalids[str];
951 this.fire(EV_REMOVE_INVALID, { handle: str });
956 * Add a selector string to test the handle against. If the test passes the drag operation will not continue.
958 * @param {String} str The selector to test against to determine if this is an invalid drag handle.
961 addInvalid: function(str) {
962 if (Y.Lang.isString(str)) {
963 this._invalids[str] = true;
964 this.fire(EV_ADD_INVALID, { handle: str });
969 * Internal init handler
971 * @method initializer
973 initializer: function() {
975 this.get(NODE).dd = this;
977 if (!this.get(NODE).get('id')) {
978 var id = Y.stamp(this.get(NODE));
979 this.get(NODE).set('id', id);
984 this._invalids = Y.clone(this._invalidsDefault, true);
986 this._createEvents();
988 if (!this.get(DRAG_NODE)) {
989 this.set(DRAG_NODE, this.get(NODE));
993 //Don't prep the DD instance until all plugins are loaded.
994 this.on('initializedChange', Y.bind(this._prep, this));
996 //Shouldn't have to do this..
997 this.set('groups', this.get('groups'));
1000 * Attach event listners and add classname
1005 this._dragThreshMet = false;
1006 var node = this.get(NODE);
1007 node.addClass(DDM.CSS_PREFIX + '-draggable');
1008 node.on(Drag.START_EVENT, Y.bind(this._handleMouseDownEvent, this));
1009 node.on('mouseup', Y.bind(this._handleMouseUp, this));
1010 node.on('dragstart', Y.bind(this._fixDragStart, this));
1013 * Detach event listeners and remove classname
1017 _unprep: function() {
1018 var node = this.get(NODE);
1019 node.removeClass(DDM.CSS_PREFIX + '-draggable');
1020 node.detachAll('mouseup');
1021 node.detachAll('dragstart');
1022 node.detachAll(Drag.START_EVENT);
1024 this.deltaXY = [0,0];
1032 * Starts the drag operation
1037 if (!this.get('lock') && !this.get(DRAGGING)) {
1038 var node = this.get(NODE), ow, oh, xy;
1039 this._startTime = (new Date()).getTime();
1042 node.addClass(DDM.CSS_PREFIX + '-dragging');
1043 this.fire(EV_START, {
1044 pageX: this.nodeXY[0],
1045 pageY: this.nodeXY[1],
1046 startTime: this._startTime
1048 node = this.get(DRAG_NODE);
1051 ow = node.get(OFFSET_WIDTH);
1052 oh = node.get(OFFSET_HEIGHT);
1054 if (this.get('startCentered')) {
1055 this._setStartPosition([xy[0] + (ow / 2), xy[1] + (oh / 2)]);
1068 this.set(DRAGGING, true);
1073 * Ends the drag operation
1078 this._endTime = (new Date()).getTime();
1079 if (this._clickTimeout) {
1080 this._clickTimeout.cancel();
1082 this._dragThreshMet = this._fromTimeout = false;
1084 if (!this.get('lock') && this.get(DRAGGING)) {
1086 pageX: this.lastXY[0],
1087 pageY: this.lastXY[1],
1088 startTime: this._startTime,
1089 endTime: this._endTime
1092 this.get(NODE).removeClass(DDM.CSS_PREFIX + '-dragging');
1093 this.set(DRAGGING, false);
1094 this.deltaXY = [0, 0];
1099 * Handler for fixing the selection in IE
1103 _defEndFn: function() {
1104 this._fixIEMouseUp();
1108 * Handler for preventing the drag:end event. It will reset the node back to it's start position
1110 * @method _prevEndFn
1112 _prevEndFn: function() {
1113 this._fixIEMouseUp();
1115 this.get(DRAG_NODE).setXY(this.nodeXY);
1120 * Calculates the offsets and set's the XY that the element will move to.
1123 * @param {Array} xy The xy coords to align with.
1125 _align: function(xy) {
1126 this.fire(EV_ALIGN, {pageX: xy[0], pageY: xy[1] });
1129 * Calculates the offsets and set's the XY that the element will move to.
1131 * @method _defAlignFn
1132 * @param {EventFacade} e The drag:align event.
1134 _defAlignFn: function(e) {
1135 this.actXY = [e.pageX - this.deltaXY[0], e.pageY - this.deltaXY[1]];
1138 * This method performs the alignment before the element move.
1140 * @method _alignNode
1141 * @param {Array} eXY The XY to move the element to, usually comes from the mousemove DOM event.
1143 _alignNode: function(eXY, scroll) {
1150 * This method performs the actual element move.
1154 _moveNode: function(scroll) {
1155 //if (!this.get(DRAGGING)) {
1158 var diffXY = [], diffXY2 = [], startXY = this.nodeXY, xy = this.actXY;
1160 diffXY[0] = (xy[0] - this.lastXY[0]);
1161 diffXY[1] = (xy[1] - this.lastXY[1]);
1163 diffXY2[0] = (xy[0] - this.nodeXY[0]);
1164 diffXY2[1] = (xy[1] - this.nodeXY[1]);
1172 right: xy[0] + this.get(DRAG_NODE).get(OFFSET_WIDTH),
1173 bottom: xy[1] + this.get(DRAG_NODE).get(OFFSET_HEIGHT),
1177 this.fire(EV_DRAG, {
1192 * Default function for drag:drag. Fired from _moveNode.
1194 * @method _defDragFn
1195 * @param {EventFacade} ev The drag:drag event
1197 _defDragFn: function(e) {
1198 if (this.get('move')) {
1199 if (e.scroll && e.scroll.node) {
1200 var domNode = e.scroll.node.getDOMNode();
1201 //If it's the window
1202 if (domNode === Y.config.win) {
1203 domNode.scrollTo(e.scroll.left, e.scroll.top);
1205 e.scroll.node.set('scrollTop', e.scroll.top);
1206 e.scroll.node.set('scrollLeft', e.scroll.left);
1209 this.get(DRAG_NODE).setXY([e.pageX, e.pageY]);
1210 this.realXY = [e.pageX, e.pageY];
1214 * Fired from DragDropMgr (DDM) on mousemove.
1217 * @param {EventFacade} ev The mousemove DOM event
1219 _move: function(ev) {
1220 if (this.get('lock')) {
1224 this.mouseXY = [ev.pageX, ev.pageY];
1225 if (!this._dragThreshMet) {
1226 var diffX = Math.abs(this.startXY[0] - ev.pageX),
1227 diffY = Math.abs(this.startXY[1] - ev.pageY);
1228 if (diffX > this.get('clickPixelThresh') || diffY > this.get('clickPixelThresh')) {
1229 this._dragThreshMet = true;
1231 //This only happens on gestures to stop the page from scrolling
1232 if (ev && ev.preventDefault) {
1233 ev.preventDefault();
1235 this._alignNode([ev.pageX, ev.pageY]);
1238 if (this._clickTimeout) {
1239 this._clickTimeout.cancel();
1241 this._alignNode([ev.pageX, ev.pageY]);
1245 * Method will forcefully stop a drag operation. For example calling this from inside an ESC keypress handler will stop this drag.
1249 stopDrag: function() {
1250 if (this.get(DRAGGING)) {
1256 * Lifecycle destructor, unreg the drag from the DDM and remove listeners
1258 * @method destructor
1260 destructor: function() {
1263 this.target.destroy();
1265 DDM._unregDrag(this);
1274 }, '3.15.0', {"requires": ["dd-ddm-base"]});