first pass RT4 merge, RT#13852
[freeside.git] / rt / share / html / NoAuth / js / jquery.event.hover-1.0.js
1 ;(function($){ // secure $ jQuery alias
2 /*******************************************************************************************/   
3 // jquery.event.hover.js - rev 5 
4 // Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
5 // Liscensed under the MIT License (MIT-LICENSE.txt)
6 // http://www.opensource.org/licenses/mit-license.php
7 // Created: 2008-06-02 | Updated: 2008-07-30
8 /*******************************************************************************************/
9
10 //      USE THESE PROPERTIES TO CUSTOMIZE SETTINGS...
11
12 //      $.event.special.hover.delay = 100; 
13 //      Defines the delay (msec) while mouse is inside the element before checking the speed
14
15 //      $.event.special.hover.speed = 100; 
16 //      Defines the maximum speed (px/sec) the mouse may be moving to trigger the hover event
17
18 // save the old jquery "hover" method
19 $.fn._hover = $.fn.hover;
20
21 // jquery method 
22 $.fn.hover = function( fn1, fn2, fn3 ) {
23         if ( fn3 ) this.bind('hoverstart', fn1 ); // 3 args
24         if ( fn2 ) this.bind('hoverend', fn3 ? fn3 : fn2 ); // 2+ args
25         return !fn1 ? this.trigger('hover') // 0 args 
26                 : this.bind('hover', fn3 ? fn2 : fn1 ); // 1+ args
27         };      
28
29 // special event configuration
30 var hover = $.event.special.hover = {
31         delay: 100, // milliseconds
32         speed: 100, // pixels per second
33         setup: function( data ){
34                 data = $.extend({ speed: hover.speed, delay: hover.delay, hovered:0 }, data||{} );
35                 $.event.add( this, "mouseenter mouseleave", hoverHandler, data );
36                 },
37         teardown: function(){
38                 $.event.remove( this, "mouseenter mouseleave", hoverHandler );
39                 }
40         };
41
42 // shared event handler
43 function hoverHandler( event ){
44         var data = event.data || event;
45         switch ( event.type ){
46                 case 'mouseenter': // mouseover
47                         data.dist2 = 0; // init mouse distance²
48                         data.event = event; // store the event
49                         event.type = "hoverstart"; // hijack event
50                         if ( $.event.handle.call( this, event ) !== false ){ // handle "hoverstart"
51                                 data.elem = this; // ref to the current element
52                                 $.event.add( this, "mousemove", hoverHandler, data ); // track the mouse
53                                 data.timer = setTimeout( compare, data.delay ); // start async compare
54                                 }
55                         break;
56                 case 'mousemove': // track the event, mouse distance² = x² + y²
57                         data.dist2 += Math.pow( event.pageX-data.event.pageX, 2 ) 
58                                 + Math.pow( event.pageY-data.event.pageY, 2 ); 
59                         data.event = event; // store current event
60                         break;
61                 case 'mouseleave': // mouseout
62                         clearTimeout( data.timer ); // uncompare
63                         if ( data.hovered ){ 
64                                 event.type = "hoverend"; // hijack event
65                                 $.event.handle.call( this, event ); // handle "hoverend"
66                                 data.hovered--; // reset flag
67                                 }
68                         else $.event.remove( data.elem, "mousemove", hoverHandler ); // untrack
69                         break;
70                 default: // timeout compare // distance² = x² + y²  = ( speed * time )²
71                         if ( data.dist2 <= Math.pow( data.speed*( data.delay/1e3 ), 2 ) ){ // speed acceptable
72                                 $.event.remove( data.elem, "mousemove", hoverHandler ); // untrack
73                                 data.event.type = "hover"; // hijack event
74                                 if ( $.event.handle.call( data.elem, data.event ) !== false ) // handle "hover"
75                                         data.hovered++; // flag for "hoverend"
76                                 }
77                         else data.timer = setTimeout( compare, data.delay ); // async recurse
78                         data.dist2 = 0; // reset distance² for next compare
79                         break;
80                 }
81         function compare(){ hoverHandler( data ); }; // timeout/recursive function
82         };
83         
84 /*******************************************************************************************/
85 })(jQuery); // confine scope