Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('dd-ddm-drop', function (Y, NAME) {
2
 
3
 
4
    /**
5
     * Extends the dd-ddm Class to add support for the placement of Drop Target
6
     * shims inside the viewport shim. It also handles all Drop Target related events and interactions.
7
     * @module dd
8
     * @submodule dd-ddm-drop
9
     * @for DDM
10
     * @namespace DD
11
     */
12
 
13
    //TODO CSS class name for the bestMatch..
14
    Y.mix(Y.DD.DDM, {
15
        /**
16
        * This flag turns off the use of the mouseover/mouseout shim. It should not be used unless you know what you are doing.
17
        * @private
18
        * @property _noShim
19
        * @type {Boolean}
20
        */
21
        _noShim: false,
22
        /**
23
        * Placeholder for all active shims on the page
24
        * @private
25
        * @property _activeShims
26
        * @type {Array}
27
        */
28
        _activeShims: [],
29
        /**
30
        * This method checks the _activeShims Object to see if there is a shim active.
31
        * @private
32
        * @method _hasActiveShim
33
        * @return {Boolean}
34
        */
35
        _hasActiveShim: function() {
36
            if (this._noShim) {
37
                return true;
38
            }
39
            return this._activeShims.length;
40
        },
41
        /**
42
        * Adds a Drop Target to the list of active shims
43
        * @private
44
        * @method _addActiveShim
45
        * @param {Object} d The Drop instance to add to the list.
46
        */
47
        _addActiveShim: function(d) {
48
            this._activeShims.push(d);
49
        },
50
        /**
51
        * Removes a Drop Target to the list of active shims
52
        * @private
53
        * @method _removeActiveShim
54
        * @param {Object} d The Drop instance to remove from the list.
55
        */
56
        _removeActiveShim: function(d) {
57
            var s = [];
58
            Y.Array.each(this._activeShims, function(v) {
59
                if (v._yuid !== d._yuid) {
60
                    s.push(v);
61
                }
62
 
63
            });
64
            this._activeShims = s;
65
        },
66
        /**
67
        * This method will sync the position of the shims on the Drop Targets that are currently active.
68
        * @method syncActiveShims
69
        * @param {Boolean} force Resize/sync all Targets.
70
        */
71
        syncActiveShims: function(force) {
72
            Y.later(0, this, function(force) {
73
                var drops = ((force) ? this.targets : this._lookup());
74
                Y.Array.each(drops, function(v) {
75
                    v.sizeShim.call(v);
76
                }, this);
77
            }, force);
78
        },
79
        /**
80
        * The mode that the drag operations will run in 0 for Point, 1 for Intersect, 2 for Strict
81
        * @private
82
        * @property mode
83
        * @type Number
84
        */
85
        mode: 0,
86
        /**
87
        * In point mode, a Drop is targeted by the cursor being over the Target
88
        * @private
89
        * @property POINT
90
        * @type Number
91
        */
92
        POINT: 0,
93
        /**
94
        * In intersect mode, a Drop is targeted by "part" of the drag node being over the Target
95
        * @private
96
        * @property INTERSECT
97
        * @type Number
98
        */
99
        INTERSECT: 1,
100
        /**
101
        * In strict mode, a Drop is targeted by the "entire" drag node being over the Target
102
        * @private
103
        * @property STRICT
104
        * @type Number
105
        */
106
        STRICT: 2,
107
        /**
108
        * Should we only check targets that are in the viewport on drags (for performance), default: true
109
        * @property useHash
110
        * @type {Boolean}
111
        */
112
        useHash: true,
113
        /**
114
        * A reference to the active Drop Target
115
        * @property activeDrop
116
        * @type {Object}
117
        */
118
        activeDrop: null,
119
        /**
120
        * An array of the valid Drop Targets for this interaction.
121
        * @property validDrops
122
        * @type {Array}
123
        */
124
        //TODO Change array/object literals to be in sync..
125
        validDrops: [],
126
        /**
127
        * An object literal of Other Drop Targets that we encountered during this interaction (in the case of overlapping Drop Targets)
128
        * @property otherDrops
129
        * @type {Object}
130
        */
131
        otherDrops: {},
132
        /**
133
        * All of the Targets
134
        * @property targets
135
        * @type {Array}
136
        */
137
        targets: [],
138
        /**
139
        * Add a Drop Target to the list of Valid Targets. This list get's regenerated on each new drag operation.
140
        * @private
141
        * @method _addValid
142
        * @param {Object} drop
143
        * @chainable
144
        */
145
        _addValid: function(drop) {
146
            this.validDrops.push(drop);
147
            return this;
148
        },
149
        /**
150
        * Removes a Drop Target from the list of Valid Targets. This list get's regenerated on each new drag operation.
151
        * @private
152
        * @method _removeValid
153
        * @param {Object} drop
154
        * @chainable
155
        */
156
        _removeValid: function(drop) {
157
            var drops = [];
158
            Y.Array.each(this.validDrops, function(v) {
159
                if (v !== drop) {
160
                    drops.push(v);
161
                }
162
            });
163
 
164
            this.validDrops = drops;
165
            return this;
166
        },
167
        /**
168
        * Check to see if the Drag element is over the target, method varies on current mode
169
        * @method isOverTarget
170
        * @param {Object} drop The drop to check against
171
        * @return {Boolean}
172
        */
173
        isOverTarget: function(drop) {
174
            if (this.activeDrag && drop) {
175
                var xy = this.activeDrag.mouseXY, r, dMode = this.activeDrag.get('dragMode'),
176
                    aRegion, node = drop.shim;
177
                if (xy && this.activeDrag) {
178
                    aRegion = this.activeDrag.region;
179
                    if (dMode === this.STRICT) {
180
                        return this.activeDrag.get('dragNode').inRegion(drop.region, true, aRegion);
181
                    }
182
                    if (drop && drop.shim) {
183
                        if ((dMode === this.INTERSECT) && this._noShim) {
184
                            r = aRegion || this.activeDrag.get('node');
185
                            return drop.get('node').intersect(r, drop.region).inRegion;
186
                        }
187
 
188
                        if (this._noShim) {
189
                            node = drop.get('node');
190
                        }
191
                        return node.intersect({
192
                            top: xy[1],
193
                            bottom: xy[1],
194
                            left: xy[0],
195
                            right: xy[0]
196
                        }, drop.region).inRegion;
197
                    }
198
                }
199
            }
200
            return false;
201
        },
202
        /**
203
        * Clears the cache data used for this interaction.
204
        * @method clearCache
205
        */
206
        clearCache: function() {
207
            this.validDrops = [];
208
            this.otherDrops = {};
209
            this._activeShims = [];
210
        },
211
        /**
212
        * Clear the cache and activate the shims of all the targets
213
        * @private
214
        * @method _activateTargets
215
        */
216
        _activateTargets: function() {
217
            this._noShim = true;
218
            this.clearCache();
219
            Y.Array.each(this.targets, function(v) {
220
                v._activateShim([]);
221
                if (v.get('noShim') === true) {
222
                    this._noShim = false;
223
                }
224
            }, this);
225
            this._handleTargetOver();
226
 
227
        },
228
        /**
229
        * This method will gather the area for all potential targets and see which has the hightest covered area and return it.
230
        * @method getBestMatch
231
        * @param {Array} drops An Array of drops to scan for the best match.
232
        * @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.
233
        * @return {Object or Array}
234
        */
235
        getBestMatch: function(drops, all) {
236
            var biggest = null, area = 0, out;
237
 
238
            Y.Object.each(drops, function(v) {
239
                var inter = this.activeDrag.get('dragNode').intersect(v.get('node'));
240
                v.region.area = inter.area;
241
 
242
                if (inter.inRegion) {
243
                    if (inter.area > area) {
244
                        area = inter.area;
245
                        biggest = v;
246
                    }
247
                }
248
            }, this);
249
            if (all) {
250
                out = [];
251
                //TODO Sort the others in numeric order by area covered..
252
                Y.Object.each(drops, function(v) {
253
                    if (v !== biggest) {
254
                        out.push(v);
255
                    }
256
                }, this);
257
                return [biggest, out];
258
            }
259
            return biggest;
260
        },
261
        /**
262
        * This method fires the drop:hit, drag:drophit, drag:dropmiss methods and deactivates the shims..
263
        * @private
264
        * @method _deactivateTargets
265
        */
266
        _deactivateTargets: function() {
267
            var other = [], tmp,
268
                activeDrag = this.activeDrag,
269
                activeDrop = this.activeDrop;
270
 
271
            //TODO why is this check so hard??
272
            if (activeDrag && activeDrop && this.otherDrops[activeDrop]) {
273
                if (!activeDrag.get('dragMode')) {
274
                    //TODO otherDrops -- private..
275
                    other = this.otherDrops;
276
                    delete other[activeDrop];
277
                } else {
278
                    tmp = this.getBestMatch(this.otherDrops, true);
279
                    activeDrop = tmp[0];
280
                    other = tmp[1];
281
                }
282
                activeDrag.get('node').removeClass(this.CSS_PREFIX + '-drag-over');
283
                if (activeDrop) {
284
                    activeDrop.fire('drop:hit', { drag: activeDrag, drop: activeDrop, others: other });
285
                    activeDrag.fire('drag:drophit', { drag: activeDrag,  drop: activeDrop, others: other });
286
                }
287
            } else if (activeDrag && activeDrag.get('dragging')) {
288
                activeDrag.get('node').removeClass(this.CSS_PREFIX + '-drag-over');
289
                activeDrag.fire('drag:dropmiss', { pageX: activeDrag.lastXY[0], pageY: activeDrag.lastXY[1] });
290
            }
291
 
292
            this.activeDrop = null;
293
 
294
            Y.Array.each(this.targets, function(v) {
295
                v._deactivateShim([]);
296
            }, this);
297
        },
298
        /**
299
        * This method is called when the move method is called on the Drag Object.
300
        * @private
301
        * @method _dropMove
302
        */
303
        _dropMove: function() {
304
            if (this._hasActiveShim()) {
305
                this._handleTargetOver();
306
            } else {
307
                Y.Object.each(this.otherDrops, function(v) {
308
                    v._handleOut.apply(v, []);
309
                });
310
            }
311
        },
312
        /**
313
        * Filters the list of Drops down to those in the viewport.
314
        * @private
315
        * @method _lookup
316
        * @return {Array} The valid Drop Targets that are in the viewport.
317
        */
318
        _lookup: function() {
319
            if (!this.useHash || this._noShim) {
320
                return this.validDrops;
321
            }
322
            var drops = [];
323
            //Only scan drop shims that are in the Viewport
324
            Y.Array.each(this.validDrops, function(v) {
325
                if (v.shim && v.shim.inViewportRegion(false, v.region)) {
326
                    drops.push(v);
327
                }
328
            });
329
            return drops;
330
 
331
        },
332
        /**
333
        * This method execs _handleTargetOver on all valid Drop Targets
334
        * @private
335
        * @method _handleTargetOver
336
        */
337
        _handleTargetOver: function() {
338
            var drops = this._lookup();
339
            Y.Array.each(drops, function(v) {
340
                v._handleTargetOver.call(v);
341
            }, this);
342
        },
343
        /**
344
        * Add the passed in Target to the targets collection
345
        * @private
346
        * @method _regTarget
347
        * @param {Object} t The Target to add to the targets collection
348
        */
349
        _regTarget: function(t) {
350
            this.targets.push(t);
351
        },
352
        /**
353
        * Remove the passed in Target from the targets collection
354
        * @private
355
        * @method _unregTarget
356
        * @param {Object} drop The Target to remove from the targets collection
357
        */
358
        _unregTarget: function(drop) {
359
            var targets = [], vdrops;
360
            Y.Array.each(this.targets, function(v) {
361
                if (v !== drop) {
362
                    targets.push(v);
363
                }
364
            }, this);
365
            this.targets = targets;
366
 
367
            vdrops = [];
368
            Y.Array.each(this.validDrops, function(v) {
369
                if (v !== drop) {
370
                    vdrops.push(v);
371
                }
372
            });
373
 
374
            this.validDrops = vdrops;
375
        },
376
        /**
377
        * Get a valid Drop instance back from a Node or a selector string, false otherwise
378
        * @method getDrop
379
        * @param {String/Object} node The Node instance or Selector string to check for a valid Drop Object
380
        * @return {Object}
381
        */
382
        getDrop: function(node) {
383
            var drop = false,
384
                n = Y.one(node);
385
            if (n instanceof Y.Node) {
386
                Y.Array.each(this.targets, function(v) {
387
                    if (n.compareTo(v.get('node'))) {
388
                        drop = v;
389
                    }
390
                });
391
            }
392
            return drop;
393
        }
394
    }, true);
395
 
396
 
397
 
398
 
399
}, '3.18.1', {"requires": ["dd-ddm"]});