diff -r 000000000000 -r 40c8f766c9b8 src/cm/media/js/lib/yui/yui_3.0.0b1/build/dd/dd-drop.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.0.0b1/build/dd/dd-drop.js Mon Nov 23 15:14:29 2009 +0100 @@ -0,0 +1,485 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 3.0.0b1 +build: 1163 +*/ +YUI.add('dd-drop', function(Y) { + + + /** + * 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. + * @module dd + * @submodule dd-drop + */ + /** + * This class provides the ability to create a Drop Target. + * @class Drop + * @extends Base + * @constructor + * @namespace DD + */ + + var NODE = 'node', + DDM = Y.DD.DDM, + OFFSET_HEIGHT = 'offsetHeight', + OFFSET_WIDTH = 'offsetWidth', + /** + * @event drop:over + * @description Fires when a drag element is over this target. + * @bubbles DDM + * @type {Event.Custom} + */ + EV_DROP_OVER = 'drop:over', + /** + * @event drop:enter + * @description Fires when a drag element enters this target. + * @bubbles DDM + * @type {Event.Custom} + */ + EV_DROP_ENTER = 'drop:enter', + /** + * @event drop:exit + * @description Fires when a drag element exits this target. + * @bubbles DDM + * @type {Event.Custom} + */ + EV_DROP_EXIT = 'drop:exit', + + /** + * @event drop:hit + * @description Fires when a draggable node is dropped on this Drop Target. (Fired from dd-ddm-drop) + * @bubbles DDM + * @type {Event.Custom} + */ + + + Drop = function() { + this._lazyAddAttrs = false; + Drop.superclass.constructor.apply(this, arguments); + + + //DD init speed up. + Y.on('domready', Y.bind(function() { + Y.later(100, this, this._createShim); + }, this)); + DDM._regTarget(this); + + /* TODO + if (Dom.getStyle(this.el, 'position') == 'fixed') { + Event.on(window, 'scroll', function() { + this.activateShim(); + }, this, true); + } + */ + }; + + Drop.NAME = 'drop'; + + Drop.ATTRS = { + /** + * @attribute node + * @description Y.Node instanace to use as the element to make a Drop Target + * @type Node + */ + node: { + setter: function(node) { + var n = Y.Node.get(node); + if (!n) { + Y.error('DD.Drop: Invalid Node Given: ' + node); + } + return n; + } + }, + /** + * @attribute groups + * @description Array of groups to add this drop into. + * @type Array + */ + groups: { + value: ['default'], + setter: function(g) { + this._groups = {}; + Y.each(g, function(v, k) { + this._groups[v] = true; + }, this); + return g; + } + }, + /** + * @attribute padding + * @description CSS style padding to make the Drop Target bigger than the node. + * @type String + */ + padding: { + value: '0', + setter: function(p) { + return DDM.cssSizestoObject(p); + } + }, + /** + * @attribute lock + * @description Set to lock this drop element. + * @type Boolean + */ + lock: { + value: false, + setter: function(lock) { + if (lock) { + this.get(NODE).addClass(DDM.CSS_PREFIX + '-drop-locked'); + } else { + this.get(NODE).removeClass(DDM.CSS_PREFIX + '-drop-locked'); + } + return lock; + } + }, + /** + * @attribute bubbles + * @description Controls the default bubble parent for this Drop instance. Default: Y.DD.DDM. Set to false to disable bubbling. + * @type Object + */ + bubbles: { + writeOnce: true, + value: Y.DD.DDM + } + }; + + Y.extend(Drop, Y.Base, { + /** + * @private + * @method _createEvents + * @description This method creates all the events for this Event Target and publishes them so we get Event Bubbling. + */ + _createEvents: function() { + + var ev = [ + EV_DROP_OVER, + EV_DROP_ENTER, + EV_DROP_EXIT, + 'drop:hit' + ]; + + Y.each(ev, function(v, k) { + this.publish(v, { + type: v, + emitFacade: true, + preventable: false, + bubbles: true, + queuable: false, + prefix: 'drop' + }); + }, this); + + if (this.get('bubbles')) { + this.addTarget(this.get('bubbles')); + } + + }, + /** + * @private + * @property _valid + * @description Flag for determining if the target is valid in this operation. + * @type Boolean + */ + _valid: null, + /** + * @private + * @property _groups + * @description The groups this target belongs to. + * @type Array + */ + _groups: null, + /** + * @property shim + * @description Node reference to the targets shim + * @type {Object} + */ + shim: null, + /** + * @property region + * @description A region object associated with this target, used for checking regions while dragging. + * @type Object + */ + region: null, + /** + * @property overTarget + * @description This flag is tripped when a drag element is over this target. + * @type Boolean + */ + overTarget: null, + /** + * @method inGroup + * @description Check if this target is in one of the supplied groups. + * @param {Array} groups The groups to check against + * @return Boolean + */ + inGroup: function(groups) { + this._valid = false; + var ret = false; + Y.each(groups, function(v, k) { + if (this._groups[v]) { + ret = true; + this._valid = true; + } + }, this); + return ret; + }, + /** + * @private + * @method initializer + * @description Private lifecycle method + */ + initializer: function() { + //this._createEvents(); + Y.later(100, this, this._createEvents); + + var node = this.get(NODE), id; + if (!node.get('id')) { + id = Y.stamp(node); + node.set('id', id); + } + node.addClass(DDM.CSS_PREFIX + '-drop'); + //Shouldn't have to do this.. + this.set('groups', this.get('groups')); + }, + /** + * @private + * @method destructor + * @description Lifecycle destructor, unreg the drag from the DDM and remove listeners + */ + destructor: function() { + DDM._unregTarget(this); + if (this.shim) { + this.shim.detachAll(); + this.shim.get('parentNode').removeChild(this.shim); + this.shim = null; + } + this.get(NODE).removeClass(DDM.CSS_PREFIX + '-drop'); + this.detachAll(); + }, + /** + * @private + * @method _deactivateShim + * @description Removes classes from the target, resets some flags and sets the shims deactive position [-999, -999] + */ + _deactivateShim: function() { + if (!this.shim) { + return false; + } + this.get(NODE).removeClass(DDM.CSS_PREFIX + '-drop-active-valid'); + this.get(NODE).removeClass(DDM.CSS_PREFIX + '-drop-active-invalid'); + this.get(NODE).removeClass(DDM.CSS_PREFIX + '-drop-over'); + this.shim.setStyles({ + top: '-999px', + left: '-999px', + zIndex: '2' + }); + this.overTarget = false; + }, + /** + * @private + * @method _activateShim + * @description Activates the shim and adds some interaction CSS classes + */ + _activateShim: function() { + if (!DDM.activeDrag) { + return false; //Nothing is dragging, no reason to activate. + } + if (this.get(NODE) === DDM.activeDrag.get(NODE)) { + return false; + } + if (this.get('lock')) { + return false; + } + var node = this.get(NODE); + //TODO Visibility Check.. + //if (this.inGroup(DDM.activeDrag.get('groups')) && this.get(NODE).isVisible()) { + if (this.inGroup(DDM.activeDrag.get('groups'))) { + node.removeClass(DDM.CSS_PREFIX + '-drop-active-invalid'); + node.addClass(DDM.CSS_PREFIX + '-drop-active-valid'); + DDM._addValid(this); + this.overTarget = false; + this.sizeShim(); + } else { + DDM._removeValid(this); + node.removeClass(DDM.CSS_PREFIX + '-drop-active-valid'); + node.addClass(DDM.CSS_PREFIX + '-drop-active-invalid'); + } + }, + /** + * @method 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 (!DDM.activeDrag) { + return false; //Nothing is dragging, no reason to activate. + } + if (this.get(NODE) === DDM.activeDrag.get(NODE)) { + return false; + } + if (this.get('lock')) { + return false; + } + if (!this.shim) { + Y.later(100, this, this.sizeShim); + return false; + } + var node = this.get(NODE), + nh = node.get(OFFSET_HEIGHT), + nw = node.get(OFFSET_WIDTH), + xy = node.getXY(), + p = this.get('padding'), + dd, dH, dW; + + + //Apply padding + nw = nw + p.left + p.right; + nh = nh + p.top + p.bottom; + xy[0] = xy[0] - p.left; + xy[1] = xy[1] - p.top; + + + if (DDM.activeDrag.get('dragMode') === DDM.INTERSECT) { + //Intersect Mode, make the shim bigger + dd = DDM.activeDrag; + dH = dd.get(NODE).get(OFFSET_HEIGHT); + dW = dd.get(NODE).get(OFFSET_WIDTH); + + nh = (nh + dH); + nw = (nw + dW); + xy[0] = xy[0] - (dW - dd.deltaXY[0]); + xy[1] = xy[1] - (dH - dd.deltaXY[1]); + + } + + //Set the style on the shim + this.shim.setStyles({ + height: nh + 'px', + width: nw + 'px', + top: xy[1] + 'px', + left: xy[0] + 'px' + }); + + //Create the region to be used by intersect when a drag node is over us. + this.region = { + '0': xy[0], + '1': xy[1], + area: 0, + top: xy[1], + right: xy[0] + nw, + bottom: xy[1] + nh, + left: xy[0] + }; + }, + /** + * @private + * @method _createShim + * @description Creates the Target shim and adds it to the DDM's playground.. + */ + _createShim: function() { + //No playground, defer + if (!DDM._pg) { + Y.later(10, this, this._createShim); + return; + } + //Shim already here, cancel + if (this.shim) { + return; + } + var s = Y.Node.create('
'); + + s.setStyles({ + height: this.get(NODE).get(OFFSET_HEIGHT) + 'px', + width: this.get(NODE).get(OFFSET_WIDTH) + 'px', + backgroundColor: 'yellow', + opacity: '.5', + zIndex: '1', + overflow: 'hidden', + top: '-900px', + left: '-900px', + position: 'absolute' + }); + DDM._pg.appendChild(s); + this.shim = s; + + s.on('mouseover', Y.bind(this._handleOverEvent, this)); + s.on('mouseout', Y.bind(this._handleOutEvent, this)); + }, + /** + * @private + * @method _handleOverTarget + * @description This handles the over target call made from this object or from the DDM + */ + _handleTargetOver: function() { + if (DDM.isOverTarget(this)) { + this.get(NODE).addClass(DDM.CSS_PREFIX + '-drop-over'); + DDM.activeDrop = this; + DDM.otherDrops[this] = this; + if (this.overTarget) { + DDM.activeDrag.fire('drag:over', { drop: this, drag: DDM.activeDrag }); + this.fire(EV_DROP_OVER, { drop: this, drag: DDM.activeDrag }); + } else { + this.overTarget = true; + this.fire(EV_DROP_ENTER, { drop: this, drag: DDM.activeDrag }); + DDM.activeDrag.fire('drag:enter', { drop: this, drag: DDM.activeDrag }); + DDM.activeDrag.get(NODE).addClass(DDM.CSS_PREFIX + '-drag-over'); + //TODO - Is this needed?? + //DDM._handleTargetOver(); + } + } else { + this._handleOut(); + } + }, + /** + * @private + * @method _handleOverEvent + * @description Handles the mouseover DOM event on the Target Shim + */ + _handleOverEvent: function() { + this.shim.setStyle('zIndex', '999'); + DDM._addActiveShim(this); + }, + /** + * @private + * @method _handleOutEvent + * @description Handles the mouseout DOM event on the Target Shim + */ + _handleOutEvent: function() { + this.shim.setStyle('zIndex', '1'); + DDM._removeActiveShim(this); + }, + /** + * @private + * @method _handleOut + * @description Handles out of target calls/checks + */ + _handleOut: function(force) { + if (!DDM.isOverTarget(this) || force) { + if (this.overTarget) { + this.overTarget = false; + if (!force) { + DDM._removeActiveShim(this); + } + if (DDM.activeDrag) { + this.get(NODE).removeClass(DDM.CSS_PREFIX + '-drop-over'); + DDM.activeDrag.get(NODE).removeClass(DDM.CSS_PREFIX + '-drag-over'); + this.fire(EV_DROP_EXIT); + DDM.activeDrag.fire('drag:exit', { drop: this }); + delete DDM.otherDrops[this]; + //if (DDM.activeDrop === this) { + // DDM.activeDrop = null; + //} + } + } + } + } + }); + + Y.DD.Drop = Drop; + + + + + +}, '3.0.0b1' ,{requires:['dd-ddm-drop', 'dd-drag'], skinnable:false});