1 var rnamespaces = /\.(.*)$/,
2 fcleanup = function( nm ) {
3 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
9 * A number of helper functions used for managing events.
10 * Many of the ideas behind this code originated from
11 * Dean Edwards' addEvent library.
15 // Bind an event to an element
16 // Original by Dean Edwards
17 add: function( elem, types, handler, data ) {
18 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
22 // For whatever reason, IE has trouble passing the window object
23 // around, causing it to be cloned in the process
24 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
28 if ( handler === false ) {
29 handler = returnFalse;
32 var handleObjIn, handleObj;
34 if ( handler.handler ) {
35 handleObjIn = handler;
36 handler = handleObjIn.handler;
39 // Make sure that the function being executed has a unique ID
40 if ( !handler.guid ) {
41 handler.guid = jQuery.guid++;
44 // Init the element's event structure
45 var elemData = jQuery.data( elem );
47 // If no elemData is found then we must be trying to bind to one of the
48 // banned noData elements
53 var events = elemData.events = elemData.events || {},
54 eventHandle = elemData.handle, eventHandle;
57 elemData.handle = eventHandle = function() {
58 // Handle the second event of a trigger and when
59 // an event is called after a page has unloaded
60 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
61 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
66 // Add elem as a property of the handle function
67 // This is to prevent a memory leak with non-native events in IE.
68 eventHandle.elem = elem;
70 // Handle multiple events separated by a space
71 // jQuery(...).bind("mouseover mouseout", fn);
72 types = types.split(" ");
74 var type, i = 0, namespaces;
76 while ( (type = types[ i++ ]) ) {
77 handleObj = handleObjIn ?
78 jQuery.extend({}, handleObjIn) :
79 { handler: handler, data: data };
81 // Namespaced event handlers
82 if ( type.indexOf(".") > -1 ) {
83 namespaces = type.split(".");
84 type = namespaces.shift();
85 handleObj.namespace = namespaces.slice(0).sort().join(".");
89 handleObj.namespace = "";
92 handleObj.type = type;
93 handleObj.guid = handler.guid;
95 // Get the current list of functions bound to this event
96 var handlers = events[ type ],
97 special = jQuery.event.special[ type ] || {};
99 // Init the event handler queue
101 handlers = events[ type ] = [];
103 // Check for a special event handler
104 // Only use addEventListener/attachEvent if the special
105 // events handler returns false
106 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
107 // Bind the global event handler to the element
108 if ( elem.addEventListener ) {
109 elem.addEventListener( type, eventHandle, false );
111 } else if ( elem.attachEvent ) {
112 elem.attachEvent( "on" + type, eventHandle );
118 special.add.call( elem, handleObj );
120 if ( !handleObj.handler.guid ) {
121 handleObj.handler.guid = handler.guid;
125 // Add the function to the element's handler list
126 handlers.push( handleObj );
128 // Keep track of which events have been used, for global triggering
129 jQuery.event.global[ type ] = true;
132 // Nullify elem to prevent memory leaks in IE
138 // Detach an event or set of events from an element
139 remove: function( elem, types, handler, pos ) {
140 // don't do events on text and comment nodes
141 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
145 if ( handler === false ) {
146 handler = returnFalse;
149 var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
150 elemData = jQuery.data( elem ),
151 events = elemData && elemData.events;
153 if ( !elemData || !events ) {
157 // types is actually an event object here
158 if ( types && types.type ) {
159 handler = types.handler;
163 // Unbind all events for the element
164 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
167 for ( type in events ) {
168 jQuery.event.remove( elem, type + types );
174 // Handle multiple events separated by a space
175 // jQuery(...).unbind("mouseover mouseout", fn);
176 types = types.split(" ");
178 while ( (type = types[ i++ ]) ) {
181 all = type.indexOf(".") < 0;
185 // Namespaced event handlers
186 namespaces = type.split(".");
187 type = namespaces.shift();
189 namespace = new RegExp("(^|\\.)" +
190 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
193 eventType = events[ type ];
200 for ( var j = 0; j < eventType.length; j++ ) {
201 handleObj = eventType[ j ];
203 if ( all || namespace.test( handleObj.namespace ) ) {
204 jQuery.event.remove( elem, origType, handleObj.handler, j );
205 eventType.splice( j--, 1 );
212 special = jQuery.event.special[ type ] || {};
214 for ( var j = pos || 0; j < eventType.length; j++ ) {
215 handleObj = eventType[ j ];
217 if ( handler.guid === handleObj.guid ) {
218 // remove the given handler for the given type
219 if ( all || namespace.test( handleObj.namespace ) ) {
221 eventType.splice( j--, 1 );
224 if ( special.remove ) {
225 special.remove.call( elem, handleObj );
235 // remove generic event handler if no more handlers exist
236 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
237 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
238 removeEvent( elem, type, elemData.handle );
242 delete events[ type ];
246 // Remove the expando if it's no longer used
247 if ( jQuery.isEmptyObject( events ) ) {
248 var handle = elemData.handle;
253 delete elemData.events;
254 delete elemData.handle;
256 if ( jQuery.isEmptyObject( elemData ) ) {
257 jQuery.removeData( elem );
262 // bubbling is internal
263 trigger: function( event, data, elem /*, bubbling */ ) {
264 // Event object or event type
265 var type = event.type || event,
266 bubbling = arguments[3];
269 event = typeof event === "object" ?
270 // jQuery.Event object
271 event[expando] ? event :
273 jQuery.extend( jQuery.Event(type), event ) :
274 // Just the event type (string)
277 if ( type.indexOf("!") >= 0 ) {
278 event.type = type = type.slice(0, -1);
279 event.exclusive = true;
282 // Handle a global trigger
284 // Don't bubble custom events when global (to avoid too much overhead)
285 event.stopPropagation();
287 // Only trigger if we've ever bound an event for it
288 if ( jQuery.event.global[ type ] ) {
289 jQuery.each( jQuery.cache, function() {
290 if ( this.events && this.events[type] ) {
291 jQuery.event.trigger( event, data, this.handle.elem );
297 // Handle triggering a single element
299 // don't do events on text and comment nodes
300 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
304 // Clean up in case it is reused
305 event.result = undefined;
308 // Clone the incoming data, if any
309 data = jQuery.makeArray( data );
310 data.unshift( event );
313 event.currentTarget = elem;
315 // Trigger the event, it is assumed that "handle" is a function
316 var handle = jQuery.data( elem, "handle" );
318 handle.apply( elem, data );
321 var parent = elem.parentNode || elem.ownerDocument;
323 // Trigger an inline bound script
325 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
326 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
327 event.result = false;
331 // prevent IE from throwing an error for some elements with some event types, see #3533
334 if ( !event.isPropagationStopped() && parent ) {
335 jQuery.event.trigger( event, data, parent, true );
337 } else if ( !event.isDefaultPrevented() ) {
338 var target = event.target, old,
339 isClick = jQuery.nodeName(target, "a") && type === "click",
340 special = jQuery.event.special[ type ] || {};
342 if ( (!special._default || special._default.call( elem, event ) === false) &&
343 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
346 if ( target[ type ] ) {
347 // Make sure that we don't accidentally re-trigger the onFOO events
348 old = target[ "on" + type ];
351 target[ "on" + type ] = null;
354 jQuery.event.triggered = true;
358 // prevent IE from throwing an error for some elements with some event types, see #3533
362 target[ "on" + type ] = old;
365 jQuery.event.triggered = false;
370 handle: function( event ) {
371 var all, handlers, namespaces, namespace, events;
373 event = arguments[0] = jQuery.event.fix( event || window.event );
374 event.currentTarget = this;
376 // Namespaced event handlers
377 all = event.type.indexOf(".") < 0 && !event.exclusive;
380 namespaces = event.type.split(".");
381 event.type = namespaces.shift();
382 namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
385 events = jQuery.data(this, "events");
386 handlers = (events || {})[ event.type ];
388 if ( events && handlers ) {
389 // Clone the handlers to prevent manipulation
390 handlers = handlers.slice(0);
392 for ( var j = 0, l = handlers.length; j < l; j++ ) {
393 var handleObj = handlers[ j ];
395 // Filter the functions by class
396 if ( all || namespace.test( handleObj.namespace ) ) {
397 // Pass in a reference to the handler function itself
398 // So that we can later remove it
399 event.handler = handleObj.handler;
400 event.data = handleObj.data;
401 event.handleObj = handleObj;
403 var ret = handleObj.handler.apply( this, arguments );
405 if ( ret !== undefined ) {
407 if ( ret === false ) {
408 event.preventDefault();
409 event.stopPropagation();
413 if ( event.isImmediatePropagationStopped() ) {
423 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
425 fix: function( event ) {
426 if ( event[ expando ] ) {
430 // store a copy of the original event object
431 // and "clone" to set read-only properties
432 var originalEvent = event;
433 event = jQuery.Event( originalEvent );
435 for ( var i = this.props.length, prop; i; ) {
436 prop = this.props[ --i ];
437 event[ prop ] = originalEvent[ prop ];
440 // Fix target property, if necessary
441 if ( !event.target ) {
442 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
445 // check if target is a textnode (safari)
446 if ( event.target.nodeType === 3 ) {
447 event.target = event.target.parentNode;
450 // Add relatedTarget, if necessary
451 if ( !event.relatedTarget && event.fromElement ) {
452 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
455 // Calculate pageX/Y if missing and clientX/Y available
456 if ( event.pageX == null && event.clientX != null ) {
457 var doc = document.documentElement, body = document.body;
458 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
459 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
462 // Add which for key events
463 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
464 event.which = event.charCode || event.keyCode;
467 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
468 if ( !event.metaKey && event.ctrlKey ) {
469 event.metaKey = event.ctrlKey;
472 // Add which for click: 1 === left; 2 === middle; 3 === right
473 // Note: button is not normalized, so don't use it
474 if ( !event.which && event.button !== undefined ) {
475 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
481 // Deprecated, use jQuery.guid instead
484 // Deprecated, use jQuery.proxy instead
489 // Make sure the ready event is setup
490 setup: jQuery.bindReady,
491 teardown: jQuery.noop
495 add: function( handleObj ) {
496 jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
499 remove: function( handleObj ) {
501 type = handleObj.origType.replace(rnamespaces, "");
503 jQuery.each( jQuery.data(this, "events").live || [], function() {
504 if ( type === this.origType.replace(rnamespaces, "") ) {
511 jQuery.event.remove( this, handleObj.origType, liveHandler );
518 setup: function( data, namespaces, eventHandle ) {
519 // We only want to do this special case on windows
520 if ( this.setInterval ) {
521 this.onbeforeunload = eventHandle;
526 teardown: function( namespaces, eventHandle ) {
527 if ( this.onbeforeunload === eventHandle ) {
528 this.onbeforeunload = null;
535 var removeEvent = document.removeEventListener ?
536 function( elem, type, handle ) {
537 if ( elem.removeEventListener ) {
538 elem.removeEventListener( type, handle, false );
541 function( elem, type, handle ) {
542 if ( elem.detachEvent ) {
543 elem.detachEvent( "on" + type, handle );
547 jQuery.Event = function( src ) {
548 // Allow instantiation without the 'new' keyword
549 if ( !this.preventDefault ) {
550 return new jQuery.Event( src );
554 if ( src && src.type ) {
555 this.originalEvent = src;
556 this.type = src.type;
562 // timeStamp is buggy for some events on Firefox(#3843)
563 // So we won't rely on the native value
564 this.timeStamp = now();
567 this[ expando ] = true;
570 function returnFalse() {
573 function returnTrue() {
577 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
578 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
579 jQuery.Event.prototype = {
580 preventDefault: function() {
581 this.isDefaultPrevented = returnTrue;
583 var e = this.originalEvent;
588 // if preventDefault exists run it on the original event
589 if ( e.preventDefault ) {
592 // otherwise set the returnValue property of the original event to false (IE)
593 e.returnValue = false;
595 stopPropagation: function() {
596 this.isPropagationStopped = returnTrue;
598 var e = this.originalEvent;
602 // if stopPropagation exists run it on the original event
603 if ( e.stopPropagation ) {
606 // otherwise set the cancelBubble property of the original event to true (IE)
607 e.cancelBubble = true;
609 stopImmediatePropagation: function() {
610 this.isImmediatePropagationStopped = returnTrue;
611 this.stopPropagation();
613 isDefaultPrevented: returnFalse,
614 isPropagationStopped: returnFalse,
615 isImmediatePropagationStopped: returnFalse
618 // Checks if an event happened on an element within another element
619 // Used in jQuery.event.special.mouseenter and mouseleave handlers
620 var withinElement = function( event ) {
621 // Check if mouse(over|out) are still within the same parent element
622 var parent = event.relatedTarget;
624 // Firefox sometimes assigns relatedTarget a XUL element
625 // which we cannot access the parentNode property of
627 // Traverse up the tree
628 while ( parent && parent !== this ) {
629 parent = parent.parentNode;
632 if ( parent !== this ) {
633 // set the correct event type
634 event.type = event.data;
636 // handle event if we actually just moused on to a non sub-element
637 jQuery.event.handle.apply( this, arguments );
640 // assuming we've left the element since we most likely mousedover a xul element
644 // In case of event delegation, we only need to rename the event.type,
645 // liveHandler will take care of the rest.
646 delegate = function( event ) {
647 event.type = event.data;
648 jQuery.event.handle.apply( this, arguments );
651 // Create mouseenter and mouseleave events
653 mouseenter: "mouseover",
654 mouseleave: "mouseout"
655 }, function( orig, fix ) {
656 jQuery.event.special[ orig ] = {
657 setup: function( data ) {
658 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
660 teardown: function( data ) {
661 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
667 if ( !jQuery.support.submitBubbles ) {
669 jQuery.event.special.submit = {
670 setup: function( data, namespaces ) {
671 if ( this.nodeName.toLowerCase() !== "form" ) {
672 jQuery.event.add(this, "click.specialSubmit", function( e ) {
673 var elem = e.target, type = elem.type;
675 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
676 return trigger( "submit", this, arguments );
680 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
681 var elem = e.target, type = elem.type;
683 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
684 return trigger( "submit", this, arguments );
693 teardown: function( namespaces ) {
694 jQuery.event.remove( this, ".specialSubmit" );
700 // change delegation, happens here so we have bind.
701 if ( !jQuery.support.changeBubbles ) {
703 var formElems = /textarea|input|select/i,
707 getVal = function( elem ) {
708 var type = elem.type, val = elem.value;
710 if ( type === "radio" || type === "checkbox" ) {
713 } else if ( type === "select-multiple" ) {
714 val = elem.selectedIndex > -1 ?
715 jQuery.map( elem.options, function( elem ) {
716 return elem.selected;
720 } else if ( elem.nodeName.toLowerCase() === "select" ) {
721 val = elem.selectedIndex;
727 testChange = function testChange( e ) {
728 var elem = e.target, data, val;
730 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
734 data = jQuery.data( elem, "_change_data" );
737 // the current data will be also retrieved by beforeactivate
738 if ( e.type !== "focusout" || elem.type !== "radio" ) {
739 jQuery.data( elem, "_change_data", val );
742 if ( data === undefined || val === data ) {
746 if ( data != null || val ) {
748 return jQuery.event.trigger( e, arguments[1], elem );
752 jQuery.event.special.change = {
754 focusout: testChange,
756 click: function( e ) {
757 var elem = e.target, type = elem.type;
759 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
760 return testChange.call( this, e );
764 // Change has to be called before submit
765 // Keydown will be called before keypress, which is used in submit-event delegation
766 keydown: function( e ) {
767 var elem = e.target, type = elem.type;
769 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
770 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
771 type === "select-multiple" ) {
772 return testChange.call( this, e );
776 // Beforeactivate happens also before the previous element is blurred
777 // with this event you can't trigger a change event, but you can store
778 // information/focus[in] is not needed anymore
779 beforeactivate: function( e ) {
781 jQuery.data( elem, "_change_data", getVal(elem) );
785 setup: function( data, namespaces ) {
786 if ( this.type === "file" ) {
790 for ( var type in changeFilters ) {
791 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
794 return formElems.test( this.nodeName );
797 teardown: function( namespaces ) {
798 jQuery.event.remove( this, ".specialChange" );
800 return formElems.test( this.nodeName );
804 changeFilters = jQuery.event.special.change.filters;
807 function trigger( type, elem, args ) {
809 return jQuery.event.handle.apply( elem, args );
812 // Create "bubbling" focus and blur events
813 if ( document.addEventListener ) {
814 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
815 jQuery.event.special[ fix ] = {
817 this.addEventListener( orig, handler, true );
819 teardown: function() {
820 this.removeEventListener( orig, handler, true );
824 function handler( e ) {
825 e = jQuery.event.fix( e );
827 return jQuery.event.handle.call( this, e );
832 jQuery.each(["bind", "one"], function( i, name ) {
833 jQuery.fn[ name ] = function( type, data, fn ) {
834 // Handle object literals
835 if ( typeof type === "object" ) {
836 for ( var key in type ) {
837 this[ name ](key, data, type[key], fn);
842 if ( jQuery.isFunction( data ) || data === false ) {
847 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
848 jQuery( this ).unbind( event, handler );
849 return fn.apply( this, arguments );
852 if ( type === "unload" && name !== "one" ) {
853 this.one( type, data, fn );
856 for ( var i = 0, l = this.length; i < l; i++ ) {
857 jQuery.event.add( this[i], type, handler, data );
866 unbind: function( type, fn ) {
867 // Handle object literals
868 if ( typeof type === "object" && !type.preventDefault ) {
869 for ( var key in type ) {
870 this.unbind(key, type[key]);
874 for ( var i = 0, l = this.length; i < l; i++ ) {
875 jQuery.event.remove( this[i], type, fn );
882 delegate: function( selector, types, data, fn ) {
883 return this.live( types, data, fn, selector );
886 undelegate: function( selector, types, fn ) {
887 if ( arguments.length === 0 ) {
888 return this.unbind( "live" );
891 return this.die( types, null, fn, selector );
895 trigger: function( type, data ) {
896 return this.each(function() {
897 jQuery.event.trigger( type, data, this );
901 triggerHandler: function( type, data ) {
903 var event = jQuery.Event( type );
904 event.preventDefault();
905 event.stopPropagation();
906 jQuery.event.trigger( event, data, this[0] );
911 toggle: function( fn ) {
912 // Save reference to arguments for access in closure
913 var args = arguments, i = 1;
915 // link all the functions, so any of them can unbind this click handler
916 while ( i < args.length ) {
917 jQuery.proxy( fn, args[ i++ ] );
920 return this.click( jQuery.proxy( fn, function( event ) {
921 // Figure out which function to execute
922 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
923 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
925 // Make sure that clicks stop
926 event.preventDefault();
928 // and execute the function
929 return args[ lastToggle ].apply( this, arguments ) || false;
933 hover: function( fnOver, fnOut ) {
934 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
941 mouseenter: "mouseover",
942 mouseleave: "mouseout"
945 jQuery.each(["live", "die"], function( i, name ) {
946 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
947 var type, i = 0, match, namespaces, preType,
948 selector = origSelector || this.selector,
949 context = origSelector ? this : jQuery( this.context );
951 if ( jQuery.isFunction( data ) ) {
956 types = (types || "").split(" ");
958 while ( (type = types[ i++ ]) != null ) {
959 match = rnamespaces.exec( type );
963 namespaces = match[0];
964 type = type.replace( rnamespaces, "" );
967 if ( type === "hover" ) {
968 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
974 if ( type === "focus" || type === "blur" ) {
975 types.push( liveMap[ type ] + namespaces );
976 type = type + namespaces;
979 type = (liveMap[ type ] || type) + namespaces;
982 if ( name === "live" ) {
984 context.each(function(){
985 jQuery.event.add( this, liveConvert( type, selector ),
986 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
990 // unbind live handler
991 context.unbind( liveConvert( type, selector ), fn );
999 function liveHandler( event ) {
1000 var stop, maxLevel, elems = [], selectors = [],
1001 related, match, handleObj, elem, j, i, l, data, close,
1002 events = jQuery.data( this, "events" );
1004 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
1005 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1009 event.liveFired = this;
1011 var live = events.live.slice(0);
1013 for ( j = 0; j < live.length; j++ ) {
1014 handleObj = live[j];
1016 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1017 selectors.push( handleObj.selector );
1020 live.splice( j--, 1 );
1024 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1026 for ( i = 0, l = match.length; i < l; i++ ) {
1029 for ( j = 0; j < live.length; j++ ) {
1030 handleObj = live[j];
1032 if ( close.selector === handleObj.selector ) {
1036 // Those two events require additional checking
1037 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1038 event.type = handleObj.preType;
1039 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1042 if ( !related || related !== elem ) {
1043 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1049 for ( i = 0, l = elems.length; i < l; i++ ) {
1052 if ( maxLevel && match.level > maxLevel ) {
1056 event.currentTarget = match.elem;
1057 event.data = match.handleObj.data;
1058 event.handleObj = match.handleObj;
1060 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1062 if ( ret === false || event.isPropagationStopped() ) {
1063 maxLevel = match.level;
1065 if ( ret === false ) {
1074 function liveConvert( type, selector ) {
1075 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
1078 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1079 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1080 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1082 // Handle event binding
1083 jQuery.fn[ name ] = function( data, fn ) {
1084 if ( fn == undefined ) {
1089 return arguments.length > 0 ?
1090 this.bind( name, data, fn ) :
1091 this.trigger( name );
1094 if ( jQuery.attrFn ) {
1095 jQuery.attrFn[ name ] = true;
1099 // Prevent memory leaks in IE
1100 // Window isn't included so as not to unbind existing unload events
1102 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1103 if ( window.attachEvent && !window.addEventListener ) {
1104 window.attachEvent("onunload", function() {
1105 for ( var id in jQuery.cache ) {
1106 if ( jQuery.cache[ id ].handle ) {
1107 // Try/Catch is to handle iframes being unloaded, see #4280
1109 jQuery.event.remove( jQuery.cache[ id ].handle.elem );