root/galaxy-central/static/scripts/jquery.event.drop.js @ 2

リビジョン 2, 7.1 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
1/*! jquery.event.drop.js * v1.2
2Copyright (c) 2008-2009, Three Dub Media (http://threedubmedia.com) 
3Liscensed under the MIT License (http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt)
4*/;(function($){ // secure $ jQuery alias
5// Created: 2008-06-04 | Updated: 2009-03-16
6/*******************************************************************************************/
7// Events: drop, dropstart, dropend
8/*******************************************************************************************/
9
10// JQUERY METHOD
11$.fn.drop = function( fn1, fn2, fn3 ){
12        if ( fn2 ) this.bind('dropstart', fn1 ); // 2+ args
13        if ( fn3 ) this.bind('dropend', fn3 ); // 3 args
14        return !fn1 ? this.trigger('drop') // 0 args
15                : this.bind('drop', fn2 ? fn2 : fn1 ); // 1+ args
16        };
17
18// DROP MANAGEMENT UTILITY
19$.dropManage = function( opts ){ // return filtered drop target elements, cache their positions
20        opts = opts || {};
21        // safely set new options...
22        drop.data = [];
23        drop.filter = opts.filter || '*';
24        drop.delay = opts.delay || drop.delay;
25        drop.tolerance = opts.tolerance || null;
26        drop.mode = opts.mode || drop.mode || 'intersect';
27        // return the filtered set of drop targets
28        return drop.$targets.filter( drop.filter ).each(function(){
29                // locate and store the filtered drop targets
30                drop.data[ drop.data.length ] = drop.locate( this );
31                });
32        };
33
34// local refs
35var $event = $.event, $special = $event.special,
36
37// SPECIAL EVENT CONFIGURATION
38drop = $special.drop = {
39        delay: 100, // default frequency to track drop targets
40        mode: 'intersect', // default mode to determine valid drop targets
41        $targets: $([]), data: [], // storage of drop targets and locations
42        setup: function(){
43                drop.$targets = drop.$targets.add( this );
44                drop.data[ drop.data.length ] = drop.locate( this );
45                },
46        teardown: function(){ var elem = this;
47                drop.$targets = drop.$targets.not( this );
48                drop.data = $.grep( drop.data, function( obj ){
49                        return ( obj.elem !== elem );
50                        });
51                },
52        // shared handler
53        handler: function( event ){
54                var dropstart = null, dropped;
55                event.dropTarget = drop.dropping || undefined; // dropped element
56                if ( drop.data.length && event.dragTarget ){
57                        // handle various events
58                        switch ( event.type ){
59                                // drag/mousemove, from $.event.special.drag
60                                case 'drag': // TOLERATE >>
61                                        drop.event = event; // store the mousemove event
62                                        if ( !drop.timer ) // monitor drop targets
63                                                drop.timer = setTimeout( tolerate, 20 );
64                                        break;                 
65                                // dragstop/mouseup, from $.event.special.drag
66                                case 'mouseup': // DROP >> DROPEND >>
67                                        drop.timer = clearTimeout( drop.timer ); // delete timer       
68                                        if ( !drop.dropping ) break; // stop, no drop
69                                        if ( drop.allowed )     
70                                                dropped = hijack( event, "drop", drop.dropping ); // trigger "drop"
71                                        dropstart = false;
72                                // activate new target, from tolerate (async)
73                                case drop.dropping && 'dropstart': // DROPSTART >> ( new target )
74                                        dropstart = dropstart===null && drop.allowed ? true : false;
75                                // deactivate active target, from tolerate (async)
76                                case drop.dropping && 'dropend': // DROPEND >>
77                                        hijack( event, "dropend", drop.dropping ); // trigger "dropend"
78                                        drop.dropping = null; // empty dropper
79                                        if ( dropped === false ) event.dropTarget = undefined;
80                                        if ( !dropstart ) break; // stop
81                                // activate target, from tolerate (async)
82                                case drop.allowed && 'dropstart': // DROPSTART >>
83                                        event.dropTarget = this;
84                                        drop.dropping = hijack( event, "dropstart", this )!==false ? this : null;  // trigger "dropstart"
85                                        break;
86                                }
87                        }
88                },
89        // returns the location positions of an element
90        locate: function( elem ){ // return { L:left, R:right, T:top, B:bottom, H:height, W:width }
91                var $el = $(elem), pos = $el.offset(), h = $el.outerHeight(), w = $el.outerWidth();
92                return { elem: elem, L: pos.left, R: pos.left+w, T: pos.top, B: pos.top+h, W: w, H: h };
93                },
94        // test the location positions of an element against another OR an X,Y coord
95        contains: function( target, test ){ // target { L,R,T,B,H,W } contains test [x,y] or { L,R,T,B,H,W }
96                return ( ( test[0] || test.L ) >= target.L && ( test[0] || test.R ) <= target.R
97                        && ( test[1] || test.T ) >= target.T && ( test[1] || test.B ) <= target.B );
98                },
99        // stored tolerance modes
100        modes: { // fn scope: "$.event.special.drop" object
101                // target with mouse wins, else target with most overlap wins
102                'intersect': function( event, proxy, target ){
103                        return this.contains( target, [ event.pageX, event.pageY ] ) ? // check cursor
104                                target : this.modes['overlap'].apply( this, arguments ); // check overlap
105                        },
106                // target with most overlap wins       
107                'overlap': function( event, proxy, target ){
108                        // calculate the area of overlap...
109                        target.overlap = Math.max( 0, Math.min( target.B, proxy.B ) - Math.max( target.T, proxy.T ) )
110                                * Math.max( 0, Math.min( target.R, proxy.R ) - Math.max( target.L, proxy.L ) );
111                        if ( target.overlap > ( ( this.best || {} ).overlap || 0 ) ) // compare overlap
112                                this.best = target; // set as the best match so far
113                        return null; // no winner
114                        },
115                // proxy is completely contained within target bounds   
116                'fit': function( event, proxy, target ){
117                        return this.contains( target, proxy ) ? target : null;
118                        },
119                // center of the proxy is contained within target bounds       
120                'middle': function( event, proxy, target ){
121                        return this.contains( target, [ proxy.L+proxy.W/2, proxy.T+proxy.H/2 ] ) ? target : null;
122                        }
123                }       
124        };
125
126// set event type to custom value, and handle it
127function hijack ( event, type, elem ){
128        event.type = type; // force the event type
129        try { var result = $event.handle.call( elem, event );
130                } catch ( ex ){ /* catch IE error with async event handling */ }         
131        return result===false ? false : result || event.result;
132        };
133       
134// async, recursive tolerance execution
135function tolerate (){
136        var i = 0, drp, winner, // local variables
137        xy = [ drop.event.pageX, drop.event.pageY ], // mouse location
138        drg = drop.locate( drop.event.dragProxy ); // drag proxy location
139        drop.tolerance = drop.tolerance || drop.modes[ drop.mode ]; // custom or stored tolerance fn
140        do if ( drp = drop.data[i] ){ // each drop target location
141                // tolerance function is defined, or mouse contained
142                winner = drop.tolerance ? drop.tolerance.call( drop, drop.event, drg, drp )
143                        : drop.contains( drp, xy ) ? drp : null; // mouse is always fallback
144                }
145        while ( ++i<drop.data.length && !winner ); // loop
146        drop.event.type = ( winner = winner || drop.best ) ? 'dropstart' : 'dropend'; // start ? stop
147        if ( drop.event.type=='dropend' || winner.elem!=drop.dropping ) // don't dropstart on active drop target
148                drop.handler.call( winner ? winner.elem : drop.dropping, drop.event ); // handle events
149        if ( drop.last && xy[0] == drop.last.pageX && xy[1] == drop.last.pageY ) // no movement
150                delete drop.timer; // idle, don't recurse
151        else drop.timer = setTimeout( tolerate, drop.delay ); // recurse
152        drop.last = drop.event; // to compare idleness
153        drop.best = null; // reset comparitors
154        };
155
156/*******************************************************************************************/
157})(jQuery); // confine scope
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。