Moved all the relevant event-related code into the event module.
[jquery.git] / src / event / event.js
1 /*
2  * A number of helper functions used for managing events.
3  * Many of the ideas behind this code orignated from 
4  * Dean Edwards' addEvent library.
5  */
6 jQuery.event = {
7
8         // Bind an event to an element
9         // Original by Dean Edwards
10         add: function(element, type, handler, data) {
11                 // For whatever reason, IE has trouble passing the window object
12                 // around, causing it to be cloned in the process
13                 if ( jQuery.browser.msie && element.setInterval != undefined )
14                         element = window;
15
16                 // if data is passed, bind to handler
17                 if( data ) 
18                         handler.data = data;
19
20                 // Make sure that the function being executed has a unique ID
21                 if ( !handler.guid )
22                         handler.guid = this.guid++;
23
24                 // Init the element's event structure
25                 if (!element.events)
26                         element.events = {};
27
28                 // Get the current list of functions bound to this event
29                 var handlers = element.events[type];
30
31                 // If it hasn't been initialized yet
32                 if (!handlers) {
33                         // Init the event handler queue
34                         handlers = element.events[type] = {};
35
36                         // Remember an existing handler, if it's already there
37                         if (element["on" + type])
38                                 handlers[0] = element["on" + type];
39                 }
40
41                 // Add the function to the element's handler list
42                 handlers[handler.guid] = handler;
43
44                 // And bind the global event handler to the element
45                 element["on" + type] = this.handle;
46
47                 // Remember the function in a global list (for triggering)
48                 if (!this.global[type])
49                         this.global[type] = [];
50                 this.global[type].push( element );
51         },
52
53         guid: 1,
54         global: {},
55
56         // Detach an event or set of events from an element
57         remove: function(element, type, handler) {
58                 if (element.events)
59                         if ( type && type.type )
60                                 delete element.events[ type.type ][ type.handler.guid ];
61                         else if (type && element.events[type])
62                                 if ( handler )
63                                         delete element.events[type][handler.guid];
64                                 else
65                                         for ( var i in element.events[type] )
66                                                 delete element.events[type][i];
67                         else
68                                 for ( var j in element.events )
69                                         this.remove( element, j );
70         },
71
72         trigger: function(type,data,element) {
73                 // Clone the incoming data, if any
74                 data = jQuery.makeArray(data || []);
75
76                 // Handle a global trigger
77                 if ( !element ) {
78                         var g = this.global[type];
79                         if ( g )
80                                 for ( var i = 0, gl = g.length; i < gl; i++ )
81                                         this.trigger( type, data, g[i] );
82
83                 // Handle triggering a single element
84                 } else if ( element["on" + type] ) {
85                         // Pass along a fake event
86                         data.unshift( this.fix({ type: type, target: element }) );
87
88                         // Trigger the event
89                         element["on" + type].apply( element, data );
90                 }
91         },
92
93         handle: function(event) {
94                 if ( typeof jQuery == "undefined" ) return false;
95
96                 event = jQuery.event.fix( event || window.event || {} ); // Empty object is for triggered events with no data
97
98                 // returned undefined or false
99                 var returnValue;
100
101                 var c = this.events[event.type];
102
103                 var args = [].slice.call( arguments, 1 );
104                 args.unshift( event );
105
106                 for ( var j in c ) {
107                         // Pass in a reference to the handler function itself
108                         // So that we can later remove it
109                         args[0].handler = c[j];
110                         args[0].data = c[j].data;
111
112                         if ( c[j].apply( this, args ) === false ) {
113                                 event.preventDefault();
114                                 event.stopPropagation();
115                                 returnValue = false;
116                         }
117                 }
118
119                 // Clean up added properties in IE to prevent memory leak
120                 if (jQuery.browser.msie) event.target = event.preventDefault = event.stopPropagation = event.handler = event.data = null;
121
122                 return returnValue;
123         },
124
125         fix: function(event) {
126                 // Fix target property, if necessary
127                 if ( !event.target && event.srcElement )
128                         event.target = event.srcElement;
129
130                 // Calculate pageX/Y if missing and clientX/Y available
131                 if ( typeof event.pageX == "undefined" && typeof event.clientX != "undefined" ) {
132                         var e = document.documentElement, b = document.body;
133                         event.pageX = event.clientX + (e.scrollLeft || b.scrollLeft);
134                         event.pageY = event.clientY + (e.scrollTop || b.scrollTop);
135                 }
136                                 
137                 // Check safari and if target is a textnode
138                 if ( jQuery.browser.safari && event.target.nodeType == 3 ) {
139                         // target is readonly, clone the event object
140                         event = jQuery.extend({}, event);
141                         // get parentnode from textnode
142                         event.target = event.target.parentNode;
143                 }
144                 
145                 // fix preventDefault and stopPropagation
146                 if (!event.preventDefault) {
147                         event.preventDefault = function() {
148                                 this.returnValue = false;
149                         };
150                 }
151                         
152                 if (!event.stopPropagation) {
153                         event.stopPropagation = function() {
154                                 this.cancelBubble = true;
155                         };
156                 }
157                         
158                 return event;
159         }
160 };
161
162 jQuery.fn.extend({
163
164         /**
165          * Binds a handler to a particular event (like click) for each matched element.
166          * The event handler is passed an event object that you can use to prevent
167          * default behaviour. To stop both default action and event bubbling, your handler
168          * has to return false.
169          *
170          * In most cases, you can define your event handlers as anonymous functions
171          * (see first example). In cases where that is not possible, you can pass additional
172          * data as the second paramter (and the handler function as the third), see 
173          * second example.
174          *
175          * @example $("p").bind( "click", function() {
176          *   alert( $(this).text() );
177          * } )
178          * @before <p>Hello</p>
179          * @result alert("Hello")
180          *
181          * @example var handler = function(event) {
182          *   alert(event.data.foo);
183          * };
184          * $("p").bind( "click", {foo: "bar"}, handler)
185          * @result alert("bar")
186          * @desc Pass some additional data to the event handler.
187          *
188          * @example $("form").bind( "submit", function() { return false; } )
189          * @desc Cancel a default action and prevent it from bubbling by returning false
190          * from your function.
191          *
192          * @example $("form").bind( "submit", function(event) {
193          *   event.preventDefault();
194          * } );
195          * @desc Cancel only the default action by using the preventDefault method.
196          *
197          *
198          * @example $("form").bind( "submit", function(event) {
199          *   event.stopPropagation();
200          * } )
201          * @desc Stop only an event from bubbling by using the stopPropagation method.
202          *
203          * @name bind
204          * @type jQuery
205          * @param String type An event type
206          * @param Object data (optional) Additional data passed to the event handler as event.data
207          * @param Function fn A function to bind to the event on each of the set of matched elements
208          * @cat Events
209          */
210         bind: function( type, data, fn ) {
211                 return this.each(function(){
212                         jQuery.event.add( this, type, fn || data, data );
213                 });
214         },
215         
216         /**
217          * Binds a handler to a particular event (like click) for each matched element.
218          * The handler is executed only once for each element. Otherwise, the same rules
219          * as described in bind() apply.
220          The event handler is passed an event object that you can use to prevent
221          * default behaviour. To stop both default action and event bubbling, your handler
222          * has to return false.
223          *
224          * In most cases, you can define your event handlers as anonymous functions
225          * (see first example). In cases where that is not possible, you can pass additional
226          * data as the second paramter (and the handler function as the third), see 
227          * second example.
228          *
229          * @example $("p").one( "click", function() {
230          *   alert( $(this).text() );
231          * } )
232          * @before <p>Hello</p>
233          * @result alert("Hello")
234          *
235          * @name one
236          * @type jQuery
237          * @param String type An event type
238          * @param Object data (optional) Additional data passed to the event handler as event.data
239          * @param Function fn A function to bind to the event on each of the set of matched elements
240          * @cat Events
241          */
242         one: function( type, data, fn ) {
243                 return this.each(function(){
244                         jQuery.event.add( this, type, function(event) {
245                                 jQuery(this).unbind(event);
246                                 return (fn || data).apply( this, arguments);
247                         }, data);
248                 });
249         },
250
251         /**
252          * The opposite of bind, removes a bound event from each of the matched
253          * elements. You must pass the identical function that was used in the original
254          * bind method.
255          *
256          * @example $("p").unbind( "click", function() { alert("Hello"); } )
257          * @before <p onclick="alert('Hello');">Hello</p>
258          * @result [ <p>Hello</p> ]
259          *
260          * @name unbind
261          * @type jQuery
262          * @param String type An event type
263          * @param Function fn A function to unbind from the event on each of the set of matched elements
264          * @cat Events
265          */
266
267         /**
268          * Removes all bound events of a particular type from each of the matched
269          * elements.
270          *
271          * @example $("p").unbind( "click" )
272          * @before <p onclick="alert('Hello');">Hello</p>
273          * @result [ <p>Hello</p> ]
274          *
275          * @name unbind
276          * @type jQuery
277          * @param String type An event type
278          * @cat Events
279          */
280
281         /**
282          * Removes all bound events from each of the matched elements.
283          *
284          * @example $("p").unbind()
285          * @before <p onclick="alert('Hello');">Hello</p>
286          * @result [ <p>Hello</p> ]
287          *
288          * @name unbind
289          * @type jQuery
290          * @cat Events
291          */
292         unbind: function( type, fn ) {
293                 return this.each(function(){
294                         jQuery.event.remove( this, type, fn );
295                 });
296         },
297
298         /**
299          * Trigger a type of event on every matched element.
300          *
301          * @example $("p").trigger("click")
302          * @before <p click="alert('hello')">Hello</p>
303          * @result alert('hello')
304          *
305          * @name trigger
306          * @type jQuery
307          * @param String type An event type to trigger.
308          * @cat Events
309          */
310         trigger: function( type, data ) {
311                 return this.each(function(){
312                         jQuery.event.trigger( type, data, this );
313                 });
314         },
315
316         // We're overriding the old toggle function, so
317         // remember it for later
318         _toggle: jQuery.fn.toggle,
319         
320         /**
321          * Toggle between two function calls every other click.
322          * Whenever a matched element is clicked, the first specified function 
323          * is fired, when clicked again, the second is fired. All subsequent 
324          * clicks continue to rotate through the two functions.
325          *
326          * Use unbind("click") to remove.
327          *
328          * @example $("p").toggle(function(){
329          *   $(this).addClass("selected");
330          * },function(){
331          *   $(this).removeClass("selected");
332          * });
333          * 
334          * @name toggle
335          * @type jQuery
336          * @param Function even The function to execute on every even click.
337          * @param Function odd The function to execute on every odd click.
338          * @cat Events
339          */
340         toggle: function() {
341                 // save reference to arguments for access in closure
342                 var a = arguments;
343                 return typeof a[0] == "function" && typeof a[1] == "function" ? this.click(function(e) {
344                         // Figure out which function to execute
345                         this.lastToggle = this.lastToggle == 0 ? 1 : 0;
346                         
347                         // Make sure that clicks stop
348                         e.preventDefault();
349                         
350                         // and execute the function
351                         return a[this.lastToggle].apply( this, [e] ) || false;
352                 }) :
353                 
354                 // Otherwise, execute the old toggle function
355                 this._toggle.apply( this, arguments );
356         },
357         
358         /**
359          * A method for simulating hovering (moving the mouse on, and off,
360          * an object). This is a custom method which provides an 'in' to a 
361          * frequent task.
362          *
363          * Whenever the mouse cursor is moved over a matched 
364          * element, the first specified function is fired. Whenever the mouse 
365          * moves off of the element, the second specified function fires. 
366          * Additionally, checks are in place to see if the mouse is still within 
367          * the specified element itself (for example, an image inside of a div), 
368          * and if it is, it will continue to 'hover', and not move out 
369          * (a common error in using a mouseout event handler).
370          *
371          * @example $("p").hover(function(){
372          *   $(this).addClass("over");
373          * },function(){
374          *   $(this).addClass("out");
375          * });
376          *
377          * @name hover
378          * @type jQuery
379          * @param Function over The function to fire whenever the mouse is moved over a matched element.
380          * @param Function out The function to fire whenever the mouse is moved off of a matched element.
381          * @cat Events
382          */
383         hover: function(f,g) {
384                 
385                 // A private function for haandling mouse 'hovering'
386                 function handleHover(e) {
387                         // Check if mouse(over|out) are still within the same parent element
388                         var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
389         
390                         // Traverse up the tree
391                         while ( p && p != this ) try { p = p.parentNode } catch(e) { p = this; };
392                         
393                         // If we actually just moused on to a sub-element, ignore it
394                         if ( p == this ) return false;
395                         
396                         // Execute the right function
397                         return (e.type == "mouseover" ? f : g).apply(this, [e]);
398                 }
399                 
400                 // Bind the function to the two event listeners
401                 return this.mouseover(handleHover).mouseout(handleHover);
402         },
403         
404         /**
405          * Bind a function to be executed whenever the DOM is ready to be
406          * traversed and manipulated. This is probably the most important 
407          * function included in the event module, as it can greatly improve
408          * the response times of your web applications.
409          *
410          * In a nutshell, this is a solid replacement for using window.onload, 
411          * and attaching a function to that. By using this method, your bound Function 
412          * will be called the instant the DOM is ready to be read and manipulated, 
413          * which is exactly what 99.99% of all Javascript code needs to run.
414          * 
415          * Please ensure you have no code in your &lt;body&gt; onload event handler, 
416          * otherwise $(document).ready() may not fire.
417          *
418          * You can have as many $(document).ready events on your page as you like.
419          * The functions are then executed in the order they were added.
420          *
421          * @example $(document).ready(function(){ Your code here... });
422          *
423          * @name ready
424          * @type jQuery
425          * @param Function fn The function to be executed when the DOM is ready.
426          * @cat Events
427          */
428         ready: function(f) {
429                 // If the DOM is already ready
430                 if ( jQuery.isReady )
431                         // Execute the function immediately
432                         f.apply( document );
433                         
434                 // Otherwise, remember the function for later
435                 else {
436                         // Add the function to the wait list
437                         jQuery.readyList.push( f );
438                 }
439         
440                 return this;
441         }
442 });
443
444 jQuery.extend({
445         /*
446          * All the code that makes DOM Ready work nicely.
447          */
448         isReady: false,
449         readyList: [],
450         
451         // Handle when the DOM is ready
452         ready: function() {
453                 // Make sure that the DOM is not already loaded
454                 if ( !jQuery.isReady ) {
455                         // Remember that the DOM is ready
456                         jQuery.isReady = true;
457                         
458                         // If there are functions bound, to execute
459                         if ( jQuery.readyList ) {
460                                 // Execute all of them
461                                 for ( var i = 0; i < jQuery.readyList.length; i++ )
462                                         jQuery.readyList[i].apply( document );
463                                 
464                                 // Reset the list of functions
465                                 jQuery.readyList = null;
466                         }
467                         // Remove event lisenter to avoid memory leak
468                         if ( jQuery.browser.mozilla || jQuery.browser.opera )
469                                 document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
470                 }
471         }
472 });
473
474 new function(){
475
476                 /**
477                  * Bind a function to the scroll event of each matched element.
478                  *
479                  * @example $("p").scroll( function() { alert("Hello"); } );
480                  * @before <p>Hello</p>
481                  * @result <p onscroll="alert('Hello');">Hello</p>
482                  *
483                  * @name scroll
484                  * @type jQuery
485                  * @param Function fn A function to bind to the scroll event on each of the matched elements.
486                  * @cat Events/Browser
487                  */
488
489                 /**
490                  * Trigger the scroll event of each matched element. This causes all of the functions
491                  * that have been bound to thet scroll event to be executed.
492                  *
493                  * @example $("p").scroll();
494                  * @before <p onscroll="alert('Hello');">Hello</p>
495                  * @result alert('Hello');
496                  *
497                  * @name scroll
498                  * @type jQuery
499                  * @cat Events/Browser
500                  */
501
502                 /**
503                  * Bind a function to the submit event of each matched element.
504                  *
505                  * @example $("#myform").submit( function() {
506                  *   return $("input", this).val().length > 0;
507                  * } );
508                  * @before <form id="myform"><input /></form>
509                  * @desc Prevents the form submission when the input has no value entered.
510                  *
511                  * @name submit
512                  * @type jQuery
513                  * @param Function fn A function to bind to the submit event on each of the matched elements.
514                  * @cat Events/Form
515                  */
516
517                 /**
518                  * Trigger the submit event of each matched element. This causes all of the functions
519                  * that have been bound to thet submit event to be executed.
520                  *
521                  * Note: This does not execute the submit method of the form element! If you need to
522                  * submit the form via code, you have to use the DOM method, eg. $("form")[0].submit();
523                  *
524                  * @example $("form").submit();
525                  * @desc Triggers all submit events registered for forms, but does not submit the form
526                  *
527                  * @name submit
528                  * @type jQuery
529                  * @cat Events/Form
530                  */
531
532                 /**
533                  * Bind a function to the focus event of each matched element.
534                  *
535                  * @example $("p").focus( function() { alert("Hello"); } );
536                  * @before <p>Hello</p>
537                  * @result <p onfocus="alert('Hello');">Hello</p>
538                  *
539                  * @name focus
540                  * @type jQuery
541                  * @param Function fn A function to bind to the focus event on each of the matched elements.
542                  * @cat Events/UI
543                  */
544
545                 /**
546                  * Trigger the focus event of each matched element. This causes all of the functions
547                  * that have been bound to thet focus event to be executed.
548                  *
549                  * Note: This does not execute the focus method of the underlying elements! If you need to
550                  * focus an element via code, you have to use the DOM method, eg. $("#myinput")[0].focus();
551                  *
552                  * @example $("p").focus();
553                  * @before <p onfocus="alert('Hello');">Hello</p>
554                  * @result alert('Hello');
555                  *
556                  * @name focus
557                  * @type jQuery
558                  * @cat Events/UI
559                  */
560
561                 /**
562                  * Bind a function to the keydown event of each matched element.
563                  *
564                  * @example $("p").keydown( function() { alert("Hello"); } );
565                  * @before <p>Hello</p>
566                  * @result <p onkeydown="alert('Hello');">Hello</p>
567                  *
568                  * @name keydown
569                  * @type jQuery
570                  * @param Function fn A function to bind to the keydown event on each of the matched elements.
571                  * @cat Events/Keyboard
572                  */
573
574                 /**
575                  * Trigger the keydown event of each matched element. This causes all of the functions
576                  * that have been bound to thet keydown event to be executed.
577                  *
578                  * @example $("p").keydown();
579                  * @before <p onkeydown="alert('Hello');">Hello</p>
580                  * @result alert('Hello');
581                  *
582                  * @name keydown
583                  * @type jQuery
584                  * @cat Events/Keyboard
585                  */
586
587                 /**
588                  * Bind a function to the dblclick event of each matched element.
589                  *
590                  * @example $("p").dblclick( function() { alert("Hello"); } );
591                  * @before <p>Hello</p>
592                  * @result <p ondblclick="alert('Hello');">Hello</p>
593                  *
594                  * @name dblclick
595                  * @type jQuery
596                  * @param Function fn A function to bind to the dblclick event on each of the matched elements.
597                  * @cat Events/Mouse
598                  */
599
600                 /**
601                  * Trigger the dblclick event of each matched element. This causes all of the functions
602                  * that have been bound to thet dblclick event to be executed.
603                  *
604                  * @example $("p").dblclick();
605                  * @before <p ondblclick="alert('Hello');">Hello</p>
606                  * @result alert('Hello');
607                  *
608                  * @name dblclick
609                  * @type jQuery
610                  * @cat Events/Mouse
611                  */
612
613                 /**
614                  * Bind a function to the keypress event of each matched element.
615                  *
616                  * @example $("p").keypress( function() { alert("Hello"); } );
617                  * @before <p>Hello</p>
618                  * @result <p onkeypress="alert('Hello');">Hello</p>
619                  *
620                  * @name keypress
621                  * @type jQuery
622                  * @param Function fn A function to bind to the keypress event on each of the matched elements.
623                  * @cat Events/Keyboard
624                  */
625
626                 /**
627                  * Trigger the keypress event of each matched element. This causes all of the functions
628                  * that have been bound to thet keypress event to be executed.
629                  *
630                  * @example $("p").keypress();
631                  * @before <p onkeypress="alert('Hello');">Hello</p>
632                  * @result alert('Hello');
633                  *
634                  * @name keypress
635                  * @type jQuery
636                  * @cat Events/Keyboard
637                  */
638
639                 /**
640                  * Bind a function to the error event of each matched element.
641                  *
642                  * @example $("p").error( function() { alert("Hello"); } );
643                  * @before <p>Hello</p>
644                  * @result <p onerror="alert('Hello');">Hello</p>
645                  *
646                  * @name error
647                  * @type jQuery
648                  * @param Function fn A function to bind to the error event on each of the matched elements.
649                  * @cat Events/Browser
650                  */
651
652                 /**
653                  * Trigger the error event of each matched element. This causes all of the functions
654                  * that have been bound to thet error event to be executed.
655                  *
656                  * @example $("p").error();
657                  * @before <p onerror="alert('Hello');">Hello</p>
658                  * @result alert('Hello');
659                  *
660                  * @name error
661                  * @type jQuery
662                  * @cat Events/Browser
663                  */
664
665                 /**
666                  * Bind a function to the blur event of each matched element.
667                  *
668                  * @example $("p").blur( function() { alert("Hello"); } );
669                  * @before <p>Hello</p>
670                  * @result <p onblur="alert('Hello');">Hello</p>
671                  *
672                  * @name blur
673                  * @type jQuery
674                  * @param Function fn A function to bind to the blur event on each of the matched elements.
675                  * @cat Events/UI
676                  */
677
678                 /**
679                  * Trigger the blur event of each matched element. This causes all of the functions
680                  * that have been bound to thet blur event to be executed.
681                  *
682                  * Note: This does not execute the blur method of the underlying elements! If you need to
683                  * blur an element via code, you have to use the DOM method, eg. $("#myinput")[0].blur();
684                  *
685                  * @example $("p").blur();
686                  * @before <p onblur="alert('Hello');">Hello</p>
687                  * @result alert('Hello');
688                  *
689                  * @name blur
690                  * @type jQuery
691                  * @cat Events/UI
692                  */
693
694                 /**
695                  * Bind a function to the load event of each matched element.
696                  *
697                  * @example $("p").load( function() { alert("Hello"); } );
698                  * @before <p>Hello</p>
699                  * @result <p onload="alert('Hello');">Hello</p>
700                  *
701                  * @name load
702                  * @type jQuery
703                  * @param Function fn A function to bind to the load event on each of the matched elements.
704                  * @cat Events/Browser
705                  */
706
707                 /**
708                  * Trigger the load event of each matched element. This causes all of the functions
709                  * that have been bound to thet load event to be executed.
710                  *
711                  * Marked as private: Calling load() without arguments throws exception because the ajax load
712                  * does not handle it.
713                  *
714                  * @example $("p").load();
715                  * @before <p onload="alert('Hello');">Hello</p>
716                  * @result alert('Hello');
717                  *
718                  * @name load
719                  * @private
720                  * @type jQuery
721                  * @cat Events/Browser
722                  */
723
724                 /**
725                  * Bind a function to the select event of each matched element.
726                  *
727                  * @example $("p").select( function() { alert("Hello"); } );
728                  * @before <p>Hello</p>
729                  * @result <p onselect="alert('Hello');">Hello</p>
730                  *
731                  * @name select
732                  * @type jQuery
733                  * @param Function fn A function to bind to the select event on each of the matched elements.
734                  * @cat Events/Form
735                  */
736
737                 /**
738                  * Trigger the select event of each matched element. This causes all of the functions
739                  * that have been bound to thet select event to be executed.
740                  *
741                  * @example $("p").select();
742                  * @before <p onselect="alert('Hello');">Hello</p>
743                  * @result alert('Hello');
744                  *
745                  * @name select
746                  * @type jQuery
747                  * @cat Events/Form
748                  */
749
750                 /**
751                  * Bind a function to the mouseup event of each matched element.
752                  *
753                  * @example $("p").mouseup( function() { alert("Hello"); } );
754                  * @before <p>Hello</p>
755                  * @result <p onmouseup="alert('Hello');">Hello</p>
756                  *
757                  * @name mouseup
758                  * @type jQuery
759                  * @param Function fn A function to bind to the mouseup event on each of the matched elements.
760                  * @cat Events/Mouse
761                  */
762
763                 /**
764                  * Trigger the mouseup event of each matched element. This causes all of the functions
765                  * that have been bound to thet mouseup event to be executed.
766                  *
767                  * @example $("p").mouseup();
768                  * @before <p onmouseup="alert('Hello');">Hello</p>
769                  * @result alert('Hello');
770                  *
771                  * @name mouseup
772                  * @type jQuery
773                  * @cat Events/Mouse
774                  */
775
776                 /**
777                  * Bind a function to the unload event of each matched element.
778                  *
779                  * @example $("p").unload( function() { alert("Hello"); } );
780                  * @before <p>Hello</p>
781                  * @result <p onunload="alert('Hello');">Hello</p>
782                  *
783                  * @name unload
784                  * @type jQuery
785                  * @param Function fn A function to bind to the unload event on each of the matched elements.
786                  * @cat Events/Browser
787                  */
788
789                 /**
790                  * Trigger the unload event of each matched element. This causes all of the functions
791                  * that have been bound to thet unload event to be executed.
792                  *
793                  * @example $("p").unload();
794                  * @before <p onunload="alert('Hello');">Hello</p>
795                  * @result alert('Hello');
796                  *
797                  * @name unload
798                  * @type jQuery
799                  * @cat Events/Browser
800                  */
801
802                 /**
803                  * Bind a function to the change event of each matched element.
804                  *
805                  * @example $("p").change( function() { alert("Hello"); } );
806                  * @before <p>Hello</p>
807                  * @result <p onchange="alert('Hello');">Hello</p>
808                  *
809                  * @name change
810                  * @type jQuery
811                  * @param Function fn A function to bind to the change event on each of the matched elements.
812                  * @cat Events/Form
813                  */
814
815                 /**
816                  * Trigger the change event of each matched element. This causes all of the functions
817                  * that have been bound to thet change event to be executed.
818                  *
819                  * @example $("p").change();
820                  * @before <p onchange="alert('Hello');">Hello</p>
821                  * @result alert('Hello');
822                  *
823                  * @name change
824                  * @type jQuery
825                  * @cat Events/Form
826                  */
827
828                 /**
829                  * Bind a function to the mouseout event of each matched element.
830                  *
831                  * @example $("p").mouseout( function() { alert("Hello"); } );
832                  * @before <p>Hello</p>
833                  * @result <p onmouseout="alert('Hello');">Hello</p>
834                  *
835                  * @name mouseout
836                  * @type jQuery
837                  * @param Function fn A function to bind to the mouseout event on each of the matched elements.
838                  * @cat Events/Mouse
839                  */
840
841                 /**
842                  * Trigger the mouseout event of each matched element. This causes all of the functions
843                  * that have been bound to thet mouseout event to be executed.
844                  *
845                  * @example $("p").mouseout();
846                  * @before <p onmouseout="alert('Hello');">Hello</p>
847                  * @result alert('Hello');
848                  *
849                  * @name mouseout
850                  * @type jQuery
851                  * @cat Events/Mouse
852                  */
853
854                 /**
855                  * Bind a function to the keyup event of each matched element.
856                  *
857                  * @example $("p").keyup( function() { alert("Hello"); } );
858                  * @before <p>Hello</p>
859                  * @result <p onkeyup="alert('Hello');">Hello</p>
860                  *
861                  * @name keyup
862                  * @type jQuery
863                  * @param Function fn A function to bind to the keyup event on each of the matched elements.
864                  * @cat Events/Keyboard
865                  */
866
867                 /**
868                  * Trigger the keyup event of each matched element. This causes all of the functions
869                  * that have been bound to thet keyup event to be executed.
870                  *
871                  * @example $("p").keyup();
872                  * @before <p onkeyup="alert('Hello');">Hello</p>
873                  * @result alert('Hello');
874                  *
875                  * @name keyup
876                  * @type jQuery
877                  * @cat Events/Keyboard
878                  */
879
880                 /**
881                  * Bind a function to the click event of each matched element.
882                  *
883                  * @example $("p").click( function() { alert("Hello"); } );
884                  * @before <p>Hello</p>
885                  * @result <p onclick="alert('Hello');">Hello</p>
886                  *
887                  * @name click
888                  * @type jQuery
889                  * @param Function fn A function to bind to the click event on each of the matched elements.
890                  * @cat Events/Mouse
891                  */
892
893                 /**
894                  * Trigger the click event of each matched element. This causes all of the functions
895                  * that have been bound to thet click event to be executed.
896                  *
897                  * @example $("p").click();
898                  * @before <p onclick="alert('Hello');">Hello</p>
899                  * @result alert('Hello');
900                  *
901                  * @name click
902                  * @type jQuery
903                  * @cat Events/Mouse
904                  */
905
906                 /**
907                  * Bind a function to the resize event of each matched element.
908                  *
909                  * @example $("p").resize( function() { alert("Hello"); } );
910                  * @before <p>Hello</p>
911                  * @result <p onresize="alert('Hello');">Hello</p>
912                  *
913                  * @name resize
914                  * @type jQuery
915                  * @param Function fn A function to bind to the resize event on each of the matched elements.
916                  * @cat Events/Browser
917                  */
918
919                 /**
920                  * Trigger the resize event of each matched element. This causes all of the functions
921                  * that have been bound to thet resize event to be executed.
922                  *
923                  * @example $("p").resize();
924                  * @before <p onresize="alert('Hello');">Hello</p>
925                  * @result alert('Hello');
926                  *
927                  * @name resize
928                  * @type jQuery
929                  * @cat Events/Browser
930                  */
931
932                 /**
933                  * Bind a function to the mousemove event of each matched element.
934                  *
935                  * @example $("p").mousemove( function() { alert("Hello"); } );
936                  * @before <p>Hello</p>
937                  * @result <p onmousemove="alert('Hello');">Hello</p>
938                  *
939                  * @name mousemove
940                  * @type jQuery
941                  * @param Function fn A function to bind to the mousemove event on each of the matched elements.
942                  * @cat Events/Mouse
943                  */
944
945                 /**
946                  * Trigger the mousemove event of each matched element. This causes all of the functions
947                  * that have been bound to thet mousemove event to be executed.
948                  *
949                  * @example $("p").mousemove();
950                  * @before <p onmousemove="alert('Hello');">Hello</p>
951                  * @result alert('Hello');
952                  *
953                  * @name mousemove
954                  * @type jQuery
955                  * @cat Events/Mouse
956                  */
957
958                 /**
959                  * Bind a function to the mousedown event of each matched element.
960                  *
961                  * @example $("p").mousedown( function() { alert("Hello"); } );
962                  * @before <p>Hello</p>
963                  * @result <p onmousedown="alert('Hello');">Hello</p>
964                  *
965                  * @name mousedown
966                  * @type jQuery
967                  * @param Function fn A function to bind to the mousedown event on each of the matched elements.
968                  * @cat Events/Mouse
969                  */
970
971                 /**
972                  * Trigger the mousedown event of each matched element. This causes all of the functions
973                  * that have been bound to thet mousedown event to be executed.
974                  *
975                  * @example $("p").mousedown();
976                  * @before <p onmousedown="alert('Hello');">Hello</p>
977                  * @result alert('Hello');
978                  *
979                  * @name mousedown
980                  * @type jQuery
981                  * @cat Events/Mouse
982                  */
983                  
984                 /**
985                  * Bind a function to the mouseover event of each matched element.
986                  *
987                  * @example $("p").mouseover( function() { alert("Hello"); } );
988                  * @before <p>Hello</p>
989                  * @result <p onmouseover="alert('Hello');">Hello</p>
990                  *
991                  * @name mouseover
992                  * @type jQuery
993                  * @param Function fn A function to bind to the mousedown event on each of the matched elements.
994                  * @cat Events/Mouse
995                  */
996
997                 /**
998                  * Trigger the mouseover event of each matched element. This causes all of the functions
999                  * that have been bound to thet mousedown event to be executed.
1000                  *
1001                  * @example $("p").mouseover();
1002                  * @before <p onmouseover="alert('Hello');">Hello</p>
1003                  * @result alert('Hello');
1004                  *
1005                  * @name mouseover
1006                  * @type jQuery
1007                  * @cat Events/Mouse
1008                  */
1009
1010         var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
1011                 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 
1012                 "submit,keydown,keypress,keyup,error").split(",");
1013
1014         // Go through all the event names, but make sure that
1015         // it is enclosed properly
1016         for ( var i = 0; i < e.length; i++ ) new function(){
1017                         
1018                 var o = e[i];
1019                 
1020                 // Handle event binding
1021                 jQuery.fn[o] = function(f){
1022                         return f ? this.bind(o, f) : this.trigger(o);
1023                 };
1024                 
1025                 // Handle event unbinding
1026                 // TODO remove
1027                 jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); };
1028                 
1029                 // Finally, handle events that only fire once
1030                 // TODO remove
1031                 jQuery.fn["one"+o] = function(f){
1032                         // save cloned reference to this
1033                         var element = jQuery(this);
1034                         var handler = function() {
1035                                 // unbind itself when executed
1036                                 element.unbind(o, handler);
1037                                 element = null;
1038                                 // apply original handler with the same arguments
1039                                 return f.apply(this, arguments);
1040                         };
1041                         return this.bind(o, handler);
1042                 };
1043                         
1044         };
1045         
1046         // If Mozilla is used
1047         if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
1048                 // Use the handy event callback
1049                 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
1050         
1051         // If IE is used, use the excellent hack by Matthias Miller
1052         // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
1053         } else if ( jQuery.browser.msie ) {
1054         
1055                 // Only works if you document.write() it
1056                 document.write("<scr" + "ipt id=__ie_init defer=true " + 
1057                         "src=//:><\/script>");
1058         
1059                 // Use the defer script hack
1060                 var script = document.getElementById("__ie_init");
1061                 if (script) // script does not exist if jQuery is loaded dynamically
1062                         script.onreadystatechange = function() {
1063                                 if ( this.readyState != "complete" ) return;
1064                                 this.parentNode.removeChild( this );
1065                                 jQuery.ready();
1066                         };
1067         
1068                 // Clear from memory
1069                 script = null;
1070         
1071         // If Safari  is used
1072         } else if ( jQuery.browser.safari ) {
1073                 // Continually check to see if the document.readyState is valid
1074                 jQuery.safariTimer = setInterval(function(){
1075                         // loaded and complete are both valid states
1076                         if ( document.readyState == "loaded" || 
1077                                 document.readyState == "complete" ) {
1078         
1079                                 // If either one are found, remove the timer
1080                                 clearInterval( jQuery.safariTimer );
1081                                 jQuery.safariTimer = null;
1082         
1083                                 // and execute any waiting functions
1084                                 jQuery.ready();
1085                         }
1086                 }, 10);
1087         } 
1088
1089         // A fallback to window.onload, that will always work
1090         jQuery.event.add( window, "load", jQuery.ready );
1091         
1092 };
1093
1094 // Clean up after IE to avoid memory leaks
1095 if (jQuery.browser.msie) jQuery(window).unload(function() {
1096         var event = jQuery.event, global = event.global;
1097         for (var type in global) {
1098                 var els = global[type], i = els.length;
1099                 if (i>0) do if (type != 'unload') event.remove(els[i-1], type); while (--i);
1100         }
1101 });