source: extensions/EasyCaptcha/template/jquery.events/jquery.event.drop-2.2.js @ 24215

Last change on this file since 24215 was 24215, checked in by mistic100, 11 years ago

add extension EasyCaptcha

File size: 9.2 KB
Line 
1/*!
2 * jquery.event.drop - v 2.2
3 * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
4 * Open Source MIT License - http://threedubmedia.com/code/license
5 */
6// Created: 2008-06-04
7// Updated: 2012-05-21
8// REQUIRES: jquery 1.7.x, event.drag 2.2
9
10;(function($){ // secure $ jQuery alias
11
12// Events: drop, dropstart, dropend
13
14// add the jquery instance method
15$.fn.drop = function( str, arg, opts ){
16        // figure out the event type
17        var type = typeof str == "string" ? str : "",
18        // figure out the event handler...
19        fn = $.isFunction( str ) ? str : $.isFunction( arg ) ? arg : null;
20        // fix the event type
21        if ( type.indexOf("drop") !== 0 ) 
22                type = "drop"+ type;
23        // were options passed
24        opts = ( str == fn ? arg : opts ) || {};
25        // trigger or bind event handler
26        return fn ? this.bind( type, opts, fn ) : this.trigger( type );
27};
28
29// DROP MANAGEMENT UTILITY
30// returns filtered drop target elements, caches their positions
31$.drop = function( opts ){ 
32        opts = opts || {};
33        // safely set new options...
34        drop.multi = opts.multi === true ? Infinity : 
35                opts.multi === false ? 1 : !isNaN( opts.multi ) ? opts.multi : drop.multi;
36        drop.delay = opts.delay || drop.delay;
37        drop.tolerance = $.isFunction( opts.tolerance ) ? opts.tolerance : 
38                opts.tolerance === null ? null : drop.tolerance;
39        drop.mode = opts.mode || drop.mode || 'intersect';
40};
41
42// local refs (increase compression)
43var $event = $.event, 
44$special = $event.special,
45// configure the drop special event
46drop = $.event.special.drop = {
47
48        // these are the default settings
49        multi: 1, // allow multiple drop winners per dragged element
50        delay: 20, // async timeout delay
51        mode: 'overlap', // drop tolerance mode
52               
53        // internal cache
54        targets: [], 
55       
56        // the key name for stored drop data
57        datakey: "dropdata",
58               
59        // prevent bubbling for better performance
60        noBubble: true,
61       
62        // count bound related events
63        add: function( obj ){ 
64                // read the interaction data
65                var data = $.data( this, drop.datakey );
66                // count another realted event
67                data.related += 1;
68        },
69       
70        // forget unbound related events
71        remove: function(){
72                $.data( this, drop.datakey ).related -= 1;
73        },
74       
75        // configure the interactions
76        setup: function(){
77                // check for related events
78                if ( $.data( this, drop.datakey ) ) 
79                        return;
80                // initialize the drop element data
81                var data = { 
82                        related: 0,
83                        active: [],
84                        anyactive: 0,
85                        winner: 0,
86                        location: {}
87                };
88                // store the drop data on the element
89                $.data( this, drop.datakey, data );
90                // store the drop target in internal cache
91                drop.targets.push( this );
92        },
93       
94        // destroy the configure interaction   
95        teardown: function(){ 
96                var data = $.data( this, drop.datakey ) || {};
97                // check for related events
98                if ( data.related ) 
99                        return;
100                // remove the stored data
101                $.removeData( this, drop.datakey );
102                // reference the targeted element
103                var element = this;
104                // remove from the internal cache
105                drop.targets = $.grep( drop.targets, function( target ){ 
106                        return ( target !== element ); 
107                });
108        },
109       
110        // shared event handler
111        handler: function( event, dd ){ 
112                // local vars
113                var results, $targets;
114                // make sure the right data is available
115                if ( !dd ) 
116                        return;
117                // handle various events
118                switch ( event.type ){
119                        // draginit, from $.event.special.drag
120                        case 'mousedown': // DROPINIT >>
121                        case 'touchstart': // DROPINIT >>
122                                // collect and assign the drop targets
123                                $targets =  $( drop.targets );
124                                if ( typeof dd.drop == "string" )
125                                        $targets = $targets.filter( dd.drop );
126                                // reset drop data winner properties
127                                $targets.each(function(){
128                                        var data = $.data( this, drop.datakey );
129                                        data.active = [];
130                                        data.anyactive = 0;
131                                        data.winner = 0;
132                                });
133                                // set available target elements
134                                dd.droppable = $targets;
135                                // activate drop targets for the initial element being dragged
136                                $special.drag.hijack( event, "dropinit", dd ); 
137                                break;
138                        // drag, from $.event.special.drag
139                        case 'mousemove': // TOLERATE >>
140                        case 'touchmove': // TOLERATE >>
141                                drop.event = event; // store the mousemove event
142                                if ( !drop.timer )
143                                        // monitor drop targets
144                                        drop.tolerate( dd ); 
145                                break;
146                        // dragend, from $.event.special.drag
147                        case 'mouseup': // DROP >> DROPEND >>
148                        case 'touchend': // DROP >> DROPEND >>
149                                drop.timer = clearTimeout( drop.timer ); // delete timer       
150                                if ( dd.propagates ){
151                                        $special.drag.hijack( event, "drop", dd ); 
152                                        $special.drag.hijack( event, "dropend", dd ); 
153                                }
154                                break;
155                               
156                }
157        },
158               
159        // returns the location positions of an element
160        locate: function( elem, index ){ 
161                var data = $.data( elem, drop.datakey ),
162                $elem = $( elem ), 
163                posi = $elem.offset() || {}, 
164                height = $elem.outerHeight(), 
165                width = $elem.outerWidth(),
166                location = { 
167                        elem: elem, 
168                        width: width, 
169                        height: height,
170                        top: posi.top, 
171                        left: posi.left, 
172                        right: posi.left + width, 
173                        bottom: posi.top + height
174                };
175                // drag elements might not have dropdata
176                if ( data ){
177                        data.location = location;
178                        data.index = index;
179                        data.elem = elem;
180                }
181                return location;
182        },
183       
184        // test the location positions of an element against another OR an X,Y coord
185        contains: function( target, test ){ // target { location } contains test [x,y] or { location }
186                return ( ( test[0] || test.left ) >= target.left && ( test[0] || test.right ) <= target.right
187                        && ( test[1] || test.top ) >= target.top && ( test[1] || test.bottom ) <= target.bottom ); 
188        },
189       
190        // stored tolerance modes
191        modes: { // fn scope: "$.event.special.drop" object
192                // target with mouse wins, else target with most overlap wins
193                'intersect': function( event, proxy, target ){
194                        return this.contains( target, [ event.pageX, event.pageY ] ) ? // check cursor
195                                1e9 : this.modes.overlap.apply( this, arguments ); // check overlap
196                },
197                // target with most overlap wins       
198                'overlap': function( event, proxy, target ){
199                        // calculate the area of overlap...
200                        return Math.max( 0, Math.min( target.bottom, proxy.bottom ) - Math.max( target.top, proxy.top ) )
201                                * Math.max( 0, Math.min( target.right, proxy.right ) - Math.max( target.left, proxy.left ) );
202                },
203                // proxy is completely contained within target bounds   
204                'fit': function( event, proxy, target ){
205                        return this.contains( target, proxy ) ? 1 : 0;
206                },
207                // center of the proxy is contained within target bounds       
208                'middle': function( event, proxy, target ){
209                        return this.contains( target, [ proxy.left + proxy.width * .5, proxy.top + proxy.height * .5 ] ) ? 1 : 0;
210                }
211        },     
212       
213        // sort drop target cache by by winner (dsc), then index (asc)
214        sort: function( a, b ){
215                return ( b.winner - a.winner ) || ( a.index - b.index );
216        },
217               
218        // async, recursive tolerance execution
219        tolerate: function( dd ){               
220                // declare local refs
221                var i, drp, drg, data, arr, len, elem,
222                // interaction iteration variables
223                x = 0, ia, end = dd.interactions.length,
224                // determine the mouse coords
225                xy = [ drop.event.pageX, drop.event.pageY ],
226                // custom or stored tolerance fn
227                tolerance = drop.tolerance || drop.modes[ drop.mode ];
228                // go through each passed interaction...
229                do if ( ia = dd.interactions[x] ){
230                        // check valid interaction
231                        if ( !ia )
232                                return; 
233                        // initialize or clear the drop data
234                        ia.drop = [];
235                        // holds the drop elements
236                        arr = []; 
237                        len = ia.droppable.length;
238                        // determine the proxy location, if needed
239                        if ( tolerance )
240                                drg = drop.locate( ia.proxy ); 
241                        // reset the loop
242                        i = 0;
243                        // loop each stored drop target
244                        do if ( elem = ia.droppable[i] ){ 
245                                data = $.data( elem, drop.datakey );
246                                drp = data.location;
247                                if ( !drp ) continue;
248                                // find a winner: tolerance function is defined, call it
249                                data.winner = tolerance ? tolerance.call( drop, drop.event, drg, drp ) 
250                                        // mouse position is always the fallback
251                                        : drop.contains( drp, xy ) ? 1 : 0; 
252                                arr.push( data );       
253                        } while ( ++i < len ); // loop
254                        // sort the drop targets
255                        arr.sort( drop.sort );                 
256                        // reset the loop
257                        i = 0;
258                        // loop through all of the targets again
259                        do if ( data = arr[ i ] ){
260                                // winners...
261                                if ( data.winner && ia.drop.length < drop.multi ){
262                                        // new winner... dropstart
263                                        if ( !data.active[x] && !data.anyactive ){
264                                                // check to make sure that this is not prevented
265                                                if ( $special.drag.hijack( drop.event, "dropstart", dd, x, data.elem )[0] !== false ){ 
266                                                        data.active[x] = 1;
267                                                        data.anyactive += 1;
268                                                }
269                                                // if false, it is not a winner
270                                                else
271                                                        data.winner = 0;
272                                        }
273                                        // if it is still a winner
274                                        if ( data.winner )
275                                                ia.drop.push( data.elem );
276                                }
277                                // losers...
278                                else if ( data.active[x] && data.anyactive == 1 ){
279                                        // former winner... dropend
280                                        $special.drag.hijack( drop.event, "dropend", dd, x, data.elem ); 
281                                        data.active[x] = 0;
282                                        data.anyactive -= 1;
283                                }
284                        } while ( ++i < len ); // loop         
285                } while ( ++x < end ) // loop
286                // check if the mouse is still moving or is idle
287                if ( drop.last && xy[0] == drop.last.pageX && xy[1] == drop.last.pageY ) 
288                        delete drop.timer; // idle, don't recurse
289                else  // recurse
290                        drop.timer = setTimeout(function(){ 
291                                drop.tolerate( dd ); 
292                        }, drop.delay );
293                // remember event, to compare idleness
294                drop.last = drop.event; 
295        }
296       
297};
298
299// share the same special event configuration with related events...
300$special.dropinit = $special.dropstart = $special.dropend = drop;
301
302})(jQuery);
Note: See TracBrowser for help on using the repository browser.