drag.js revision 23353a53c7478bead2dcf9e89dc706930671ee44
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * Provides the ability to drag a Node.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @module dd
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @submodule dd-drag
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
09c638a157dd9d2ed9027215d9e254badfa019b8Dav Glass /**
09c638a157dd9d2ed9027215d9e254badfa019b8Dav Glass * Provides the ability to drag a Node.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @class Drag
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @extends Base
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @constructor
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @namespace DD
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass var DDM = Y.DD.DDM,
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass NODE = 'node',
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass DRAGGING = 'dragging',
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass DRAG_NODE = 'dragNode',
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass OFFSET_HEIGHT = 'offsetHeight',
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass OFFSET_WIDTH = 'offsetWidth',
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @event drag:mouseup
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description Handles the mouseup DOM event, does nothing internally just fires.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @bubbles DDM
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * @type {CustomEvent}
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass */
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass /**
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * @event drag:mouseDown
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * @description Handles the mousedown DOM event, checks to see if you have a valid handle then starts the drag timers.
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * @preventable _defMouseDownFn
364e2a6af13dafc0a78fda276167a477b2f7aabfDav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
364e2a6af13dafc0a78fda276167a477b2f7aabfDav Glass * <dl><dt>ev</dt><dd>The original mousedown event.</dd></dl>
364e2a6af13dafc0a78fda276167a477b2f7aabfDav Glass * @bubbles DDM
364e2a6af13dafc0a78fda276167a477b2f7aabfDav Glass * @type {CustomEvent}
364e2a6af13dafc0a78fda276167a477b2f7aabfDav Glass */
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass EV_MOUSE_DOWN = 'drag:mouseDown',
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass /**
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * @event drag:afterMouseDown
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description Fires after the mousedown event has been cleared.
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * <dl><dt>ev</dt><dd>The original mousedown event.</dd></dl>
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @bubbles DDM
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type {CustomEvent}
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass EV_AFTER_MOUSE_DOWN = 'drag:afterMouseDown',
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @event drag:removeHandle
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description Fires after a handle is removed.
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dl><dt>handle</dt><dd>The handle that was removed.</dd></dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @type {CustomEvent}
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass EV_REMOVE_HANDLE = 'drag:removeHandle',
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @event drag:addHandle
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @description Fires after a handle is added.
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dl><dt>handle</dt><dd>The handle that was added.</dd></dl>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @bubbles DDM
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @type {CustomEvent}
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass */
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass EV_ADD_HANDLE = 'drag:addHandle',
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
db9067a7aace004de2603396af611d5a294bc554Dav Glass * @event drag:removeInvalid
db9067a7aace004de2603396af611d5a294bc554Dav Glass * @description Fires after an invalid selector is removed.
db9067a7aace004de2603396af611d5a294bc554Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dl><dt>handle</dt><dd>The handle that was removed.</dd></dl>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @bubbles DDM
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @type {CustomEvent}
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass */
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass EV_REMOVE_INVALID = 'drag:removeInvalid',
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @event drag:addInvalid
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @description Fires after an invalid selector is added.
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dl><dt>handle</dt><dd>The handle that was added.</dd></dl>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @bubbles DDM
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @type {CustomEvent}
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass */
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass EV_ADD_INVALID = 'drag:addInvalid',
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @event drag:start
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @description Fires at the start of a drag operation.
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dl>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dt>pageX</dt><dd>The original node position X.</dd>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dt>pageY</dt><dd>The original node position Y.</dd>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * <dt>startTime</dt><dd>The startTime of the event. getTime on the current Date object.</dd>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * </dl>
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @bubbles DDM
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @type {CustomEvent}
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass */
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass EV_START = 'drag:start',
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @event drag:end
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @description Fires at the end of a drag operation.
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * <dl>
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass * <dt>pageX</dt><dd>The current node position X.</dd>
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass * <dt>pageY</dt><dd>The current node position Y.</dd>
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass * <dt>startTime</dt><dd>The startTime of the event, from the start event.</dd>
a5b442fa7022cb624533685ed17a7cfe6344890dDav Glass * <dt>endTime</dt><dd>The endTime of the event. getTime on the current Date object.</dd>
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass * </dl>
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass * @bubbles DDM
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass * @type {CustomEvent}
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass */
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass EV_END = 'drag:end',
c03e8210b031a389a9441f7f550a03d1272bac31Dav Glass /**
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @event drag:drag
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @description Fires every mousemove during a drag operation.
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * <dl>
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * <dt>pageX</dt><dd>The current node position X.</dd>
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * <dt>pageY</dt><dd>The current node position Y.</dd>
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * <dt>scroll</dt><dd>Should a scroll action occur.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>info</dt><dd>Object hash containing calculated XY arrays: start, xy, delta, offset</dd>
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * </dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type {CustomEvent}
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass EV_DRAG = 'drag:drag',
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass /**
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @event drag:align
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @preventable _defAlignFn
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @description Fires when this node is aligned.
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>pageX</dt><dd>The current node position X.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>pageY</dt><dd>The current node position Y.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * </dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type {CustomEvent}
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass EV_ALIGN = 'drag:align',
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass /**
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @event drag:over
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @description Fires when this node is over a Drop Target. (Fired from dd-drop)
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * </dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type {CustomEvent}
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass /**
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @event drag:enter
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @description Fires when this node enters a Drop Target. (Fired from dd-drop)
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * </dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type {CustomEvent}
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass /**
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @event drag:exit
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @description Fires when this node exits a Drop Target. (Fired from dd-drop)
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drop</dt><dd>The drop object at the time of the event.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * </dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type {CustomEvent}
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass /**
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @event drag:drophit
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @description Fires when this node is dropped on a valid Drop Target. (Fired from dd-ddm-drop)
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drop</dt><dd>The best guess on what was dropped on.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>drag</dt><dd>The drag object at the time of the event.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * <dt>others</dt><dd>An array of all the other drop targets that was dropped on.</dd>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * </dl>
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @bubbles DDM
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type {CustomEvent}
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass /**
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @event drag:dropmiss
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @description Fires when this node is dropped on an invalid Drop Target. (Fired from dd-ddm-drop)
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @param {EventFacade} event An Event Facade object with the following specific property added:
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * <dl>
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * <dt>pageX</dt><dd>The current node position X.</dd>
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * <dt>pageY</dt><dd>The current node position Y.</dd>
677d6ad6503f3daaaaf9800c58eec9e00fee4cddDav Glass * </dl>
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @bubbles DDM
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type {CustomEvent}
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass Drag = function(o) {
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass this._lazyAddAttrs = false;
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass Drag.superclass.constructor.apply(this, arguments);
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass var valid = DDM._regDrag(this);
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass if (!valid) {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass Y.error('Failed to register node, already in use: ' + o.node);
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass }
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass };
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass Drag.NAME = 'drag';
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass /**
0523d0a8daaa474f0214203f8cbb0bc4a88e2964Dav Glass * This property defaults to "mousedown", but when drag-gestures is loaded, it is changed to "gesturemovestart"
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @static
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @property START_EVENT
216633e2ad28e9568a902f3763c3bef052c5f908Dav Glass */
aa2ac226ad6e45232f8416eecc99d2165ce74d03Dav Glass Drag.START_EVENT = 'mousedown';
5432371fbb6d790a76159481f0dd16e806812153Dav Glass
aa2ac226ad6e45232f8416eecc99d2165ce74d03Dav Glass Drag.ATTRS = {
5432371fbb6d790a76159481f0dd16e806812153Dav Glass /**
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @attribute node
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @description Y.Node instance to use as the element to initiate a drag operation
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @type Node
5432371fbb6d790a76159481f0dd16e806812153Dav Glass */
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass node: {
5432371fbb6d790a76159481f0dd16e806812153Dav Glass setter: function(node) {
5432371fbb6d790a76159481f0dd16e806812153Dav Glass if (this._canDrag(node)) {
5432371fbb6d790a76159481f0dd16e806812153Dav Glass return node;
5432371fbb6d790a76159481f0dd16e806812153Dav Glass }
5432371fbb6d790a76159481f0dd16e806812153Dav Glass var n = Y.one(node);
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass if (!n) {
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass Y.error('DD.Drag: Invalid Node Given: ' + node);
5432371fbb6d790a76159481f0dd16e806812153Dav Glass }
5432371fbb6d790a76159481f0dd16e806812153Dav Glass return n;
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass }
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass },
5432371fbb6d790a76159481f0dd16e806812153Dav Glass /**
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @attribute dragNode
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @description Y.Node instance to use as the draggable element, defaults to node
5432371fbb6d790a76159481f0dd16e806812153Dav Glass * @type Node
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass */
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass dragNode: {
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass setter: function(node) {
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass if (this._canDrag(node)) {
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass return node;
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass }
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass var n = Y.one(node);
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass if (!n) {
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass Y.error('DD.Drag: Invalid dragNode Given: ' + node);
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass }
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass return n;
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass }
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass },
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass /**
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass * @attribute offsetNode
f7aa62ea2e8cf43fbb9d83db5060db540ff1893fDav Glass * @description Offset the drag element by the difference in cursor position: default true
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Boolean
96c1e6aab172b57cf3566abee931c26676990044Dav Glass */
e4f71ec590faf50c1621b6b2c32bae83eb73ee74Dav Glass offsetNode: {
96c1e6aab172b57cf3566abee931c26676990044Dav Glass value: true
96c1e6aab172b57cf3566abee931c26676990044Dav Glass },
96c1e6aab172b57cf3566abee931c26676990044Dav Glass /**
96c1e6aab172b57cf3566abee931c26676990044Dav Glass * @attribute startCentered
96c1e6aab172b57cf3566abee931c26676990044Dav Glass * @description Center the dragNode to the mouse position on drag:start: default false
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass * @type Boolean
6dbc2e0b2c23ae7763959af9762fc50c84dbd937Dav Glass */
96c1e6aab172b57cf3566abee931c26676990044Dav Glass startCentered: {
96c1e6aab172b57cf3566abee931c26676990044Dav Glass value: false
96c1e6aab172b57cf3566abee931c26676990044Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute clickPixelThresh
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @description The number of pixels to move to start a drag operation, default is 3.
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @type Number
7a67e82a93bc7dc5bf9a62a3ad321c2424da37f7Dav Glass */
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass clickPixelThresh: {
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass value: DDM.get('clickPixelThresh')
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass },
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass * @attribute clickTimeThresh
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description The number of milliseconds a mousedown has to pass to start a drag operation, default is 1000.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Number
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass clickTimeThresh: {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass value: DDM.get('clickTimeThresh')
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute lock
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass * @description Set to lock this drag element so that it can't be dragged: default false.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Boolean
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass lock: {
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass value: false,
162527ab925c04aa8d6bbf78d0484a133a8076f1Dav Glass setter: function(lock) {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass if (lock) {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass this.get(NODE).addClass(DDM.CSS_PREFIX + '-locked');
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass } else {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass this.get(NODE).removeClass(DDM.CSS_PREFIX + '-locked');
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass }
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass return lock;
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass }
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute data
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description A payload holder to store arbitrary data about this drag object, can be used to store any value.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Mixed
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass data: {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass value: false
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute move
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description If this is false, the drag element will not move with the cursor: default true. Can be used to "resize" the element.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Boolean
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass move: {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass value: true
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute useShim
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description Use the protective shim on all drag operations: default true. Only works with dd-ddm, not dd-ddm-base.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Boolean
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass useShim: {
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass value: true
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass },
0db84e0da684308b0fd9ea9b5906c11bafa7a246Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute activeHandle
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description This 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.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Node
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d0bccce76452becc96b65acaaa684aa6fabaf386Dav Glass activeHandle: {
d0bccce76452becc96b65acaaa684aa6fabaf386Dav Glass value: false
d0bccce76452becc96b65acaaa684aa6fabaf386Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute primaryButtonOnly
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description By default a drag operation will only begin if the mousedown occurred with the primary mouse button. Setting this to false will allow for all mousedown events to trigger a drag.
d0bccce76452becc96b65acaaa684aa6fabaf386Dav Glass * @type Boolean
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass primaryButtonOnly: {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass value: true
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d0bccce76452becc96b65acaaa684aa6fabaf386Dav Glass * @attribute dragging
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description 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.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Boolean
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass dragging: {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass value: false
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass parent: {
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass value: false
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass },
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass /**
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @attribute target
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @description This attribute only works if the dd-drop module has been loaded. It will make this node a drop target as well as draggable.
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass * @type Boolean
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass */
d2a5a45ff58ab15a8ee0339edcd03f0243373d59Dav Glass target: {
value: false,
setter: function(config) {
this._handleTarget(config);
return config;
}
},
/**
* @attribute dragMode
* @description This attribute only works if the dd-drop module is active. It will set the dragMode (point, intersect, strict) of this Drag instance.
* @type String
*/
dragMode: {
value: null,
setter: function(mode) {
return DDM._setDragMode(mode);
}
},
/**
* @attribute groups
* @description Array of groups to add this drag into.
* @type Array
*/
groups: {
value: ['default'],
getter: function() {
if (!this._groups) {
this._groups = {};
}
var ret = [];
Y.each(this._groups, function(v, k) {
ret[ret.length] = k;
});
return ret;
},
setter: function(g) {
this._groups = {};
Y.each(g, function(v, k) {
this._groups[v] = true;
}, this);
return g;
}
},
/**
* @attribute handles
* @description Array of valid handles to add. Adding something here will set all handles, even if previously added with addHandle
* @type Array
*/
handles: {
value: null,
setter: function(g) {
if (g) {
this._handles = {};
Y.each(g, function(v, k) {
var key = v;
if (v instanceof Y.Node || v instanceof Y.NodeList) {
key = v._yuid;
}
this._handles[key] = v;
}, this);
} else {
this._handles = null;
}
return g;
}
},
/**
* @deprecated
* @attribute bubbles
* @description Controls the default bubble parent for this Drag instance. Default: Y.DD.DDM. Set to false to disable bubbling. Use bubbleTargets in config
* @type Object
*/
bubbles: {
setter: function(t) {
Y.log('bubbles is deprecated use bubbleTargets: HOST', 'warn', 'dd');
this.addTarget(t);
return t;
}
},
/**
* @attribute haltDown
* @description Should the mousedown event be halted. Default: true
* @type Boolean
*/
haltDown: {
value: true
}
};
Y.extend(Drag, Y.Base, {
/**
* Checks the object for the methods needed to drag the object around.
* Normally this would be a node instance, but in the case of Graphics, it
* may be an SVG node or something similar.
* @method _canDrag
* @private
* @param {Object} n The object to check
* @return {Boolean} True or false if the Object contains the methods needed to Drag
*/
_canDrag: function(n) {
if (n && n.setXY && n.getXY && n.test && n.contains) {
return true;
}
return false;
},
/**
* @private
* @property _bubbleTargets
* @description The default bubbleTarget for this object. Default: Y.DD.DDM
*/
_bubbleTargets: Y.DD.DDM,
/**
* @method addToGroup
* @description Add this Drag instance to a group, this should be used for on-the-fly group additions.
* @param {String} g The group to add this Drag Instance to.
* @return {Self}
* @chainable
*/
addToGroup: function(g) {
this._groups[g] = true;
DDM._activateTargets();
return this;
},
/**
* @method removeFromGroup
* @description Remove this Drag instance from a group, this should be used for on-the-fly group removals.
* @param {String} g The group to remove this Drag Instance from.
* @return {Self}
* @chainable
*/
removeFromGroup: function(g) {
delete this._groups[g];
DDM._activateTargets();
return this;
},
/**
* @property target
* @description This will be a reference to the Drop instance associated with this drag if the target: true config attribute is set..
* @type {Object}
*/
target: null,
/**
* @private
* @method _handleTarget
* @description Attribute handler for the target config attribute.
* @param {Boolean/Object} config The Config
*/
_handleTarget: function(config) {
if (Y.DD.Drop) {
if (config === false) {
if (this.target) {
DDM._unregTarget(this.target);
this.target = null;
}
return false;
} else {
if (!Y.Lang.isObject(config)) {
config = {};
}
config.bubbleTargets = ('bubbleTargets' in config) ? config.bubbleTargets : Y.Object.values(this._yuievt.targets);
config.node = this.get(NODE);
config.groups = config.groups || this.get('groups');
this.target = new Y.DD.Drop(config);
}
} else {
return false;
}
},
/**
* @private
* @property _groups
* @description Storage Array for the groups this drag belongs to.
* @type {Array}
*/
_groups: null,
/**
* @private
* @method _createEvents
* @description This method creates all the events for this Event Target and publishes them so we get Event Bubbling.
*/
_createEvents: function() {
this.publish(EV_MOUSE_DOWN, {
defaultFn: this._defMouseDownFn,
queuable: false,
emitFacade: true,
bubbles: true,
prefix: 'drag'
});
this.publish(EV_ALIGN, {
defaultFn: this._defAlignFn,
queuable: false,
emitFacade: true,
bubbles: true,
prefix: 'drag'
});
this.publish(EV_DRAG, {
defaultFn: this._defDragFn,
queuable: false,
emitFacade: true,
bubbles: true,
prefix: 'drag'
});
this.publish(EV_END, {
defaultFn: this._defEndFn,
preventedFn: this._prevEndFn,
queuable: false,
emitFacade: true,
bubbles: true,
prefix: 'drag'
});
var ev = [
EV_AFTER_MOUSE_DOWN,
EV_REMOVE_HANDLE,
EV_ADD_HANDLE,
EV_REMOVE_INVALID,
EV_ADD_INVALID,
EV_START,
'drag:drophit',
'drag:dropmiss',
'drag:over',
'drag:enter',
'drag:exit'
];
Y.each(ev, function(v, k) {
this.publish(v, {
type: v,
emitFacade: true,
bubbles: true,
preventable: false,
queuable: false,
prefix: 'drag'
});
}, this);
},
/**
* @private
* @property _ev_md
* @description A private reference to the mousedown DOM event
* @type {EventFacade}
*/
_ev_md: null,
/**
* @private
* @property _startTime
* @description The getTime of the mousedown event. Not used, just here in case someone wants/needs to use it.
* @type Date
*/
_startTime: null,
/**
* @private
* @property _endTime
* @description The getTime of the mouseup event. Not used, just here in case someone wants/needs to use it.
* @type Date
*/
_endTime: null,
/**
* @private
* @property _handles
* @description A private hash of the valid drag handles
* @type {Object}
*/
_handles: null,
/**
* @private
* @property _invalids
* @description A private hash of the invalid selector strings
* @type {Object}
*/
_invalids: null,
/**
* @private
* @property _invalidsDefault
* @description A private hash of the default invalid selector strings: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true}
* @type {Object}
*/
_invalidsDefault: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true },
/**
* @private
* @property _dragThreshMet
* @description Private flag to see if the drag threshhold was met
* @type {Boolean}
*/
_dragThreshMet: null,
/**
* @private
* @property _fromTimeout
* @description Flag to determine if the drag operation came from a timeout
* @type {Boolean}
*/
_fromTimeout: null,
/**
* @private
* @property _clickTimeout
* @description Holder for the setTimeout call
* @type {Boolean}
*/
_clickTimeout: null,
/**
* @property deltaXY
* @description The offset of the mouse position to the element's position
* @type {Array}
*/
deltaXY: null,
/**
* @property startXY
* @description The initial mouse position
* @type {Array}
*/
startXY: null,
/**
* @property nodeXY
* @description The initial element position
* @type {Array}
*/
nodeXY: null,
/**
* @property lastXY
* @description The position of the element as it's moving (for offset calculations)
* @type {Array}
*/
lastXY: null,
/**
* @property actXY
* @description The xy that the node will be set to. Changing this will alter the position as it's dragged.
* @type {Array}
*/
actXY: null,
/**
* @property realXY
* @description The real xy position of the node.
* @type {Array}
*/
realXY: null,
/**
* @property mouseXY
* @description The XY coords of the mousemove
* @type {Array}
*/
mouseXY: null,
/**
* @property region
* @description A region object associated with this drag, used for checking regions while dragging.
* @type Object
*/
region: null,
/**
* @private
* @method _handleMouseUp
* @description Handler for the mouseup DOM event
* @param {EventFacade} ev The Event
*/
_handleMouseUp: function(ev) {
this.fire('drag:mouseup');
this._fixIEMouseUp();
if (DDM.activeDrag) {
DDM._end();
}
},
/**
* @private
* @method _fixDragStart
* @description The function we use as the ondragstart handler when we start a drag in Internet Explorer. This keeps IE from blowing up on images as drag handles.
* @param {Event} e The Event
*/
_fixDragStart: function(e) {
e.preventDefault();
},
/**
* @private
* @method _ieSelectFix
* @description The function we use as the onselectstart handler when we start a drag in Internet Explorer
*/
_ieSelectFix: function() {
return false;
},
/**
* @private
* @property _ieSelectBack
* @description We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
*/
_ieSelectBack: null,
/**
* @private
* @method _fixIEMouseDown
* @description This method copies the onselectstart listner on the document to the _ieSelectFix property
*/
_fixIEMouseDown: function(e) {
if (Y.UA.ie) {
this._ieSelectBack = Y.config.doc.body.onselectstart;
Y.config.doc.body.onselectstart = this._ieSelectFix;
}
},
/**
* @private
* @method _fixIEMouseUp
* @description This method copies the _ieSelectFix property back to the onselectstart listner on the document.
*/
_fixIEMouseUp: function() {
if (Y.UA.ie) {
Y.config.doc.body.onselectstart = this._ieSelectBack;
}
},
/**
* @private
* @method _handleMouseDownEvent
* @description Handler for the mousedown DOM event
* @param {EventFacade} ev The Event
*/
_handleMouseDownEvent: function(ev) {
this.fire(EV_MOUSE_DOWN, { ev: ev });
},
/**
* @private
* @method _defMouseDownFn
* @description Handler for the mousedown DOM event
* @param {EventFacade} e The Event
*/
_defMouseDownFn: function(e) {
var ev = e.ev;
this._dragThreshMet = false;
this._ev_md = ev;
if (this.get('primaryButtonOnly') && ev.button > 1) {
return false;
}
if (this.validClick(ev)) {
this._fixIEMouseDown(ev);
if (this.get('haltDown')) {
Y.log('Halting MouseDown', 'info', 'drag');
ev.halt();
} else {
Y.log('Preventing Default on MouseDown', 'info', 'drag');
ev.preventDefault();
}
this._setStartPosition([ev.pageX, ev.pageY]);
DDM.activeDrag = this;
this._clickTimeout = Y.later(this.get('clickTimeThresh'), this, this._timeoutCheck);
}
this.fire(EV_AFTER_MOUSE_DOWN, { ev: ev });
},
/**
* @method validClick
* @description Method first checks to see if we have handles, if so it validates the click against the handle. Then if it finds a valid handle, it checks it against the invalid handles list. Returns true if a good handle was used, false otherwise.
* @param {EventFacade} ev The Event
* @return {Boolean}
*/
validClick: function(ev) {
var r = false, n = false,
tar = ev.target,
hTest = null,
els = null,
nlist = null,
set = false;
if (this._handles) {
Y.each(this._handles, function(i, n) {
if (i instanceof Y.Node || i instanceof Y.NodeList) {
if (!r) {
nlist = i;
if (nlist instanceof Y.Node) {
nlist = new Y.NodeList(i._node);
}
nlist.each(function(nl) {
if (nl.contains(tar)) {
r = true;
}
});
}
} else if (Y.Lang.isString(n)) {
//Am I this or am I inside this
if (tar.test(n + ', ' + n + ' *') && !hTest) {
hTest = n;
r = true;
}
}
});
} else {
n = this.get(NODE);
if (n.contains(tar) || n.compareTo(tar)) {
r = true;
}
}
if (r) {
if (this._invalids) {
Y.each(this._invalids, function(i, n) {
if (Y.Lang.isString(n)) {
//Am I this or am I inside this
if (tar.test(n + ', ' + n + ' *')) {
r = false;
}
}
});
}
}
if (r) {
if (hTest) {
els = ev.currentTarget.all(hTest);
set = false;
els.each(function(n, i) {
if ((n.contains(tar) || n.compareTo(tar)) && !set) {
set = true;
this.set('activeHandle', n);
}
}, this);
} else {
this.set('activeHandle', this.get(NODE));
}
}
return r;
},
/**
* @private
* @method _setStartPosition
* @description Sets the current position of the Element and calculates the offset
* @param {Array} xy The XY coords to set the position to.
*/
_setStartPosition: function(xy) {
this.startXY = xy;
this.nodeXY = this.lastXY = this.realXY = this.get(NODE).getXY();
if (this.get('offsetNode')) {
this.deltaXY = [(this.startXY[0] - this.nodeXY[0]), (this.startXY[1] - this.nodeXY[1])];
} else {
this.deltaXY = [0, 0];
}
},
/**
* @private
* @method _timeoutCheck
* @description The method passed to setTimeout to determine if the clickTimeThreshold was met.
*/
_timeoutCheck: function() {
if (!this.get('lock') && !this._dragThreshMet && this._ev_md) {
this._fromTimeout = this._dragThreshMet = true;
this.start();
this._alignNode([this._ev_md.pageX, this._ev_md.pageY], true);
}
},
/**
* @method removeHandle
* @description Remove a Selector added by addHandle
* @param {String} str The selector for the handle to be removed.
* @return {Self}
* @chainable
*/
removeHandle: function(str) {
var key = str;
if (str instanceof Y.Node || str instanceof Y.NodeList) {
key = str._yuid;
}
if (this._handles[key]) {
delete this._handles[key];
this.fire(EV_REMOVE_HANDLE, { handle: str });
}
return this;
},
/**
* @method addHandle
* @description Add a handle to a drag element. Drag only initiates when a mousedown happens on this element.
* @param {String} str The selector to test for a valid handle. Must be a child of the element.
* @return {Self}
* @chainable
*/
addHandle: function(str) {
if (!this._handles) {
this._handles = {};
}
var key = str;
if (str instanceof Y.Node || str instanceof Y.NodeList) {
key = str._yuid;
}
this._handles[key] = str;
this.fire(EV_ADD_HANDLE, { handle: str });
return this;
},
/**
* @method removeInvalid
* @description Remove an invalid handle added by addInvalid
* @param {String} str The invalid handle to remove from the internal list.
* @return {Self}
* @chainable
*/
removeInvalid: function(str) {
if (this._invalids[str]) {
this._invalids[str] = null;
delete this._invalids[str];
this.fire(EV_REMOVE_INVALID, { handle: str });
}
return this;
},
/**
* @method addInvalid
* @description Add a selector string to test the handle against. If the test passes the drag operation will not continue.
* @param {String} str The selector to test against to determine if this is an invalid drag handle.
* @return {Self}
* @chainable
*/
addInvalid: function(str) {
if (Y.Lang.isString(str)) {
this._invalids[str] = true;
this.fire(EV_ADD_INVALID, { handle: str });
}
return this;
},
/**
* @private
* @method initializer
* @description Internal init handler
*/
initializer: function(cfg) {
this.get(NODE).dd = this;
if (!this.get(NODE).get('id')) {
var id = Y.stamp(this.get(NODE));
this.get(NODE).set('id', id);
}
this.actXY = [];
this._invalids = Y.clone(this._invalidsDefault, true);
this._createEvents();
if (!this.get(DRAG_NODE)) {
this.set(DRAG_NODE, this.get(NODE));
}
//Fix for #2528096
//Don't prep the DD instance until all plugins are loaded.
this.on('initializedChange', Y.bind(this._prep, this));
//Shouldn't have to do this..
this.set('groups', this.get('groups'));
},
/**
* @private
* @method _prep
* @description Attach event listners and add classname
*/
_prep: function() {
this._dragThreshMet = false;
var node = this.get(NODE);
node.addClass(DDM.CSS_PREFIX + '-draggable');
node.on(Drag.START_EVENT, Y.bind(this._handleMouseDownEvent, this));
node.on('mouseup', Y.bind(this._handleMouseUp, this));
node.on('dragstart', Y.bind(this._fixDragStart, this));
},
/**
* @private
* @method _unprep
* @description Detach event listeners and remove classname
*/
_unprep: function() {
var node = this.get(NODE);
node.removeClass(DDM.CSS_PREFIX + '-draggable');
node.detachAll('mouseup');
node.detachAll('dragstart');
node.detachAll(Drag.START_EVENT);
this.mouseXY = [];
this.deltaXY = [0,0];
this.startXY = [];
this.nodeXY = [];
this.lastXY = [];
this.actXY = [];
this.realXY = [];
},
/**
* @method start
* @description Starts the drag operation
* @return {Self}
* @chainable
*/
start: function() {
if (!this.get('lock') && !this.get(DRAGGING)) {
var node = this.get(NODE), ow, oh, xy;
this._startTime = (new Date()).getTime();
DDM._start();
node.addClass(DDM.CSS_PREFIX + '-dragging');
this.fire(EV_START, {
pageX: this.nodeXY[0],
pageY: this.nodeXY[1],
startTime: this._startTime
});
node = this.get(DRAG_NODE);
xy = this.nodeXY;
ow = node.get(OFFSET_WIDTH);
oh = node.get(OFFSET_HEIGHT);
if (this.get('startCentered')) {
this._setStartPosition([xy[0] + (ow / 2), xy[1] + (oh / 2)]);
}
this.region = {
'0': xy[0],
'1': xy[1],
area: 0,
top: xy[1],
right: xy[0] + ow,
bottom: xy[1] + oh,
left: xy[0]
};
this.set(DRAGGING, true);
}
return this;
},
/**
* @method end
* @description Ends the drag operation
* @return {Self}
* @chainable
*/
end: function() {
this._endTime = (new Date()).getTime();
if (this._clickTimeout) {
this._clickTimeout.cancel();
}
this._dragThreshMet = this._fromTimeout = false;
if (!this.get('lock') && this.get(DRAGGING)) {
this.fire(EV_END, {
pageX: this.lastXY[0],
pageY: this.lastXY[1],
startTime: this._startTime,
endTime: this._endTime
});
}
this.get(NODE).removeClass(DDM.CSS_PREFIX + '-dragging');
this.set(DRAGGING, false);
this.deltaXY = [0, 0];
return this;
},
/**
* @private
* @method _defEndFn
* @description Handler for fixing the selection in IE
*/
_defEndFn: function(e) {
this._fixIEMouseUp();
this._ev_md = null;
},
/**
* @private
* @method _prevEndFn
* @description Handler for preventing the drag:end event. It will reset the node back to it's start position
*/
_prevEndFn: function(e) {
this._fixIEMouseUp();
//Bug #1852577
this.get(DRAG_NODE).setXY(this.nodeXY);
this._ev_md = null;
this.region = null;
},
/**
* @private
* @method _align
* @description Calculates the offsets and set's the XY that the element will move to.
* @param {Array} xy The xy coords to align with.
*/
_align: function(xy) {
this.fire(EV_ALIGN, {pageX: xy[0], pageY: xy[1] });
},
/**
* @private
* @method _defAlignFn
* @description Calculates the offsets and set's the XY that the element will move to.
* @param {EventFacade} e The drag:align event.
*/
_defAlignFn: function(e) {
this.actXY = [e.pageX - this.deltaXY[0], e.pageY - this.deltaXY[1]];
},
/**
* @private
* @method _alignNode
* @description This method performs the alignment before the element move.
* @param {Array} eXY The XY to move the element to, usually comes from the mousemove DOM event.
*/
_alignNode: function(eXY) {
this._align(eXY);
this._moveNode();
},
/**
* @private
* @method _moveNode
* @description This method performs the actual element move.
*/
_moveNode: function(scroll) {
//if (!this.get(DRAGGING)) {
// return;
//}
var diffXY = [], diffXY2 = [], startXY = this.nodeXY, xy = this.actXY;
diffXY[0] = (xy[0] - this.lastXY[0]);
diffXY[1] = (xy[1] - this.lastXY[1]);
diffXY2[0] = (xy[0] - this.nodeXY[0]);
diffXY2[1] = (xy[1] - this.nodeXY[1]);
this.region = {
'0': xy[0],
'1': xy[1],
area: 0,
top: xy[1],
right: xy[0] + this.get(DRAG_NODE).get(OFFSET_WIDTH),
bottom: xy[1] + this.get(DRAG_NODE).get(OFFSET_HEIGHT),
left: xy[0]
};
this.fire(EV_DRAG, {
pageX: xy[0],
pageY: xy[1],
scroll: scroll,
info: {
start: startXY,
xy: xy,
delta: diffXY,
offset: diffXY2
}
});
this.lastXY = xy;
},
/**
* @private
* @method _defDragFn
* @description Default function for drag:drag. Fired from _moveNode.
* @param {EventFacade} ev The drag:drag event
*/
_defDragFn: function(e) {
if (this.get('move')) {
if (e.scroll) {
e.scroll.node.set('scrollTop', e.scroll.top);
e.scroll.node.set('scrollLeft', e.scroll.left);
}
this.get(DRAG_NODE).setXY([e.pageX, e.pageY]);
this.realXY = [e.pageX, e.pageY];
}
},
/**
* @private
* @method _move
* @description Fired from DragDropMgr (DDM) on mousemove.
* @param {EventFacade} ev The mousemove DOM event
*/
_move: function(ev) {
if (this.get('lock')) {
return false;
} else {
this.mouseXY = [ev.pageX, ev.pageY];
if (!this._dragThreshMet) {
var diffX = Math.abs(this.startXY[0] - ev.pageX),
diffY = Math.abs(this.startXY[1] - ev.pageY);
if (diffX > this.get('clickPixelThresh') || diffY > this.get('clickPixelThresh')) {
this._dragThreshMet = true;
this.start();
this._alignNode([ev.pageX, ev.pageY]);
}
} else {
if (this._clickTimeout) {
this._clickTimeout.cancel();
}
this._alignNode([ev.pageX, ev.pageY]);
}
}
},
/**
* @method stopDrag
* @description Method will forcefully stop a drag operation. For example calling this from inside an ESC keypress handler will stop this drag.
* @return {Self}
* @chainable
*/
stopDrag: function() {
if (this.get(DRAGGING)) {
DDM._end();
}
return this;
},
/**
* @private
* @method destructor
* @description Lifecycle destructor, unreg the drag from the DDM and remove listeners
*/
destructor: function() {
this._unprep();
if (this.target) {
this.target.destroy();
}
DDM._unregDrag(this);
}
});
Y.namespace('DD');
Y.DD.Drag = Drag;