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;
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, j, 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 ( 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 ( 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
332 } catch (inlineError) {}
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
359 } catch (triggerError) {}
362 target[ "on" + type ] = old;
365 jQuery.event.triggered = false;
370 handle: function( event ) {
371 var all, handlers, namespaces, namespace, events, args = jQuery.makeArray( arguments );
373 event = args[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, args );
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;
525 teardown: function( namespaces, eventHandle ) {
526 if ( this.onbeforeunload === eventHandle ) {
527 this.onbeforeunload = null;
534 var removeEvent = document.removeEventListener ?
535 function( elem, type, handle ) {
536 if ( elem.removeEventListener ) {
537 elem.removeEventListener( type, handle, false );
540 function( elem, type, handle ) {
541 if ( elem.detachEvent ) {
542 elem.detachEvent( "on" + type, handle );
546 jQuery.Event = function( src ) {
547 // Allow instantiation without the 'new' keyword
548 if ( !this.preventDefault ) {
549 return new jQuery.Event( src );
553 if ( src && src.type ) {
554 this.originalEvent = src;
555 this.type = src.type;
561 // timeStamp is buggy for some events on Firefox(#3843)
562 // So we won't rely on the native value
563 this.timeStamp = now();
566 this[ expando ] = true;
569 function returnFalse() {
572 function returnTrue() {
576 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
577 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
578 jQuery.Event.prototype = {
579 preventDefault: function() {
580 this.isDefaultPrevented = returnTrue;
582 var e = this.originalEvent;
587 // if preventDefault exists run it on the original event
588 if ( e.preventDefault ) {
591 // otherwise set the returnValue property of the original event to false (IE)
592 e.returnValue = false;
594 stopPropagation: function() {
595 this.isPropagationStopped = returnTrue;
597 var e = this.originalEvent;
601 // if stopPropagation exists run it on the original event
602 if ( e.stopPropagation ) {
605 // otherwise set the cancelBubble property of the original event to true (IE)
606 e.cancelBubble = true;
608 stopImmediatePropagation: function() {
609 this.isImmediatePropagationStopped = returnTrue;
610 this.stopPropagation();
612 isDefaultPrevented: returnFalse,
613 isPropagationStopped: returnFalse,
614 isImmediatePropagationStopped: returnFalse
617 // Checks if an event happened on an element within another element
618 // Used in jQuery.event.special.mouseenter and mouseleave handlers
619 var withinElement = function( event ) {
620 // Check if mouse(over|out) are still within the same parent element
621 var parent = event.relatedTarget;
623 // Firefox sometimes assigns relatedTarget a XUL element
624 // which we cannot access the parentNode property of
626 // Traverse up the tree
627 while ( parent && parent !== this ) {
628 parent = parent.parentNode;
631 if ( parent !== this ) {
632 // set the correct event type
633 event.type = event.data;
635 // handle event if we actually just moused on to a non sub-element
636 jQuery.event.handle.apply( this, arguments );
639 // assuming we've left the element since we most likely mousedover a xul element
643 // In case of event delegation, we only need to rename the event.type,
644 // liveHandler will take care of the rest.
645 delegate = function( event ) {
646 event.type = event.data;
647 jQuery.event.handle.apply( this, arguments );
650 // Create mouseenter and mouseleave events
652 mouseenter: "mouseover",
653 mouseleave: "mouseout"
654 }, function( orig, fix ) {
655 jQuery.event.special[ orig ] = {
656 setup: function( data ) {
657 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
659 teardown: function( data ) {
660 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
666 if ( !jQuery.support.submitBubbles ) {
668 jQuery.event.special.submit = {
669 setup: function( data, namespaces ) {
670 if ( this.nodeName.toLowerCase() !== "form" ) {
671 jQuery.event.add(this, "click.specialSubmit", function( e ) {
672 var elem = e.target, type = elem.type;
674 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
675 return trigger( "submit", this, arguments );
679 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
680 var elem = e.target, type = elem.type;
682 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
683 return trigger( "submit", this, arguments );
692 teardown: function( namespaces ) {
693 jQuery.event.remove( this, ".specialSubmit" );
699 // change delegation, happens here so we have bind.
700 if ( !jQuery.support.changeBubbles ) {
702 var formElems = /textarea|input|select/i,
706 getVal = function( elem ) {
707 var type = elem.type, val = elem.value;
709 if ( type === "radio" || type === "checkbox" ) {
712 } else if ( type === "select-multiple" ) {
713 val = elem.selectedIndex > -1 ?
714 jQuery.map( elem.options, function( elem ) {
715 return elem.selected;
719 } else if ( elem.nodeName.toLowerCase() === "select" ) {
720 val = elem.selectedIndex;
726 testChange = function testChange( e ) {
727 var elem = e.target, data, val;
729 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
733 data = jQuery.data( elem, "_change_data" );
736 // the current data will be also retrieved by beforeactivate
737 if ( e.type !== "focusout" || elem.type !== "radio" ) {
738 jQuery.data( elem, "_change_data", val );
741 if ( data === undefined || val === data ) {
745 if ( data != null || val ) {
747 return jQuery.event.trigger( e, arguments[1], elem );
751 jQuery.event.special.change = {
753 focusout: testChange,
755 click: function( e ) {
756 var elem = e.target, type = elem.type;
758 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
759 return testChange.call( this, e );
763 // Change has to be called before submit
764 // Keydown will be called before keypress, which is used in submit-event delegation
765 keydown: function( e ) {
766 var elem = e.target, type = elem.type;
768 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
769 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
770 type === "select-multiple" ) {
771 return testChange.call( this, e );
775 // Beforeactivate happens also before the previous element is blurred
776 // with this event you can't trigger a change event, but you can store
777 // information/focus[in] is not needed anymore
778 beforeactivate: function( e ) {
780 jQuery.data( elem, "_change_data", getVal(elem) );
784 setup: function( data, namespaces ) {
785 if ( this.type === "file" ) {
789 for ( var type in changeFilters ) {
790 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
793 return formElems.test( this.nodeName );
796 teardown: function( namespaces ) {
797 jQuery.event.remove( this, ".specialChange" );
799 return formElems.test( this.nodeName );
803 changeFilters = jQuery.event.special.change.filters;
806 function trigger( type, elem, args ) {
808 return jQuery.event.handle.apply( elem, args );
811 // Create "bubbling" focus and blur events
812 if ( document.addEventListener ) {
813 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
814 jQuery.event.special[ fix ] = {
816 this.addEventListener( orig, handler, true );
818 teardown: function() {
819 this.removeEventListener( orig, handler, true );
823 function handler( e ) {
824 e = jQuery.event.fix( e );
826 return jQuery.event.handle.call( this, e );
831 jQuery.each(["bind", "one"], function( i, name ) {
832 jQuery.fn[ name ] = function( type, data, fn ) {
833 // Handle object literals
834 if ( typeof type === "object" ) {
835 for ( var key in type ) {
836 this[ name ](key, data, type[key], fn);
841 if ( jQuery.isFunction( data ) || data === false ) {
846 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
847 jQuery( this ).unbind( event, handler );
848 return fn.apply( this, arguments );
851 if ( type === "unload" && name !== "one" ) {
852 this.one( type, data, fn );
855 for ( var i = 0, l = this.length; i < l; i++ ) {
856 jQuery.event.add( this[i], type, handler, data );
865 unbind: function( type, fn ) {
866 // Handle object literals
867 if ( typeof type === "object" && !type.preventDefault ) {
868 for ( var key in type ) {
869 this.unbind(key, type[key]);
873 for ( var i = 0, l = this.length; i < l; i++ ) {
874 jQuery.event.remove( this[i], type, fn );
881 delegate: function( selector, types, data, fn ) {
882 return this.live( types, data, fn, selector );
885 undelegate: function( selector, types, fn ) {
886 if ( arguments.length === 0 ) {
887 return this.unbind( "live" );
890 return this.die( types, null, fn, selector );
894 trigger: function( type, data ) {
895 return this.each(function() {
896 jQuery.event.trigger( type, data, this );
900 triggerHandler: function( type, data ) {
902 var event = jQuery.Event( type );
903 event.preventDefault();
904 event.stopPropagation();
905 jQuery.event.trigger( event, data, this[0] );
910 toggle: function( fn ) {
911 // Save reference to arguments for access in closure
912 var args = arguments, i = 1;
914 // link all the functions, so any of them can unbind this click handler
915 while ( i < args.length ) {
916 jQuery.proxy( fn, args[ i++ ] );
919 return this.click( jQuery.proxy( fn, function( event ) {
920 // Figure out which function to execute
921 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
922 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
924 // Make sure that clicks stop
925 event.preventDefault();
927 // and execute the function
928 return args[ lastToggle ].apply( this, arguments ) || false;
932 hover: function( fnOver, fnOut ) {
933 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
940 mouseenter: "mouseover",
941 mouseleave: "mouseout"
944 jQuery.each(["live", "die"], function( i, name ) {
945 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
946 var type, i = 0, match, namespaces, preType,
947 selector = origSelector || this.selector,
948 context = origSelector ? this : jQuery( this.context );
950 if ( jQuery.isFunction( data ) ) {
955 types = (types || "").split(" ");
957 while ( (type = types[ i++ ]) != null ) {
958 match = rnamespaces.exec( type );
962 namespaces = match[0];
963 type = type.replace( rnamespaces, "" );
966 if ( type === "hover" ) {
967 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
973 if ( type === "focus" || type === "blur" ) {
974 types.push( liveMap[ type ] + namespaces );
975 type = type + namespaces;
978 type = (liveMap[ type ] || type) + namespaces;
981 if ( name === "live" ) {
983 for ( var j = 0, l = context.length; j < l; j++ ) {
984 jQuery.event.add( context[j], liveConvert( type, selector ),
985 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
989 // unbind live handler
990 context.unbind( liveConvert( type, selector ), fn );
998 function liveHandler( event ) {
999 var stop, maxLevel, elems = [], selectors = [],
1000 related, match, handleObj, elem, j, i, l, data, close,
1001 events = jQuery.data( this, "events" );
1003 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
1004 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1008 event.liveFired = this;
1010 var live = events.live.slice(0);
1012 for ( j = 0; j < live.length; j++ ) {
1013 handleObj = live[j];
1015 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1016 selectors.push( handleObj.selector );
1019 live.splice( j--, 1 );
1023 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1025 for ( i = 0, l = match.length; i < l; i++ ) {
1028 for ( j = 0; j < live.length; j++ ) {
1029 handleObj = live[j];
1031 if ( close.selector === handleObj.selector ) {
1035 // Those two events require additional checking
1036 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1037 event.type = handleObj.preType;
1038 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1041 if ( !related || related !== elem ) {
1042 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1048 for ( i = 0, l = elems.length; i < l; i++ ) {
1051 if ( maxLevel && match.level > maxLevel ) {
1055 event.currentTarget = match.elem;
1056 event.data = match.handleObj.data;
1057 event.handleObj = match.handleObj;
1059 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1061 if ( ret === false || event.isPropagationStopped() ) {
1062 maxLevel = match.level;
1064 if ( ret === false ) {
1073 function liveConvert( type, selector ) {
1074 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
1077 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1078 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1079 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1081 // Handle event binding
1082 jQuery.fn[ name ] = function( data, fn ) {
1088 return arguments.length > 0 ?
1089 this.bind( name, data, fn ) :
1090 this.trigger( name );
1093 if ( jQuery.attrFn ) {
1094 jQuery.attrFn[ name ] = true;
1098 // Prevent memory leaks in IE
1099 // Window isn't included so as not to unbind existing unload events
1101 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1102 if ( window.attachEvent && !window.addEventListener ) {
1103 window.attachEvent("onunload", function() {
1104 for ( var id in jQuery.cache ) {
1105 if ( jQuery.cache[ id ].handle ) {
1106 // Try/Catch is to handle iframes being unloaded, see #4280
1108 jQuery.event.remove( jQuery.cache[ id ].handle.elem );