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