]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/dd/dd-delegate.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / dd / dd-delegate.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('dd-delegate', function(Y) {
9
10
11     /**
12      * Provides the ability to drag multiple nodes under a container element using only one Y.DD.Drag instance as a delegate.
13      * @module dd
14      * @submodule dd-delegate
15      */     
16     /**
17      * Provides the ability to drag multiple nodes under a container element using only one Y.DD.Drag instance as a delegate.
18      * @class Delegate
19      * @extends Base
20      * @constructor
21      * @namespace DD
22      */
23
24
25     var Delegate = function(o) {
26         Delegate.superclass.constructor.apply(this, arguments);
27     },
28     CONT = 'container',
29     NODES = 'nodes',
30     _tmpNode = Y.Node.create('<div>Temp Node</div>');
31
32
33     Y.extend(Delegate, Y.Base, {
34         /**
35         * @private
36         * @property _bubbleTargets
37         * @description The default bubbleTarget for this object. Default: Y.DD.DDM
38         */
39         _bubbleTargets: Y.DD.DDM,
40         /**
41         * @property dd
42         * @description A reference to the temporary dd instance used under the hood.
43         */    
44         dd: null,
45         /**
46         * @property _shimState
47         * @private
48         * @description The state of the Y.DD.DDM._noShim property to it can be reset.
49         */    
50         _shimState: null,
51         /**
52         * @private
53         * @property _handles
54         * @description Array of event handles to be destroyed
55         */
56         _handles: null,
57         /**
58         * @private
59         * @method _onNodeChange
60         * @description Listens to the nodeChange event and sets the dragNode on the temp dd instance.
61         * @param {Event} e The Event.
62         */
63         _onNodeChange: function(e) {
64             this.set('dragNode', e.newVal);
65         },
66         /**
67         * @private
68         * @method _afterDragEnd
69         * @description Listens for the drag:end event and updates the temp dd instance.
70         * @param {Event} e The Event.
71         */
72         _afterDragEnd: function(e) {
73             Y.DD.DDM._noShim = this._shimState;
74
75             this.set('lastNode', this.dd.get('node'));
76             this.get('lastNode').removeClass(Y.DD.DDM.CSS_PREFIX + '-dragging');
77             this.dd._unprep();
78             this.dd.set('node', _tmpNode);
79         },
80         /**
81         * @private
82         * @method _delMouseDown
83         * @description The callback for the Y.DD.Delegate instance used
84         * @param {Event} e The MouseDown Event.
85         */
86         _delMouseDown: function(e) {
87             var tar = e.currentTarget,
88                 dd = this.dd;
89             
90             if (tar.test(this.get(NODES)) && !tar.test(this.get('invalid'))) {
91                 this._shimState = Y.DD.DDM._noShim;
92                 Y.DD.DDM._noShim = true;
93                 this.set('currentNode', tar);
94                 dd.set('node', tar);
95                 if (dd.proxy) {
96                     dd.set('dragNode', Y.DD.DDM._proxy);
97                 } else {
98                     dd.set('dragNode', tar);
99                 }
100                 dd._prep();
101                 
102                 dd.fire('drag:mouseDown', { ev: e });
103             }
104         },
105         /**
106         * @private
107         * @method _onMouseEnter
108         * @description Sets the target shim state
109         * @param {Event} e The MouseEnter Event
110         */
111         _onMouseEnter: function(e) {
112             this._shimState = Y.DD.DDM._noShim;
113             Y.DD.DDM._noShim = true;
114         },
115         /**
116         * @private
117         * @method _onMouseLeave
118         * @description Resets the target shim state
119         * @param {Event} e The MouseLeave Event
120         */
121         _onMouseLeave: function(e) {
122             Y.DD.DDM._noShim = this._shimState;
123         },
124         initializer: function(cfg) {
125             this._handles = [];
126             //Create a tmp DD instance under the hood.
127             var conf = Y.clone(this.get('dragConfig') || {}),
128                 cont = this.get(CONT);
129
130             conf.node = _tmpNode.cloneNode(true);
131             conf.bubbleTargets = this;
132
133             if (this.get('handles')) {
134                 conf.handles = this.get('handles');
135             }
136
137             this.dd = new Y.DD.Drag(conf);
138
139             //On end drag, detach the listeners
140             this.dd.after('drag:end', Y.bind(this._afterDragEnd, this));
141             this.dd.on('dragNodeChange', Y.bind(this._onNodeChange, this));
142             this.dd.after('drag:mouseup', function() {
143                 this._unprep();
144             });
145
146             //Attach the delegate to the container
147             this._handles.push(Y.delegate(Y.DD.Drag.START_EVENT, Y.bind(this._delMouseDown, this), cont, this.get(NODES)));
148
149             this._handles.push(Y.on('mouseenter', Y.bind(this._onMouseEnter, this), cont));
150
151             this._handles.push(Y.on('mouseleave', Y.bind(this._onMouseLeave, this), cont));
152
153             Y.later(50, this, this.syncTargets);
154             Y.DD.DDM.regDelegate(this);
155         },
156         /**
157         * @method syncTargets
158         * @description Applies the Y.Plugin.Drop to all nodes matching the cont + nodes selector query.
159         * @return {Self}
160         * @chainable
161         */        
162         syncTargets: function() {
163             if (!Y.Plugin.Drop || this.get('destroyed')) {
164                 return;
165             }
166             var items, groups, config;
167
168             if (this.get('target')) {
169                 items = Y.one(this.get(CONT)).all(this.get(NODES));
170                 groups = this.dd.get('groups');
171                 config = this.get('dragConfig');
172                 
173                 if (config && 'groups' in config) {
174                     groups = config.groups;
175                 }
176
177                 items.each(function(i) {
178                     this.createDrop(i, groups);
179                 }, this);
180             }
181             return this;
182         },
183         /**
184         * @method createDrop
185         * @description Apply the Drop plugin to this node
186         * @param {Node} node The Node to apply the plugin to
187         * @param {Array} groups The default groups to assign this target to.
188         * @return Node
189         */
190         createDrop: function(node, groups) {
191             var config = {
192                 useShim: false,
193                 bubbleTargets: this
194             };
195
196             if (!node.drop) {
197                 node.plug(Y.Plugin.Drop, config);
198             }
199             node.drop.set('groups', groups);
200             return node;
201         },
202         destructor: function() {
203             if (this.dd) {
204                 this.dd.destroy();
205             }
206             if (Y.Plugin.Drop) {
207                 var targets = Y.one(this.get(CONT)).all(this.get(NODES));
208                 targets.unplug(Y.Plugin.Drop);
209             }
210             Y.each(this._handles, function(v) {
211                 v.detach();
212             });
213         }
214     }, {
215         NAME: 'delegate',
216         ATTRS: {
217             /**
218             * @attribute container
219             * @description A selector query to get the container to listen for mousedown events on. All "nodes" should be a child of this container.
220             * @type String
221             */    
222             container: {
223                 value: 'body'
224             },
225             /**
226             * @attribute nodes
227             * @description A selector query to get the children of the "container" to make draggable elements from.
228             * @type String
229             */        
230             nodes: {
231                 value: '.dd-draggable'
232             },
233             /**
234             * @attribute invalid
235             * @description A selector query to test a node to see if it's an invalid item.
236             * @type String
237             */        
238             invalid: {
239                 value: 'input, select, button, a, textarea'
240             },
241             /**
242             * @attribute lastNode
243             * @description Y.Node instance of the last item dragged.
244             * @type Node
245             */        
246             lastNode: {
247                 value: _tmpNode
248             },
249             /**
250             * @attribute currentNode
251             * @description Y.Node instance of the dd node.
252             * @type Node
253             */        
254             currentNode: {
255                 value: _tmpNode
256             },
257             /**
258             * @attribute dragNode
259             * @description Y.Node instance of the dd dragNode.
260             * @type Node
261             */        
262             dragNode: {
263                 value: _tmpNode
264             },
265             /**
266             * @attribute over
267             * @description Is the mouse currently over the container
268             * @type Boolean
269             */        
270             over: {
271                 value: false
272             },
273             /**
274             * @attribute target
275             * @description Should the items also be a drop target.
276             * @type Boolean
277             */        
278             target: {
279                 value: false
280             },
281             /**
282             * @attribute dragConfig
283             * @description The default config to be used when creating the DD instance.
284             * @type Object
285             */        
286             dragConfig: {
287                 value: null
288             },
289             /**
290             * @attribute handles
291             * @description The handles config option added to the temp DD instance.
292             * @type Array
293             */        
294             handles: {
295                 value: null
296             }
297         }
298     });
299
300     Y.mix(Y.DD.DDM, {
301         /**
302         * @private
303         * @for DDM
304         * @property _delegates
305         * @description Holder for all Y.DD.Delegate instances
306         * @type Array
307         */
308         _delegates: [],
309         /**
310         * @for DDM
311         * @method regDelegate
312         * @description Register a Delegate with the DDM
313         */
314         regDelegate: function(del) {
315             this._delegates.push(del);
316         },
317         /**
318         * @for DDM
319         * @method getDelegate
320         * @description Get a delegate instance from a container node
321         * @returns Y.DD.Delegate
322         */
323         getDelegate: function(node) {
324             var del = null;
325             node = Y.one(node);
326             Y.each(this._delegates, function(v) {
327                 if (node.test(v.get(CONT))) {
328                     del = v;
329                 }
330             }, this);
331             return del;
332         }
333     });
334
335     Y.namespace('DD');    
336     Y.DD.Delegate = Delegate;
337
338
339
340 }, '3.3.0' ,{requires:['dd-drag', 'event-mouseenter'], skinnable:false, optional:['dd-drop-plugin']});