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