3 var rnamespaces = /\.(.*)$/,
4 rformElems = /^(?:textarea|input|select)$/i,
7 rescape = /[^\w\s.|`]/g,
8 fcleanup = function( nm ) {
9 return nm.replace(rescape, "\\$&");
13 * A number of helper functions used for managing events.
14 * Many of the ideas behind this code originated from
15 * Dean Edwards' addEvent library.
19 // Bind an event to an element
20 // Original by Dean Edwards
21 add: function( elem, types, handler, data ) {
22 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
26 // For whatever reason, IE has trouble passing the window object
27 // around, causing it to be cloned in the process
28 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
32 if ( handler === false ) {
33 handler = returnFalse;
36 var handleObjIn, handleObj;
38 if ( handler.handler ) {
39 handleObjIn = handler;
40 handler = handleObjIn.handler;
43 // Make sure that the function being executed has a unique ID
44 if ( !handler.guid ) {
45 handler.guid = jQuery.guid++;
48 // Init the element's event structure
49 var elemData = jQuery.data( elem );
51 // If no elemData is found then we must be trying to bind to one of the
52 // banned noData elements
57 var events = elemData.events = elemData.events || {},
58 eventHandle = elemData.handle;
61 elemData.handle = eventHandle = function() {
62 // Handle the second event of a trigger and when
63 // an event is called after a page has unloaded
64 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
65 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
70 // Add elem as a property of the handle function
71 // This is to prevent a memory leak with non-native events in IE.
72 eventHandle.elem = elem;
74 // Handle multiple events separated by a space
75 // jQuery(...).bind("mouseover mouseout", fn);
76 types = types.split(" ");
78 var type, i = 0, namespaces;
80 while ( (type = types[ i++ ]) ) {
81 handleObj = handleObjIn ?
82 jQuery.extend({}, handleObjIn) :
83 { handler: handler, data: data };
85 // Namespaced event handlers
86 if ( type.indexOf(".") > -1 ) {
87 namespaces = type.split(".");
88 type = namespaces.shift();
89 handleObj.namespace = namespaces.slice(0).sort().join(".");
93 handleObj.namespace = "";
96 handleObj.type = type;
97 if ( !handleObj.guid ) {
98 handleObj.guid = handler.guid;
101 // Get the current list of functions bound to this event
102 var handlers = events[ type ],
103 special = jQuery.event.special[ type ] || {};
105 // Init the event handler queue
107 handlers = events[ type ] = [];
109 // Check for a special event handler
110 // Only use addEventListener/attachEvent if the special
111 // events handler returns false
112 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
113 // Bind the global event handler to the element
114 if ( elem.addEventListener ) {
115 elem.addEventListener( type, eventHandle, false );
117 } else if ( elem.attachEvent ) {
118 elem.attachEvent( "on" + type, eventHandle );
124 special.add.call( elem, handleObj );
126 if ( !handleObj.handler.guid ) {
127 handleObj.handler.guid = handler.guid;
131 // Add the function to the element's handler list
132 handlers.push( handleObj );
134 // Keep track of which events have been used, for global triggering
135 jQuery.event.global[ type ] = true;
138 // Nullify elem to prevent memory leaks in IE
144 // Detach an event or set of events from an element
145 remove: function( elem, types, handler, pos ) {
146 // don't do events on text and comment nodes
147 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
151 if ( handler === false ) {
152 handler = returnFalse;
155 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
156 elemData = jQuery.data( elem ),
157 events = elemData && elemData.events;
159 if ( !elemData || !events ) {
163 // types is actually an event object here
164 if ( types && types.type ) {
165 handler = types.handler;
169 // Unbind all events for the element
170 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
173 for ( type in events ) {
174 jQuery.event.remove( elem, type + types );
180 // Handle multiple events separated by a space
181 // jQuery(...).unbind("mouseover mouseout", fn);
182 types = types.split(" ");
184 while ( (type = types[ i++ ]) ) {
187 all = type.indexOf(".") < 0;
191 // Namespaced event handlers
192 namespaces = type.split(".");
193 type = namespaces.shift();
195 namespace = new RegExp("(^|\\.)" +
196 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
199 eventType = events[ type ];
206 for ( j = 0; j < eventType.length; j++ ) {
207 handleObj = eventType[ j ];
209 if ( all || namespace.test( handleObj.namespace ) ) {
210 jQuery.event.remove( elem, origType, handleObj.handler, j );
211 eventType.splice( j--, 1 );
218 special = jQuery.event.special[ type ] || {};
220 for ( j = pos || 0; j < eventType.length; j++ ) {
221 handleObj = eventType[ j ];
223 if ( handler.guid === handleObj.guid ) {
224 // remove the given handler for the given type
225 if ( all || namespace.test( handleObj.namespace ) ) {
227 eventType.splice( j--, 1 );
230 if ( special.remove ) {
231 special.remove.call( elem, handleObj );
241 // remove generic event handler if no more handlers exist
242 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
243 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
244 jQuery.removeEvent( elem, type, elemData.handle );
248 delete events[ type ];
252 // Remove the expando if it's no longer used
253 if ( jQuery.isEmptyObject( events ) ) {
254 var handle = elemData.handle;
259 delete elemData.events;
260 delete elemData.handle;
262 if ( jQuery.isEmptyObject( elemData ) ) {
263 jQuery.removeData( elem );
268 // bubbling is internal
269 trigger: function( event, data, elem /*, bubbling */ ) {
270 // Event object or event type
271 var type = event.type || event,
272 bubbling = arguments[3];
275 event = typeof event === "object" ?
276 // jQuery.Event object
277 event[ jQuery.expando ] ? event :
279 jQuery.extend( jQuery.Event(type), event ) :
280 // Just the event type (string)
283 if ( type.indexOf("!") >= 0 ) {
284 event.type = type = type.slice(0, -1);
285 event.exclusive = true;
288 // Handle a global trigger
290 // Don't bubble custom events when global (to avoid too much overhead)
291 event.stopPropagation();
293 // Only trigger if we've ever bound an event for it
294 if ( jQuery.event.global[ type ] ) {
295 jQuery.each( jQuery.cache, function() {
296 if ( this.events && this.events[type] ) {
297 jQuery.event.trigger( event, data, this.handle.elem );
303 // Handle triggering a single element
305 // don't do events on text and comment nodes
306 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
310 // Clean up in case it is reused
311 event.result = undefined;
314 // Clone the incoming data, if any
315 data = jQuery.makeArray( data );
316 data.unshift( event );
319 event.currentTarget = elem;
321 // Trigger the event, it is assumed that "handle" is a function
322 var handle = jQuery.data( elem, "handle" );
324 handle.apply( elem, data );
327 var parent = elem.parentNode || elem.ownerDocument;
329 // Trigger an inline bound script
331 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
332 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
333 event.result = false;
334 event.preventDefault();
338 // prevent IE from throwing an error for some elements with some event types, see #3533
339 } catch (inlineError) {}
341 if ( !event.isPropagationStopped() && parent ) {
342 jQuery.event.trigger( event, data, parent, true );
344 } else if ( !event.isDefaultPrevented() ) {
345 var target = event.target, old, targetType = type.replace(rnamespaces, ""),
346 isClick = jQuery.nodeName(target, "a") && targetType === "click",
347 special = jQuery.event.special[ targetType ] || {};
349 if ( (!special._default || special._default.call( elem, event ) === false) &&
350 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
353 if ( target[ targetType ] ) {
354 // Make sure that we don't accidentally re-trigger the onFOO events
355 old = target[ "on" + targetType ];
358 target[ "on" + targetType ] = null;
361 jQuery.event.triggered = true;
362 target[ targetType ]();
365 // prevent IE from throwing an error for some elements with some event types, see #3533
366 } catch (triggerError) {}
369 target[ "on" + targetType ] = old;
372 jQuery.event.triggered = false;
377 handle: function( event ) {
378 var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
380 event = args[0] = jQuery.event.fix( event || window.event );
381 event.currentTarget = this;
383 // Namespaced event handlers
384 all = event.type.indexOf(".") < 0 && !event.exclusive;
387 namespaces = event.type.split(".");
388 event.type = namespaces.shift();
389 namespace_sort = namespaces.slice(0).sort();
390 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
393 event.namespace = event.namespace || namespace_sort.join(".");
395 events = jQuery.data(this, "events");
396 handlers = (events || {})[ event.type ];
398 if ( events && handlers ) {
399 // Clone the handlers to prevent manipulation
400 handlers = handlers.slice(0);
402 for ( var j = 0, l = handlers.length; j < l; j++ ) {
403 var handleObj = handlers[ j ];
405 // Filter the functions by class
406 if ( all || namespace_re.test( handleObj.namespace ) ) {
407 // Pass in a reference to the handler function itself
408 // So that we can later remove it
409 event.handler = handleObj.handler;
410 event.data = handleObj.data;
411 event.handleObj = handleObj;
413 var ret = handleObj.handler.apply( this, args );
415 if ( ret !== undefined ) {
417 if ( ret === false ) {
418 event.preventDefault();
419 event.stopPropagation();
423 if ( event.isImmediatePropagationStopped() ) {
433 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
435 fix: function( event ) {
436 if ( event[ jQuery.expando ] ) {
440 // store a copy of the original event object
441 // and "clone" to set read-only properties
442 var originalEvent = event;
443 event = jQuery.Event( originalEvent );
445 for ( var i = this.props.length, prop; i; ) {
446 prop = this.props[ --i ];
447 event[ prop ] = originalEvent[ prop ];
450 // Fix target property, if necessary
451 if ( !event.target ) {
452 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
455 // check if target is a textnode (safari)
456 if ( event.target.nodeType === 3 ) {
457 event.target = event.target.parentNode;
460 // Add relatedTarget, if necessary
461 if ( !event.relatedTarget && event.fromElement ) {
462 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
465 // Calculate pageX/Y if missing and clientX/Y available
466 if ( event.pageX == null && event.clientX != null ) {
467 var doc = document.documentElement, body = document.body;
468 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
469 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
472 // Add which for key events
473 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
474 event.which = event.charCode || event.keyCode;
477 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
478 if ( !event.metaKey && event.ctrlKey ) {
479 event.metaKey = event.ctrlKey;
482 // Add which for click: 1 === left; 2 === middle; 3 === right
483 // Note: button is not normalized, so don't use it
484 if ( !event.which && event.button !== undefined ) {
485 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
491 // Deprecated, use jQuery.guid instead
494 // Deprecated, use jQuery.proxy instead
499 // Make sure the ready event is setup
500 setup: jQuery.bindReady,
501 teardown: jQuery.noop
505 add: function( handleObj ) {
506 jQuery.event.add( this,
507 liveConvert( handleObj.origType, handleObj.selector ),
508 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
511 remove: function( handleObj ) {
512 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
517 setup: function( data, namespaces, eventHandle ) {
518 // We only want to do this special case on windows
519 if ( jQuery.isWindow( this ) ) {
520 this.onbeforeunload = eventHandle;
524 teardown: function( namespaces, eventHandle ) {
525 if ( this.onbeforeunload === eventHandle ) {
526 this.onbeforeunload = null;
533 jQuery.removeEvent = document.removeEventListener ?
534 function( elem, type, handle ) {
535 if ( elem.removeEventListener ) {
536 elem.removeEventListener( type, handle, false );
539 function( elem, type, handle ) {
540 if ( elem.detachEvent ) {
541 elem.detachEvent( "on" + type, handle );
545 jQuery.Event = function( src ) {
546 // Allow instantiation without the 'new' keyword
547 if ( !this.preventDefault ) {
548 return new jQuery.Event( src );
552 if ( src && src.type ) {
553 this.originalEvent = src;
554 this.type = src.type;
560 // timeStamp is buggy for some events on Firefox(#3843)
561 // So we won't rely on the native value
562 this.timeStamp = jQuery.now();
565 this[ jQuery.expando ] = true;
568 function returnFalse() {
571 function returnTrue() {
575 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
576 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
577 jQuery.Event.prototype = {
578 preventDefault: function() {
579 this.isDefaultPrevented = returnTrue;
581 var e = this.originalEvent;
586 // if preventDefault exists run it on the original event
587 if ( e.preventDefault ) {
590 // otherwise set the returnValue property of the original event to false (IE)
592 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 ) {
705 getVal = function( elem ) {
706 var type = elem.type, val = elem.value;
708 if ( type === "radio" || type === "checkbox" ) {
711 } else if ( type === "select-multiple" ) {
712 val = elem.selectedIndex > -1 ?
713 jQuery.map( elem.options, function( elem ) {
714 return elem.selected;
718 } else if ( elem.nodeName.toLowerCase() === "select" ) {
719 val = elem.selectedIndex;
725 testChange = function testChange( e ) {
726 var elem = e.target, data, val;
728 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
732 data = jQuery.data( elem, "_change_data" );
735 // the current data will be also retrieved by beforeactivate
736 if ( e.type !== "focusout" || elem.type !== "radio" ) {
737 jQuery.data( elem, "_change_data", val );
740 if ( data === undefined || val === data ) {
744 if ( data != null || val ) {
746 return jQuery.event.trigger( e, arguments[1], elem );
750 jQuery.event.special.change = {
752 focusout: testChange,
754 click: function( e ) {
755 var elem = e.target, type = elem.type;
757 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
758 return testChange.call( this, e );
762 // Change has to be called before submit
763 // Keydown will be called before keypress, which is used in submit-event delegation
764 keydown: function( e ) {
765 var elem = e.target, type = elem.type;
767 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
768 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
769 type === "select-multiple" ) {
770 return testChange.call( this, e );
774 // Beforeactivate happens also before the previous element is blurred
775 // with this event you can't trigger a change event, but you can store
776 // information/focus[in] is not needed anymore
777 beforeactivate: function( e ) {
779 jQuery.data( elem, "_change_data", getVal(elem) );
783 setup: function( data, namespaces ) {
784 if ( this.type === "file" ) {
788 for ( var type in changeFilters ) {
789 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
792 return rformElems.test( this.nodeName );
795 teardown: function( namespaces ) {
796 jQuery.event.remove( this, ".specialChange" );
798 return rformElems.test( this.nodeName );
802 changeFilters = jQuery.event.special.change.filters;
805 function trigger( type, elem, args ) {
807 return jQuery.event.handle.apply( elem, args );
810 // Create "bubbling" focus and blur events
811 if ( document.addEventListener ) {
812 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
813 jQuery.event.special[ fix ] = {
815 this.addEventListener( orig, handler, true );
817 teardown: function() {
818 this.removeEventListener( orig, handler, true );
822 function handler( e ) {
823 e = jQuery.event.fix( e );
825 return jQuery.event.handle.call( this, e );
830 jQuery.each(["bind", "one"], function( i, name ) {
831 jQuery.fn[ name ] = function( type, data, fn ) {
832 // Handle object literals
833 if ( typeof type === "object" ) {
834 for ( var key in type ) {
835 this[ name ](key, data, type[key], fn);
840 if ( jQuery.isFunction( data ) || data === false ) {
845 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
846 jQuery( this ).unbind( event, handler );
847 return fn.apply( this, arguments );
850 if ( type === "unload" && name !== "one" ) {
851 this.one( type, data, fn );
854 for ( var i = 0, l = this.length; i < l; i++ ) {
855 jQuery.event.add( this[i], type, handler, data );
864 unbind: function( type, fn ) {
865 // Handle object literals
866 if ( typeof type === "object" && !type.preventDefault ) {
867 for ( var key in type ) {
868 this.unbind(key, type[key]);
872 for ( var i = 0, l = this.length; i < l; i++ ) {
873 jQuery.event.remove( this[i], type, fn );
880 delegate: function( selector, types, data, fn ) {
881 return this.live( types, data, fn, selector );
884 undelegate: function( selector, types, fn ) {
885 if ( arguments.length === 0 ) {
886 return this.unbind( "live" );
889 return this.die( types, null, fn, selector );
893 trigger: function( type, data ) {
894 return this.each(function() {
895 jQuery.event.trigger( type, data, this );
899 triggerHandler: function( type, data ) {
901 var event = jQuery.Event( type );
902 event.preventDefault();
903 event.stopPropagation();
904 jQuery.event.trigger( event, data, this[0] );
909 toggle: function( fn ) {
910 // Save reference to arguments for access in closure
911 var args = arguments, i = 1;
913 // link all the functions, so any of them can unbind this click handler
914 while ( i < args.length ) {
915 jQuery.proxy( fn, args[ i++ ] );
918 return this.click( jQuery.proxy( fn, function( event ) {
919 // Figure out which function to execute
920 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
921 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
923 // Make sure that clicks stop
924 event.preventDefault();
926 // and execute the function
927 return args[ lastToggle ].apply( this, arguments ) || false;
931 hover: function( fnOver, fnOut ) {
932 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
939 mouseenter: "mouseover",
940 mouseleave: "mouseout"
943 jQuery.each(["live", "die"], function( i, name ) {
944 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
945 var type, i = 0, match, namespaces, preType,
946 selector = origSelector || this.selector,
947 context = origSelector ? this : jQuery( this.context );
949 if ( typeof types === "object" && !types.preventDefault ) {
950 for ( var key in types ) {
951 context[ name ]( key, data, types[key], selector );
957 if ( jQuery.isFunction( data ) ) {
962 types = (types || "").split(" ");
964 while ( (type = types[ i++ ]) != null ) {
965 match = rnamespaces.exec( type );
969 namespaces = match[0];
970 type = type.replace( rnamespaces, "" );
973 if ( type === "hover" ) {
974 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
980 if ( type === "focus" || type === "blur" ) {
981 types.push( liveMap[ type ] + namespaces );
982 type = type + namespaces;
985 type = (liveMap[ type ] || type) + namespaces;
988 if ( name === "live" ) {
990 for ( var j = 0, l = context.length; j < l; j++ ) {
991 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
992 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
996 // unbind live handler
997 context.unbind( "live." + liveConvert( type, selector ), fn );
1005 function liveHandler( event ) {
1006 var stop, maxLevel, elems = [], selectors = [],
1007 related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
1008 events = jQuery.data( this, "events" );
1010 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
1011 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1015 if ( event.namespace ) {
1016 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
1019 event.liveFired = this;
1021 var live = events.live.slice(0);
1023 for ( j = 0; j < live.length; j++ ) {
1024 handleObj = live[j];
1026 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1027 selectors.push( handleObj.selector );
1030 live.splice( j--, 1 );
1034 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1036 for ( i = 0, l = match.length; i < l; i++ ) {
1039 for ( j = 0; j < live.length; j++ ) {
1040 handleObj = live[j];
1042 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
1046 // Those two events require additional checking
1047 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1048 event.type = handleObj.preType;
1049 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1052 if ( !related || related !== elem ) {
1053 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1059 for ( i = 0, l = elems.length; i < l; i++ ) {
1062 if ( maxLevel && match.level > maxLevel ) {
1066 event.currentTarget = match.elem;
1067 event.data = match.handleObj.data;
1068 event.handleObj = match.handleObj;
1070 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1072 if ( ret === false || event.isPropagationStopped() ) {
1073 maxLevel = match.level;
1075 if ( ret === false ) {
1084 function liveConvert( type, selector ) {
1085 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
1088 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1089 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1090 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1092 // Handle event binding
1093 jQuery.fn[ name ] = function( data, fn ) {
1099 return arguments.length > 0 ?
1100 this.bind( name, data, fn ) :
1101 this.trigger( name );
1104 if ( jQuery.attrFn ) {
1105 jQuery.attrFn[ name ] = true;
1109 // Prevent memory leaks in IE
1110 // Window isn't included so as not to unbind existing unload events
1112 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1113 if ( window.attachEvent && !window.addEventListener ) {
1114 window.attachEvent("onunload", function() {
1115 for ( var id in jQuery.cache ) {
1116 if ( jQuery.cache[ id ].handle ) {
1117 // Try/Catch is to handle iframes being unloaded, see #4280
1119 jQuery.event.remove( jQuery.cache[ id ].handle.elem );