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 var handleObjIn, handleObj;
30 if ( handler.handler ) {
31 handleObjIn = handler;
32 handler = handleObjIn.handler;
35 // Make sure that the function being executed has a unique ID
36 if ( !handler.guid ) {
37 handler.guid = jQuery.guid++;
40 // Init the element's event structure
41 var elemData = jQuery.data( elem );
43 // If no elemData is found then we must be trying to bind to one of the
44 // banned noData elements
49 var events = elemData.events = elemData.events || {},
50 eventHandle = elemData.handle, eventHandle;
53 elemData.handle = eventHandle = function() {
54 // Handle the second event of a trigger and when
55 // an event is called after a page has unloaded
56 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
57 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
62 // Add elem as a property of the handle function
63 // This is to prevent a memory leak with non-native events in IE.
64 eventHandle.elem = elem;
66 // Handle multiple events separated by a space
67 // jQuery(...).bind("mouseover mouseout", fn);
68 types = types.split(" ");
70 var type, i = 0, namespaces;
72 while ( (type = types[ i++ ]) ) {
73 handleObj = handleObjIn ?
74 jQuery.extend({}, handleObjIn) :
75 { handler: handler, data: data };
77 // Namespaced event handlers
78 if ( type.indexOf(".") > -1 ) {
79 namespaces = type.split(".");
80 type = namespaces.shift();
81 handleObj.namespace = namespaces.slice(0).sort().join(".");
85 handleObj.namespace = "";
88 handleObj.type = type;
89 handleObj.guid = handler.guid;
91 // Get the current list of functions bound to this event
92 var handlers = events[ type ],
93 special = jQuery.event.special[ type ] || {};
95 // Init the event handler queue
97 handlers = events[ type ] = [];
99 // Check for a special event handler
100 // Only use addEventListener/attachEvent if the special
101 // events handler returns false
102 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
103 // Bind the global event handler to the element
104 if ( elem.addEventListener ) {
105 elem.addEventListener( type, eventHandle, false );
107 } else if ( elem.attachEvent ) {
108 elem.attachEvent( "on" + type, eventHandle );
114 special.add.call( elem, handleObj );
116 if ( !handleObj.handler.guid ) {
117 handleObj.handler.guid = handler.guid;
121 // Add the function to the element's handler list
122 handlers.push( handleObj );
124 // Keep track of which events have been used, for global triggering
125 jQuery.event.global[ type ] = true;
128 // Nullify elem to prevent memory leaks in IE
134 // Detach an event or set of events from an element
135 remove: function( elem, types, handler, pos ) {
136 // don't do events on text and comment nodes
137 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
141 var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
142 elemData = jQuery.data( elem ),
143 events = elemData && elemData.events;
145 if ( !elemData || !events ) {
149 // types is actually an event object here
150 if ( types && types.type ) {
151 handler = types.handler;
155 // Unbind all events for the element
156 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
159 for ( type in events ) {
160 jQuery.event.remove( elem, type + types );
166 // Handle multiple events separated by a space
167 // jQuery(...).unbind("mouseover mouseout", fn);
168 types = types.split(" ");
170 while ( (type = types[ i++ ]) ) {
173 all = type.indexOf(".") < 0;
177 // Namespaced event handlers
178 namespaces = type.split(".");
179 type = namespaces.shift();
181 namespace = new RegExp("(^|\\.)" +
182 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
185 eventType = events[ type ];
192 for ( var j = 0; j < eventType.length; j++ ) {
193 handleObj = eventType[ j ];
195 if ( all || namespace.test( handleObj.namespace ) ) {
196 jQuery.event.remove( elem, origType, handleObj.handler, j );
197 eventType.splice( j--, 1 );
204 special = jQuery.event.special[ type ] || {};
206 for ( var j = pos || 0; j < eventType.length; j++ ) {
207 handleObj = eventType[ j ];
209 if ( handler.guid === handleObj.guid ) {
210 // remove the given handler for the given type
211 if ( all || namespace.test( handleObj.namespace ) ) {
213 eventType.splice( j--, 1 );
216 if ( special.remove ) {
217 special.remove.call( elem, handleObj );
227 // remove generic event handler if no more handlers exist
228 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
229 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
230 removeEvent( elem, type, elemData.handle );
234 delete events[ type ];
238 // Remove the expando if it's no longer used
239 if ( jQuery.isEmptyObject( events ) ) {
240 var handle = elemData.handle;
245 delete elemData.events;
246 delete elemData.handle;
248 if ( jQuery.isEmptyObject( elemData ) ) {
249 jQuery.removeData( elem );
254 // bubbling is internal
255 trigger: function( event, data, elem /*, bubbling */ ) {
256 // Event object or event type
257 var type = event.type || event,
258 bubbling = arguments[3];
261 event = typeof event === "object" ?
262 // jQuery.Event object
263 event[expando] ? event :
265 jQuery.extend( jQuery.Event(type), event ) :
266 // Just the event type (string)
269 if ( type.indexOf("!") >= 0 ) {
270 event.type = type = type.slice(0, -1);
271 event.exclusive = true;
274 // Handle a global trigger
276 // Don't bubble custom events when global (to avoid too much overhead)
277 event.stopPropagation();
279 // Only trigger if we've ever bound an event for it
280 if ( jQuery.event.global[ type ] ) {
281 jQuery.each( jQuery.cache, function() {
282 if ( this.events && this.events[type] ) {
283 jQuery.event.trigger( event, data, this.handle.elem );
289 // Handle triggering a single element
291 // don't do events on text and comment nodes
292 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
296 // Clean up in case it is reused
297 event.result = undefined;
300 // Clone the incoming data, if any
301 data = jQuery.makeArray( data );
302 data.unshift( event );
305 event.currentTarget = elem;
307 // Trigger the event, it is assumed that "handle" is a function
308 var handle = jQuery.data( elem, "handle" );
310 handle.apply( elem, data );
313 var parent = elem.parentNode || elem.ownerDocument;
315 // Trigger an inline bound script
317 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
318 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
319 event.result = false;
323 // prevent IE from throwing an error for some elements with some event types, see #3533
326 if ( !event.isPropagationStopped() && parent ) {
327 jQuery.event.trigger( event, data, parent, true );
329 } else if ( !event.isDefaultPrevented() ) {
330 var target = event.target, old,
331 isClick = jQuery.nodeName(target, "a") && type === "click",
332 special = jQuery.event.special[ type ] || {};
334 if ( (!special._default || special._default.call( elem, event ) === false) &&
335 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
338 if ( target[ type ] ) {
339 // Make sure that we don't accidentally re-trigger the onFOO events
340 old = target[ "on" + type ];
343 target[ "on" + type ] = null;
346 jQuery.event.triggered = true;
350 // prevent IE from throwing an error for some elements with some event types, see #3533
354 target[ "on" + type ] = old;
357 jQuery.event.triggered = false;
362 handle: function( event ) {
363 var all, handlers, namespaces, namespace, events;
365 event = arguments[0] = jQuery.event.fix( event || window.event );
366 event.currentTarget = this;
368 // Namespaced event handlers
369 all = event.type.indexOf(".") < 0 && !event.exclusive;
372 namespaces = event.type.split(".");
373 event.type = namespaces.shift();
374 namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
377 events = jQuery.data(this, "events");
378 handlers = (events || {})[ event.type ];
380 if ( events && handlers ) {
381 // Clone the handlers to prevent manipulation
382 handlers = handlers.slice(0);
384 for ( var j = 0, l = handlers.length; j < l; j++ ) {
385 var handleObj = handlers[ j ];
387 // Filter the functions by class
388 if ( all || namespace.test( handleObj.namespace ) ) {
389 // Pass in a reference to the handler function itself
390 // So that we can later remove it
391 event.handler = handleObj.handler;
392 event.data = handleObj.data;
393 event.handleObj = handleObj;
395 var ret = handleObj.handler.apply( this, arguments );
397 if ( ret !== undefined ) {
399 if ( ret === false ) {
400 event.preventDefault();
401 event.stopPropagation();
405 if ( event.isImmediatePropagationStopped() ) {
415 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(" "),
417 fix: function( event ) {
418 if ( event[ expando ] ) {
422 // store a copy of the original event object
423 // and "clone" to set read-only properties
424 var originalEvent = event;
425 event = jQuery.Event( originalEvent );
427 for ( var i = this.props.length, prop; i; ) {
428 prop = this.props[ --i ];
429 event[ prop ] = originalEvent[ prop ];
432 // Fix target property, if necessary
433 if ( !event.target ) {
434 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
437 // check if target is a textnode (safari)
438 if ( event.target.nodeType === 3 ) {
439 event.target = event.target.parentNode;
442 // Add relatedTarget, if necessary
443 if ( !event.relatedTarget && event.fromElement ) {
444 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
447 // Calculate pageX/Y if missing and clientX/Y available
448 if ( event.pageX == null && event.clientX != null ) {
449 var doc = document.documentElement, body = document.body;
450 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
451 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
454 // Add which for key events
455 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
456 event.which = event.charCode || event.keyCode;
459 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
460 if ( !event.metaKey && event.ctrlKey ) {
461 event.metaKey = event.ctrlKey;
464 // Add which for click: 1 === left; 2 === middle; 3 === right
465 // Note: button is not normalized, so don't use it
466 if ( !event.which && event.button !== undefined ) {
467 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
473 // Deprecated, use jQuery.guid instead
476 // Deprecated, use jQuery.proxy instead
481 // Make sure the ready event is setup
482 setup: jQuery.bindReady,
483 teardown: jQuery.noop
487 add: function( handleObj ) {
488 jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
491 remove: function( handleObj ) {
493 type = handleObj.origType.replace(rnamespaces, "");
495 jQuery.each( jQuery.data(this, "events").live || [], function() {
496 if ( type === this.origType.replace(rnamespaces, "") ) {
503 jQuery.event.remove( this, handleObj.origType, liveHandler );
510 setup: function( data, namespaces, eventHandle ) {
511 // We only want to do this special case on windows
512 if ( this.setInterval ) {
513 this.onbeforeunload = eventHandle;
518 teardown: function( namespaces, eventHandle ) {
519 if ( this.onbeforeunload === eventHandle ) {
520 this.onbeforeunload = null;
527 var removeEvent = document.removeEventListener ?
528 function( elem, type, handle ) {
529 if ( elem.removeEventListener ) {
530 elem.removeEventListener( type, handle, false );
533 function( elem, type, handle ) {
534 if ( elem.detachEvent ) {
535 elem.detachEvent( "on" + type, handle );
539 jQuery.Event = function( src ) {
540 // Allow instantiation without the 'new' keyword
541 if ( !this.preventDefault ) {
542 return new jQuery.Event( src );
546 if ( src && src.type ) {
547 this.originalEvent = src;
548 this.type = src.type;
554 // timeStamp is buggy for some events on Firefox(#3843)
555 // So we won't rely on the native value
556 this.timeStamp = now();
559 this[ expando ] = true;
562 function returnFalse() {
565 function returnTrue() {
569 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
570 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
571 jQuery.Event.prototype = {
572 preventDefault: function() {
573 this.isDefaultPrevented = returnTrue;
575 var e = this.originalEvent;
580 // if preventDefault exists run it on the original event
581 if ( e.preventDefault ) {
584 // otherwise set the returnValue property of the original event to false (IE)
585 e.returnValue = false;
587 stopPropagation: function() {
588 this.isPropagationStopped = returnTrue;
590 var e = this.originalEvent;
594 // if stopPropagation exists run it on the original event
595 if ( e.stopPropagation ) {
598 // otherwise set the cancelBubble property of the original event to true (IE)
599 e.cancelBubble = true;
601 stopImmediatePropagation: function() {
602 this.isImmediatePropagationStopped = returnTrue;
603 this.stopPropagation();
605 isDefaultPrevented: returnFalse,
606 isPropagationStopped: returnFalse,
607 isImmediatePropagationStopped: returnFalse
610 // Checks if an event happened on an element within another element
611 // Used in jQuery.event.special.mouseenter and mouseleave handlers
612 var withinElement = function( event ) {
613 // Check if mouse(over|out) are still within the same parent element
614 var parent = event.relatedTarget;
616 // Firefox sometimes assigns relatedTarget a XUL element
617 // which we cannot access the parentNode property of
619 // Traverse up the tree
620 while ( parent && parent !== this ) {
621 parent = parent.parentNode;
624 if ( parent !== this ) {
625 // set the correct event type
626 event.type = event.data;
628 // handle event if we actually just moused on to a non sub-element
629 jQuery.event.handle.apply( this, arguments );
632 // assuming we've left the element since we most likely mousedover a xul element
636 // In case of event delegation, we only need to rename the event.type,
637 // liveHandler will take care of the rest.
638 delegate = function( event ) {
639 event.type = event.data;
640 jQuery.event.handle.apply( this, arguments );
643 // Create mouseenter and mouseleave events
645 mouseenter: "mouseover",
646 mouseleave: "mouseout"
647 }, function( orig, fix ) {
648 jQuery.event.special[ orig ] = {
649 setup: function( data ) {
650 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
652 teardown: function( data ) {
653 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
659 if ( !jQuery.support.submitBubbles ) {
661 jQuery.event.special.submit = {
662 setup: function( data, namespaces ) {
663 if ( this.nodeName.toLowerCase() !== "form" ) {
664 jQuery.event.add(this, "click.specialSubmit", function( e ) {
665 var elem = e.target, type = elem.type;
667 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
668 return trigger( "submit", this, arguments );
672 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
673 var elem = e.target, type = elem.type;
675 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
676 return trigger( "submit", this, arguments );
685 teardown: function( namespaces ) {
686 jQuery.event.remove( this, ".specialSubmit" );
692 // change delegation, happens here so we have bind.
693 if ( !jQuery.support.changeBubbles ) {
695 var formElems = /textarea|input|select/i,
699 getVal = function( elem ) {
700 var type = elem.type, val = elem.value;
702 if ( type === "radio" || type === "checkbox" ) {
705 } else if ( type === "select-multiple" ) {
706 val = elem.selectedIndex > -1 ?
707 jQuery.map( elem.options, function( elem ) {
708 return elem.selected;
712 } else if ( elem.nodeName.toLowerCase() === "select" ) {
713 val = elem.selectedIndex;
719 testChange = function testChange( e ) {
720 var elem = e.target, data, val;
722 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
726 data = jQuery.data( elem, "_change_data" );
729 // the current data will be also retrieved by beforeactivate
730 if ( e.type !== "focusout" || elem.type !== "radio" ) {
731 jQuery.data( elem, "_change_data", val );
734 if ( data === undefined || val === data ) {
738 if ( data != null || val ) {
740 return jQuery.event.trigger( e, arguments[1], elem );
744 jQuery.event.special.change = {
746 focusout: testChange,
748 click: function( e ) {
749 var elem = e.target, type = elem.type;
751 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
752 return testChange.call( this, e );
756 // Change has to be called before submit
757 // Keydown will be called before keypress, which is used in submit-event delegation
758 keydown: function( e ) {
759 var elem = e.target, type = elem.type;
761 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
762 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
763 type === "select-multiple" ) {
764 return testChange.call( this, e );
768 // Beforeactivate happens also before the previous element is blurred
769 // with this event you can't trigger a change event, but you can store
770 // information/focus[in] is not needed anymore
771 beforeactivate: function( e ) {
773 jQuery.data( elem, "_change_data", getVal(elem) );
777 setup: function( data, namespaces ) {
778 if ( this.type === "file" ) {
782 for ( var type in changeFilters ) {
783 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
786 return formElems.test( this.nodeName );
789 teardown: function( namespaces ) {
790 jQuery.event.remove( this, ".specialChange" );
792 return formElems.test( this.nodeName );
796 changeFilters = jQuery.event.special.change.filters;
799 function trigger( type, elem, args ) {
801 return jQuery.event.handle.apply( elem, args );
804 // Create "bubbling" focus and blur events
805 if ( document.addEventListener ) {
806 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
807 jQuery.event.special[ fix ] = {
809 this.addEventListener( orig, handler, true );
811 teardown: function() {
812 this.removeEventListener( orig, handler, true );
816 function handler( e ) {
817 e = jQuery.event.fix( e );
819 return jQuery.event.handle.call( this, e );
824 jQuery.each(["bind", "one"], function( i, name ) {
825 jQuery.fn[ name ] = function( type, data, fn ) {
826 // Handle object literals
827 if ( typeof type === "object" ) {
828 for ( var key in type ) {
829 this[ name ](key, data, type[key], fn);
834 if ( jQuery.isFunction( data ) ) {
839 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
840 jQuery( this ).unbind( event, handler );
841 return fn.apply( this, arguments );
844 if ( type === "unload" && name !== "one" ) {
845 this.one( type, data, fn );
848 for ( var i = 0, l = this.length; i < l; i++ ) {
849 jQuery.event.add( this[i], type, handler, data );
858 unbind: function( type, fn ) {
859 // Handle object literals
860 if ( typeof type === "object" && !type.preventDefault ) {
861 for ( var key in type ) {
862 this.unbind(key, type[key]);
866 for ( var i = 0, l = this.length; i < l; i++ ) {
867 jQuery.event.remove( this[i], type, fn );
874 delegate: function( selector, types, data, fn ) {
875 return this.live( types, data, fn, selector );
878 undelegate: function( selector, types, fn ) {
879 if ( arguments.length === 0 ) {
880 return this.unbind( "live" );
883 return this.die( types, null, fn, selector );
887 trigger: function( type, data ) {
888 return this.each(function() {
889 jQuery.event.trigger( type, data, this );
893 triggerHandler: function( type, data ) {
895 var event = jQuery.Event( type );
896 event.preventDefault();
897 event.stopPropagation();
898 jQuery.event.trigger( event, data, this[0] );
903 toggle: function( fn ) {
904 // Save reference to arguments for access in closure
905 var args = arguments, i = 1;
907 // link all the functions, so any of them can unbind this click handler
908 while ( i < args.length ) {
909 jQuery.proxy( fn, args[ i++ ] );
912 return this.click( jQuery.proxy( fn, function( event ) {
913 // Figure out which function to execute
914 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
915 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
917 // Make sure that clicks stop
918 event.preventDefault();
920 // and execute the function
921 return args[ lastToggle ].apply( this, arguments ) || false;
925 hover: function( fnOver, fnOut ) {
926 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
933 mouseenter: "mouseover",
934 mouseleave: "mouseout"
937 jQuery.each(["live", "die"], function( i, name ) {
938 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
939 var type, i = 0, match, namespaces, preType,
940 selector = origSelector || this.selector,
941 context = origSelector ? this : jQuery( this.context );
943 if ( jQuery.isFunction( data ) ) {
948 types = (types || "").split(" ");
950 while ( (type = types[ i++ ]) != null ) {
951 match = rnamespaces.exec( type );
955 namespaces = match[0];
956 type = type.replace( rnamespaces, "" );
959 if ( type === "hover" ) {
960 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
966 if ( type === "focus" || type === "blur" ) {
967 types.push( liveMap[ type ] + namespaces );
968 type = type + namespaces;
971 type = (liveMap[ type ] || type) + namespaces;
974 if ( name === "live" ) {
976 context.each(function(){
977 jQuery.event.add( this, liveConvert( type, selector ),
978 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
982 // unbind live handler
983 context.unbind( liveConvert( type, selector ), fn );
991 function liveHandler( event ) {
992 var stop, maxLevel, elems = [], selectors = [],
993 related, match, handleObj, elem, j, i, l, data, close,
994 events = jQuery.data( this, "events" );
996 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
997 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1001 event.liveFired = this;
1003 var live = events.live.slice(0);
1005 for ( j = 0; j < live.length; j++ ) {
1006 handleObj = live[j];
1008 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1009 selectors.push( handleObj.selector );
1012 live.splice( j--, 1 );
1016 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1018 for ( i = 0, l = match.length; i < l; i++ ) {
1021 for ( j = 0; j < live.length; j++ ) {
1022 handleObj = live[j];
1024 if ( close.selector === handleObj.selector ) {
1028 // Those two events require additional checking
1029 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1030 event.type = handleObj.preType;
1031 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1034 if ( !related || related !== elem ) {
1035 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1041 for ( i = 0, l = elems.length; i < l; i++ ) {
1044 if ( maxLevel && match.level > maxLevel ) {
1048 event.currentTarget = match.elem;
1049 event.data = match.handleObj.data;
1050 event.handleObj = match.handleObj;
1052 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1054 if ( ret === false || event.isPropagationStopped() ) {
1055 maxLevel = match.level;
1057 if ( ret === false ) {
1066 function liveConvert( type, selector ) {
1067 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
1070 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1071 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1072 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1074 // Handle event binding
1075 jQuery.fn[ name ] = function( fn ) {
1076 return fn ? this.bind( name, fn ) : this.trigger( name );
1079 if ( jQuery.attrFn ) {
1080 jQuery.attrFn[ name ] = true;
1084 // Prevent memory leaks in IE
1085 // Window isn't included so as not to unbind existing unload events
1087 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1088 if ( window.attachEvent && !window.addEventListener ) {
1089 window.attachEvent("onunload", function() {
1090 for ( var id in jQuery.cache ) {
1091 if ( jQuery.cache[ id ].handle ) {
1092 // Try/Catch is to handle iframes being unloaded, see #4280
1094 jQuery.event.remove( jQuery.cache[ id ].handle.elem );