dd.js revision c03d3f1eafc55ad0233f238f9ba1583c1e47fa96
4a14ce5ba00ab7bc55c99ffdcf59c7a4ab902721Automatic Updater * Provides the base Drag Drop Manger required for making a Node draggable.
ddccd5811feff696ba460dabfb666ce61040f545Andreas Gustafsson * @submodule dd-ddm-base
8a66318e41ed14c5a88130e8c362610e8faa2121Mark Andrews * Provides the base Drag Drop Manger required for making a Node draggable.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @class DDM
8a66318e41ed14c5a88130e8c362610e8faa2121Mark Andrews * @extends Base
8a66318e41ed14c5a88130e8c362610e8faa2121Mark Andrews * @constructor
8a66318e41ed14c5a88130e8c362610e8faa2121Mark Andrews * @namespace DD
ea94d370123a5892f6c47a97f21d1b28d44bb168Tinderbox User var DDMBase = function() {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein DDMBase.superclass.constructor.apply(this, arguments);
794b79e6bbc3f5db1ea6ae154d739b9f1ef1a375Tinderbox User * @attribute dragCursor
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description The cursor to apply when dragging, if shimmed the shim will get the cursor.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type String
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute clickPixelThresh
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description The number of pixels to move to start a drag operation, default is 3.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Number
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute clickTimeThresh
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description The number of milliseconds a mousedown has to pass to start a drag operation, default is 1000.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Number
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute throttleTime
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description The number of milliseconds to throttle the mousemove event. Default: 150
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * @type Number
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //value: 150
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute dragMode
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description This attribute only works if the dd-drop module is active. It will set the dragMode (point, intersect, strict) of all future Drag instances.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type String
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _createPG: function() {},
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @property _active
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description flag set when we activate our first drag, so DDM can start listening for events.
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * @type {Boolean}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _setDragMode
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * @description Handler for dragMode attribute setter.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param String/Number The Number value or the String for the DragMode to default all future drag instances to.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @return Number The Mode to be set
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (mode === null) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein case 'intersect':
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein case 'strict':
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein case 'point':
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * @property CSS_PREFIX
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description The PREFIX to attach to all DD CSS class names
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type {String}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein CSS_PREFIX: Y.ClassNameManager.getClassName('dd'),
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _activateTargets: function() {},
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @property _drags
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Holder for all registered drag elements.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type {Array}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @property activeDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description A reference to the currently active draggable object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type {Drag}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _regDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Adds a reference to the drag object to the DDM._drags array, called in the constructor of Drag.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Drag} d The Drag object
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _regDrag: function(d) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return false;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return true;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _unregDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Remove this drag object from the DDM._drags array.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Drag} d The drag object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _unregDrag: function(d) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (n !== d) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _setupListeners
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Add the document listeners.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein doc.on('mousemove', Y.throttle(Y.bind(this._move, this), this.get('throttleTime')));
8eea877894ea5bcf5cdd9ca124a8601ad421d753Andreas Gustafsson * @method _start
8eea877894ea5bcf5cdd9ca124a8601ad421d753Andreas Gustafsson * @description Internal method used by Drag to signal the start of a drag operation
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _startDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Factory method to be overwritten by other DDM's
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Number} x The x position of the drag element
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Number} y The y position of the drag element
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Number} w The width of the drag element
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Number} h The height of the drag element
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _startDrag: function() {},
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _endDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Factory method to be overwritten by other DDM's
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _endDrag: function() {},
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _dropMove: function() {},
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _end
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Internal method used by Drag to signal the end of a drag operation
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _end: function() {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method stopDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Method will forcefully stop a drag operation. For example calling this from inside an ESC keypress handler will stop this drag.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @return {Self}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @chainable
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein stopDrag: function() {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return this;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _move
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Internal listener for the mousemove DOM event to pass to the Drag's move method.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {Event.Facade} ev The Dom mousemove Event
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.activeDrag._move.call(this.activeDrag, ev);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * //TODO Private, rename??...
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method cssSizestoObject
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Helper method to use to set the gutter from the attribute setter.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param {String} gutter CSS style string for gutter: '5 0' (sets top and bottom to 5px, left and right to 0px), '1 2 3 4' (top 1px, right 2px, bottom 3px, left 4px)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @return {Object} The gutter Object Literal.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method getDrag
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Get a valid Drag instance back from a Node or a selector string, false otherwise
var drag = false,
if (n instanceof Y.Node) {
drag = v;
return drag;
return n1;
* @description Return a node instance from the given node, selector string or Y.Base extended object.
getNode: function(n) {
if (n && n.get) {
n = Y.one(n);
if (s == n1) {
return n1;
* Extends the dd-ddm-base Class to add support for the viewport shim to allow a draggable node to drag to be dragged over an iframe or any other node that traps mousemove events.
* It is also required to have Drop Targets enabled, as the viewport shim will contain the shims for the Drop Targets.
_pg: null,
_debugShim: false,
_activateTargets: function() { },
_deactivateTargets: function() {},
_startDrag: function() {
this._pg_activate();
this._activateTargets();
_endDrag: function() {
this._pg_deactivate();
this._deactivateTargets();
_pg_deactivate: function() {
_pg_activate: function() {
if (ah) {
this._pg_size();
_pg_size: function() {
if (this.activeDrag) {
_createPG: function() {
* Extends the dd-ddm Class to add support for the placement of Drop Target shims inside the viewport shim. It also handles all Drop Target related events and interactions.
* @description This flag turns off the use of the mouseover/mouseout shim. It should not be used unless you know what you are doing.
_noShim: false,
_activeShims: [],
_hasActiveShim: function() {
if (this._noShim) {
_addActiveShim: function(d) {
_removeActiveShim: function(d) {
s[s.length] = v;
this._activeShims = s;
* @description This method will sync the position of the shims on the Drop Targets that are currently active.
}, force);
* @description The mode that the drag operations will run in 0 for Point, 1 for Intersect, 2 for Strict
* @description In intersect mode, a Drop is targeted by "part" of the drag node being over the Target
* @description Should we only check targets that are in the viewport on drags (for performance), default: true
useHash: true,
activeDrop: null,
validDrops: [],
* @description An object literal of Other Drop Targets that we encountered during this interaction (in the case of overlapping Drop Targets)
otherDrops: {},
targets: [],
* @description Add a Drop Target to the list of Valid Targets. This list get's regenerated on each new drag operation.
* @description Removes a Drop Target from the list of Valid Targets. This list get's regenerated on each new drag operation.
var drops = [];
if (v !== drop) {
if (this._noShim) {
clearCache: function() {
this.validDrops = [];
this.otherDrops = {};
this._activeShims = [];
_activateTargets: function() {
this._noShim = true;
this.clearCache();
v._activateShim([]);
this._noShim = false;
this._handleTargetOver();
* @description This method will gather the area for all potential targets and see which has the hightest covered area and return it.
* @param {Boolean} all If present, it returns an Array. First item is best match, second is an Array of the other items in the original Array.
biggest = v;
if (all) {
out = [];
if (v !== biggest) {
return biggest;
* @description This method fires the drop:hit, drag:drophit, drag:dropmiss methods and deactivates the shims..
_deactivateTargets: function() {
if (activeDrop) {
this.activeDrop = null;
v._deactivateShim([]);
_dropMove: function() {
if (this._hasActiveShim()) {
this._handleTargetOver();
_lookup: function() {
return this.validDrops;
var drops = [];
return drops;
_handleTargetOver: function() {
_regTarget: function(t) {
if (v != drop) {
vdrops = [];
if (v !== drop) {
var drop = false,
if (n instanceof Y.Node) {
drop = v;
return drop;
* @description Handles the mousedown DOM event, checks to see if you have a valid handle then starts the drag timers.
Drag = function(o) {
this._lazyAddAttrs = false;
if (!valid) {
* This property defaults to "mousedown", but when drag-gestures is loaded, it is changed to "gesturemovestart"
node: {
return node;
dragNode: {
return node;
offsetNode: {
value: true
value: false
* @description The number of milliseconds a mousedown has to pass to start a drag operation, default is 1000.
lock: {
value: false,
if (lock) {
return lock;
* @description A payload holder to store arbitrary data about this drag object, can be used to store any value.
data: {
value: false
* @description If this is false, the drag element will not move with the cursor: default true. Can be used to "resize" the element.
move: {
value: true
* @description Use the protective shim on all drag operations: default true. Only works with dd-ddm, not dd-ddm-base.
useShim: {
value: true
* @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.
activeHandle: {
value: false
* @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.
value: true
* @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.
dragging: {
value: false
parent: {
value: false
* @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.
target: {
value: false,
return config;
* @description This attribute only works if the dd-drop module is active. It will set the dragMode (point, intersect, strict) of this Drag instance.
dragMode: {
value: null,
groups: {
getter: function() {
if (!this._groups) {
this._groups = {};
var ret = [];
return ret;
setter: function(g) {
this._groups = {};
Y.each(g, function(v, k) {
this._groups[v] = true;
* @description Array of valid handles to add. Adding something here will set all handles, even if previously added with addHandle
handles: {
value: null,
setter: function(g) {
this._handles = {};
Y.each(g, function(v, k) {
var key = v;
this._handles = null;
* @description Controls the default bubble parent for this Drag instance. Default: Y.DD.DDM. Set to false to disable bubbling. Use bubbleTargets in config
bubbles: {
setter: function(t) {
this.addTarget(t);
haltDown: {
value: true
_canDrag: function(n) {
* @description Add this Drag instance to a group, this should be used for on-the-fly group additions.
addToGroup: function(g) {
this._groups[g] = true;
* @description Remove this Drag instance from a group, this should be used for on-the-fly group removals.
removeFromGroup: function(g) {
delete this._groups[g];
* @description This will be a reference to the Drop instance associated with this drag if the target: true config attribute is set..
target: null,
if (config === false) {
if (this.target) {
this.target = null;
config = {};
config.bubbleTargets = ('bubbleTargets' in config) ? config.bubbleTargets : Y.Object.values(this._yuievt.targets);
_groups: null,
* @description This method creates all the events for this Event Target and publishes them so we get Event Bubbling.
_createEvents: function() {
queuable: false,
emitFacade: true,
bubbles: true,
queuable: false,
emitFacade: true,
bubbles: true,
queuable: false,
emitFacade: true,
bubbles: true,
queuable: false,
emitFacade: true,
bubbles: true,
var ev = [
this.publish(v, {
type: v,
emitFacade: true,
bubbles: true,
preventable: false,
queuable: false,
_ev_md: null,
* @description The getTime of the mousedown event. Not used, just here in case someone wants/needs to use it.
_startTime: null,
* @description The getTime of the mouseup event. Not used, just here in case someone wants/needs to use it.
_endTime: null,
_handles: null,
_invalids: null,
* @description A private hash of the default invalid selector strings: {'textarea': true, 'input': true, 'a': true, 'button': true, 'select': true}
_dragThreshMet: null,
_fromTimeout: null,
_clickTimeout: null,
deltaXY: null,
startXY: null,
nodeXY: null,
lastXY: null,
* @description The xy that the node will be set to. Changing this will alter the position as it's dragged.
actXY: null,
realXY: null,
mouseXY: null,
region: null,
this._fixIEMouseUp();
* @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.
_fixDragStart: function(e) {
e.preventDefault();
* @description The function we use as the onselectstart handler when we start a drag in Internet Explorer
_ieSelectFix: function() {
* @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,
* @description This method copies the onselectstart listner on the document to the _ieSelectFix property
_fixIEMouseDown: function(e) {
* @description This method copies the _ieSelectFix property back to the onselectstart listner on the document.
_fixIEMouseUp: function() {
_defMouseDownFn: function(e) {
this._dragThreshMet = false;
* @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.
hTest = null,
els = null,
nlist = null,
set = false;
if (this._handles) {
nlist = i;
hTest = n;
if (this._invalids) {
if (hTest) {
set = false;
set = true;
_timeoutCheck: function() {
this.start();
* @description Add a handle to a drag element. Drag only initiates when a mousedown happens on this element.
if (!this._handles) {
this._handles = {};
* @description Add a selector string to test the handle against. If the test passes the drag operation will not continue.
this.actXY = [];
this._createEvents();
_prep: function() {
this._dragThreshMet = false;
_unprep: function() {
start: function() {
this.region = {
end: function() {
if (this._clickTimeout) {
_defEndFn: function(e) {
this._fixIEMouseUp();
this._ev_md = null;
* @description Handler for preventing the drag:end event. It will reset the node back to it's start position
_prevEndFn: function(e) {
this._fixIEMouseUp();
this._ev_md = null;
this.region = null;
_defAlignFn: function(e) {
this._moveNode();
this.region = {
info: {
_defDragFn: function(e) {
if (e.scroll) {
if (!this._dragThreshMet) {
this._dragThreshMet = true;
this.start();
if (this._clickTimeout) {
* @description Method will forcefully stop a drag operation. For example calling this from inside an ESC keypress handler will stop this drag.
stopDrag: function() {
destructor: function() {
this._unprep();
this.detachAll();
if (this.target) {
P = function(config) {
P.ATTRS = {
host: {
moveOnEnd: {
hideOnEnd: {
resizeFrame: {
borderStyle: {
cloneNode: {
value: false
proto = {
_hands: null,
_init: function() {
if (!this._hands) {
this._hands = [];
v.detach();
initializer: function() {
this._init();
destructor: function() {
v.detach();
clone: function() {
c = n.cloneNode(true);
delete c._yuid;
_createFrame: function() {
p.setStyles({
b.prepend(p);
* @description If resizeProxy is set to true (default) it will resize the proxy element to match the size of the Drag Element.
* If positionProxy is set to true (default) it will position the proxy element in the same location as the Drag Element.
if (ah) {
d.setStyles({
d.setStyles({
* The Drag & Drop Utility allows you to create a draggable interface efficiently, buffering you from browser-level abnormalities and enabling you to focus on the interesting logic surrounding your particular implementation. This component enables you to create a variety of standard draggable objects with just a few lines of code and then, using its extensive API, add your own specific implementation logic.
* Plugin for the dd-drag module to add the constraining methods to it. It supports constraining to a node or viewport. It supports tick based moves and XY axis constraints.
proto = null,
C = function(config) {
this._lazyAddAttrs = false;
* @description The Constrained instance will be placed on the Drag instance under the con namespace.
C.ATTRS = {
host: {
stickX: {
value: false
stickY: {
value: false
* @description The X tick offset the drag node should snap to on each drag move. False for no ticks. Default: false
tickX: {
value: false
* @description The Y tick offset the drag node should snap to on each drag move. False for no ticks. Default: false
tickY: {
value: false
tickXArray: {
value: false
tickYArray: {
value: false
* @description CSS style string for the gutter of a region (supports negative values): '5 0' (sets top and bottom to 5px, left and right to 0px), '1 2 3 4' (top 1px, right 2px, bottom 3px, left 4px)
gutter: {
* '{Region Object}': An Object Literal containing a valid region (top, right, bottom, left) of page positions
constrain: {
if (node) {
return con;
* @description An Object Literal containing a valid region (top, right, bottom, left) of page positions to constrain the drag node to.
setter: function(r) {
setter: function(n) {
setter: function(n) {
cacheRegion: {
value: true
proto = {
_lastTickXFired: null,
_lastTickYFired: null,
initializer: function() {
this._createEvents();
* @description This method creates all the events for this Event Target and publishes them so we get Event Bubbling.
_createEvents: function() {
var instance = this;
var ev = [
this.publish(v, {
type: v,
emitFacade: true,
bubbles: true,
queuable: false,
_handleEnd: function() {
this._lastTickYFired = null;
this._lastTickXFired = null;
_handleStart: function() {
this.resetCache();
_regionCache: null,
_cacheRegion: function() {
resetCache: function() {
this._regionCache = null;
_getConstraint: function() {
if (con) {
if (!this._regionCache) {
this._cacheRegion();
this.resetCache();
Y.each(g, function(i, n) {
region[n] -= i;
region[n] += i;
return region;
r = this._getConstraint();
if (inc) {
* @param {Array} _xy The XY to check if it's in the current region, if it isn't inside the region, it will reset the xy array to be inside the region.
r = this.getRegion(),
return _xy;
inside = false;
inside = true;
return inside;
* @description Modifies the Drag.actXY method from the after drag:align event. This is where the constraining happens.
align: function() {
r = this.getRegion(true);
this._tickAlignX();
this._tickAlignY();
return xy;
_tickAlignX: function() {
_tickAlignY: function() {
return pos;
return pos;
if (ticks[i]) {
return ret;
S.ATTRS = {
* @description Internal config option to hold the node that we are scrolling. Should not be set by the developer.
parentScroll: {
value: false,
if (node) {
return node;
buffer: {
scrollDelay: {
host: {
value: null
windowScroll: {
value: false,
vertical: {
value: true,
horizontal: {
value: true,
_scrolling: null,
_vpRegionCache: null,
_dimCache: null,
_scrollTimer: null,
* @description Sets the _vpRegionCache property with an Object containing the dims from the viewport.
_getVPRegion: function() {
top: t + b,
left: l + b
this._vpRegionCache = r;
initializer: function() {
this._vpRegionCache = null;
* @description Check to see if we need to fire the scroll timer. If scroll timer is running this will scroll the window.
var r = this._getVPRegion(),
scroll = false,
w = this._dimCache.w,
h = this._dimCache.h,
scroll = true;
scroll = true;
scroll = true;
scroll = true;
if (move) {
this._cancelScroll();
if (scroll) {
this._initScroll();
this._cancelScroll();
_initScroll: function() {
this._cancelScroll();
this._scrollTimer = Y.Lang.later(this.get('scrollDelay'), this, this._checkWinScroll, [true], true);
_cancelScroll: function() {
this._scrolling = false;
if (this._scrollTimer) {
delete this._scrollTimer;
align: function(e) {
if (this._scrolling) {
this._cancelScroll();
e.preventDefault();
if (!this._scrolling) {
this._checkWinScroll();
_setDimCache: function() {
this._dimCache = {
start: function() {
this._setDimCache();
this._dimCache = null;
this._cancelScroll();
toString: function() {
WS = function() {
windowScroll: {
value: true,
if (scroll) {
return scroll;
initializer: function() {
* @description The Scroll instance will be placed on the Drag instance under the winscroll namespace.
NS = function() {
node: {
value: false,
if (node !== false) {
initializer: function() {
* @description The NodeScroll instance will be placed on the Drag instance under the nodescroll namespace.
Drop = function() {
this._lazyAddAttrs = false;
node: {
groups: {
setter: function(g) {
this._groups = {};
Y.each(g, function(v, k) {
this._groups[v] = true;
padding: {
setter: function(p) {
lock: {
value: false,
if (lock) {
return lock;
* @description Controls the default bubble parent for this Drop instance. Default: Y.DD.DDM. Set to false to disable bubbling. Use bubbleTargets in config.
bubbles: {
setter: function(t) {
this.addTarget(t);
useShim: {
value: true,
setter: function(v) {
* @description Add this Drop instance to a group, this should be used for on-the-fly group additions.
addToGroup: function(g) {
this._groups[g] = true;
* @description Remove this Drop instance from a group, this should be used for on-the-fly group removals.
removeFromGroup: function(g) {
delete this._groups[g];
* @description This method creates all the events for this Event Target and publishes them so we get Event Bubbling.
_createEvents: function() {
var ev = [
this.publish(v, {
type: v,
emitFacade: true,
preventable: false,
bubbles: true,
queuable: false,
_valid: null,
_groups: null,
shim: null,
* @description A region object associated with this target, used for checking regions while dragging.
region: null,
overTarget: null,
this._valid = false;
var ret = false;
if (this._groups[v]) {
ret = true;
this._valid = true;
return ret;
destructor: function() {
this.shim = null;
this.detachAll();
* @description Removes classes from the target, resets some flags and sets the shims deactive position [-999, -999]
_deactivateShim: function() {
if (!this.shim) {
this.overTarget = false;
_activateShim: function() {
this.overTarget = false;
this.sizeShim();
* @description Positions and sizes the shim with the raw data from the node, this can be used to programatically adjust the Targets shim for Animation..
sizeShim: function() {
if (!this.shim) {
this.region = {
_createShim: function() {
if (this.shim) {
s.setStyles({
this.shim = s;
_handleTargetOver: function() {
if (this.overTarget) {
this.overTarget = true;
this._handleOut();
_handleOverEvent: function() {
_handleOutEvent: function() {
if (this.overTarget) {
this.overTarget = false;
if (!force) {
* Provides the ability to drag multiple nodes under a container element using only one Y.DD.Drag instance as a delegate.
* Provides the ability to drag multiple nodes under a container element using only one Y.DD.Drag instance as a delegate.
var Delegate = function(o) {
dd: null,
_shimState: null,
_handles: null,
_onNodeChange: function(e) {
_afterDragEnd: function(e) {
_delMouseDown: function(e) {
_onMouseEnter: function(e) {
_onMouseLeave: function(e) {
this._handles = [];
this._unprep();
this._handles.push(Y.delegate(Y.DD.Drag.START_EVENT, Y.bind(this._delMouseDown, this), cont, this.get(NODES)));
syncTargets: function() {
var config = {
useShim: false,
bubbleTargets: this
return node;
destructor: function() {
if (this.dd) {
v.detach();
ATTRS: {
* @description A selector query to get the container to listen for mousedown events on. All "nodes" should be a child of this container.
container: {
* @description A selector query to get the children of the "container" to make draggable elements from.
nodes: {
invalid: {
lastNode: {
currentNode: {
dragNode: {
over: {
value: false
target: {
value: false
dragConfig: {
value: null
handles: {
value: null
_delegates: [],
var del = null;
del = v;
return del;