3 var rnamespaces = /\.(.*)$/,
4 fcleanup = function( nm ) {
5 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
11 * A number of helper functions used for managing events.
12 * Many of the ideas behind this code originated from
13 * Dean Edwards' addEvent library.
17 // Bind an event to an element
18 // Original by Dean Edwards
19 add: function( elem, types, handler, data ) {
20 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
24 // For whatever reason, IE has trouble passing the window object
25 // around, causing it to be cloned in the process
26 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
30 if ( handler === false ) {
31 handler = returnFalse;
34 var handleObjIn, handleObj;
36 if ( handler.handler ) {
37 handleObjIn = handler;
38 handler = handleObjIn.handler;
41 // Make sure that the function being executed has a unique ID
42 if ( !handler.guid ) {
43 handler.guid = jQuery.guid++;
46 // Init the element's event structure
47 var elemData = jQuery.data( elem );
49 // If no elemData is found then we must be trying to bind to one of the
50 // banned noData elements
55 var events = elemData.events = elemData.events || {},
56 eventHandle = elemData.handle;
59 elemData.handle = eventHandle = function() {
60 // Handle the second event of a trigger and when
61 // an event is called after a page has unloaded
62 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
63 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
68 // Add elem as a property of the handle function
69 // This is to prevent a memory leak with non-native events in IE.
70 eventHandle.elem = elem;
72 // Handle multiple events separated by a space
73 // jQuery(...).bind("mouseover mouseout", fn);
74 types = types.split(" ");
76 var type, i = 0, namespaces;
78 while ( (type = types[ i++ ]) ) {
79 handleObj = handleObjIn ?
80 jQuery.extend({}, handleObjIn) :
81 { handler: handler, data: data };
83 // Namespaced event handlers
84 if ( type.indexOf(".") > -1 ) {
85 namespaces = type.split(".");
86 type = namespaces.shift();
87 handleObj.namespace = namespaces.slice(0).sort().join(".");
91 handleObj.namespace = "";
94 handleObj.type = type;
95 if ( !handleObj.guid ) {
96 handleObj.guid = handler.guid;
99 // Get the current list of functions bound to this event
100 var handlers = events[ type ],
101 special = jQuery.event.special[ type ] || {};
103 // Init the event handler queue
105 handlers = events[ type ] = [];
107 // Check for a special event handler
108 // Only use addEventListener/attachEvent if the special
109 // events handler returns false
110 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
111 // Bind the global event handler to the element
112 if ( elem.addEventListener ) {
113 elem.addEventListener( type, eventHandle, false );
115 } else if ( elem.attachEvent ) {
116 elem.attachEvent( "on" + type, eventHandle );
122 special.add.call( elem, handleObj );
124 if ( !handleObj.handler.guid ) {
125 handleObj.handler.guid = handler.guid;
129 // Add the function to the element's handler list
130 handlers.push( handleObj );
132 // Keep track of which events have been used, for global triggering
133 jQuery.event.global[ type ] = true;
136 // Nullify elem to prevent memory leaks in IE
142 // Detach an event or set of events from an element
143 remove: function( elem, types, handler, pos ) {
144 // don't do events on text and comment nodes
145 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
149 if ( handler === false ) {
150 handler = returnFalse;
153 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
154 elemData = jQuery.data( elem ),
155 events = elemData && elemData.events;
157 if ( !elemData || !events ) {
161 // types is actually an event object here
162 if ( types && types.type ) {
163 handler = types.handler;
167 // Unbind all events for the element
168 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
171 for ( type in events ) {
172 jQuery.event.remove( elem, type + types );
178 // Handle multiple events separated by a space
179 // jQuery(...).unbind("mouseover mouseout", fn);
180 types = types.split(" ");
182 while ( (type = types[ i++ ]) ) {
185 all = type.indexOf(".") < 0;
189 // Namespaced event handlers
190 namespaces = type.split(".");
191 type = namespaces.shift();
193 namespace = new RegExp("(^|\\.)" +
194 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
197 eventType = events[ type ];
204 for ( j = 0; j < eventType.length; j++ ) {
205 handleObj = eventType[ j ];
207 if ( all || namespace.test( handleObj.namespace ) ) {
208 jQuery.event.remove( elem, origType, handleObj.handler, j );
209 eventType.splice( j--, 1 );
216 special = jQuery.event.special[ type ] || {};
218 for ( j = pos || 0; j < eventType.length; j++ ) {
219 handleObj = eventType[ j ];
221 if ( handler.guid === handleObj.guid ) {
222 // remove the given handler for the given type
223 if ( all || namespace.test( handleObj.namespace ) ) {
225 eventType.splice( j--, 1 );
228 if ( special.remove ) {
229 special.remove.call( elem, handleObj );
239 // remove generic event handler if no more handlers exist
240 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
241 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
242 jQuery.removeEvent( elem, type, elemData.handle );
246 delete events[ type ];
250 // Remove the expando if it's no longer used
251 if ( jQuery.isEmptyObject( events ) ) {
252 var handle = elemData.handle;
257 delete elemData.events;
258 delete elemData.handle;
260 if ( jQuery.isEmptyObject( elemData ) ) {
261 jQuery.removeData( elem );
266 // bubbling is internal
267 trigger: function( event, data, elem /*, bubbling */ ) {
268 // Event object or event type
269 var type = event.type || event,
270 bubbling = arguments[3];
273 event = typeof event === "object" ?
274 // jQuery.Event object
275 event[ jQuery.expando ] ? event :
277 jQuery.extend( jQuery.Event(type), event ) :
278 // Just the event type (string)
281 if ( type.indexOf("!") >= 0 ) {
282 event.type = type = type.slice(0, -1);
283 event.exclusive = true;
286 // Handle a global trigger
288 // Don't bubble custom events when global (to avoid too much overhead)
289 event.stopPropagation();
291 // Only trigger if we've ever bound an event for it
292 if ( jQuery.event.global[ type ] ) {
293 jQuery.each( jQuery.cache, function() {
294 if ( this.events && this.events[type] ) {
295 jQuery.event.trigger( event, data, this.handle.elem );
301 // Handle triggering a single element
303 // don't do events on text and comment nodes
304 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
308 // Clean up in case it is reused
309 event.result = undefined;
312 // Clone the incoming data, if any
313 data = jQuery.makeArray( data );
314 data.unshift( event );
317 event.currentTarget = elem;
319 // Trigger the event, it is assumed that "handle" is a function
320 var handle = jQuery.data( elem, "handle" );
322 handle.apply( elem, data );
325 var parent = elem.parentNode || elem.ownerDocument;
327 // Trigger an inline bound script
329 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
330 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
331 event.result = false;
335 // prevent IE from throwing an error for some elements with some event types, see #3533
336 } catch (inlineError) {}
338 if ( !event.isPropagationStopped() && parent ) {
339 jQuery.event.trigger( event, data, parent, true );
341 } else if ( !event.isDefaultPrevented() ) {
342 var target = event.target, old, targetType = type.replace(/\..*$/, ""),
343 isClick = jQuery.nodeName(target, "a") && targetType === "click",
344 special = jQuery.event.special[ targetType ] || {};
346 if ( (!special._default || special._default.call( elem, event ) === false) &&
347 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
350 if ( target[ targetType ] ) {
351 // Make sure that we don't accidentally re-trigger the onFOO events
352 old = target[ "on" + targetType ];
355 target[ "on" + targetType ] = null;
358 jQuery.event.triggered = true;
359 target[ targetType ]();
362 // prevent IE from throwing an error for some elements with some event types, see #3533
363 } catch (triggerError) {}
366 target[ "on" + targetType ] = old;
369 jQuery.event.triggered = false;
374 handle: function( event ) {
375 var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
377 event = args[0] = jQuery.event.fix( event || window.event );
378 event.currentTarget = this;
380 // Namespaced event handlers
381 all = event.type.indexOf(".") < 0 && !event.exclusive;
384 namespaces = event.type.split(".");
385 event.type = namespaces.shift();
386 namespace_sort = namespaces.slice(0).sort();
387 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
390 event.namespace = event.namespace || namespace_sort.join(".");
392 events = jQuery.data(this, "events");
393 handlers = (events || {})[ event.type ];
395 if ( events && handlers ) {
396 // Clone the handlers to prevent manipulation
397 handlers = handlers.slice(0);
399 for ( var j = 0, l = handlers.length; j < l; j++ ) {
400 var handleObj = handlers[ j ];
402 // Filter the functions by class
403 if ( all || namespace_re.test( handleObj.namespace ) ) {
404 // Pass in a reference to the handler function itself
405 // So that we can later remove it
406 event.handler = handleObj.handler;
407 event.data = handleObj.data;
408 event.handleObj = handleObj;
410 var ret = handleObj.handler.apply( this, args );
412 if ( ret !== undefined ) {
414 if ( ret === false ) {
415 event.preventDefault();
416 event.stopPropagation();
420 if ( event.isImmediatePropagationStopped() ) {
430 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(" "),
432 fix: function( event ) {
433 if ( event[ jQuery.expando ] ) {
437 // store a copy of the original event object
438 // and "clone" to set read-only properties
439 var originalEvent = event;
440 event = jQuery.Event( originalEvent );
442 for ( var i = this.props.length, prop; i; ) {
443 prop = this.props[ --i ];
444 event[ prop ] = originalEvent[ prop ];
447 // Fix target property, if necessary
448 if ( !event.target ) {
449 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
452 // check if target is a textnode (safari)
453 if ( event.target.nodeType === 3 ) {
454 event.target = event.target.parentNode;
457 // Add relatedTarget, if necessary
458 if ( !event.relatedTarget && event.fromElement ) {
459 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
462 // Calculate pageX/Y if missing and clientX/Y available
463 if ( event.pageX == null && event.clientX != null ) {
464 var doc = document.documentElement, body = document.body;
465 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
466 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
469 // Add which for key events
470 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
471 event.which = event.charCode || event.keyCode;
474 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
475 if ( !event.metaKey && event.ctrlKey ) {
476 event.metaKey = event.ctrlKey;
479 // Add which for click: 1 === left; 2 === middle; 3 === right
480 // Note: button is not normalized, so don't use it
481 if ( !event.which && event.button !== undefined ) {
482 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
488 // Deprecated, use jQuery.guid instead
491 // Deprecated, use jQuery.proxy instead
496 // Make sure the ready event is setup
497 setup: jQuery.bindReady,
498 teardown: jQuery.noop
502 add: function( handleObj ) {
503 jQuery.event.add( this,
504 liveConvert( handleObj.origType, handleObj.selector ),
505 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
508 remove: function( handleObj ) {
509 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
514 setup: function( data, namespaces, eventHandle ) {
515 // We only want to do this special case on windows
516 if ( this.setInterval ) {
517 this.onbeforeunload = eventHandle;
521 teardown: function( namespaces, eventHandle ) {
522 if ( this.onbeforeunload === eventHandle ) {
523 this.onbeforeunload = null;
530 jQuery.removeEvent = document.removeEventListener ?
531 function( elem, type, handle ) {
532 if ( elem.removeEventListener ) {
533 elem.removeEventListener( type, handle, false );
536 function( elem, type, handle ) {
537 if ( elem.detachEvent ) {
538 elem.detachEvent( "on" + type, handle );
542 jQuery.Event = function( src ) {
543 // Allow instantiation without the 'new' keyword
544 if ( !this.preventDefault ) {
545 return new jQuery.Event( src );
549 if ( src && src.type ) {
550 this.originalEvent = src;
551 this.type = src.type;
557 // timeStamp is buggy for some events on Firefox(#3843)
558 // So we won't rely on the native value
559 this.timeStamp = jQuery.now();
562 this[ jQuery.expando ] = true;
565 function returnFalse() {
568 function returnTrue() {
572 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
573 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
574 jQuery.Event.prototype = {
575 preventDefault: function() {
576 this.isDefaultPrevented = returnTrue;
578 var e = this.originalEvent;
583 // if preventDefault exists run it on the original event
584 if ( e.preventDefault ) {
587 // otherwise set the returnValue property of the original event to false (IE)
589 e.returnValue = false;
592 stopPropagation: function() {
593 this.isPropagationStopped = returnTrue;
595 var e = this.originalEvent;
599 // if stopPropagation exists run it on the original event
600 if ( e.stopPropagation ) {
603 // otherwise set the cancelBubble property of the original event to true (IE)
604 e.cancelBubble = true;
606 stopImmediatePropagation: function() {
607 this.isImmediatePropagationStopped = returnTrue;
608 this.stopPropagation();
610 isDefaultPrevented: returnFalse,
611 isPropagationStopped: returnFalse,
612 isImmediatePropagationStopped: returnFalse
615 // Checks if an event happened on an element within another element
616 // Used in jQuery.event.special.mouseenter and mouseleave handlers
617 var withinElement = function( event ) {
618 // Check if mouse(over|out) are still within the same parent element
619 var parent = event.relatedTarget;
621 // Firefox sometimes assigns relatedTarget a XUL element
622 // which we cannot access the parentNode property of
624 // Traverse up the tree
625 while ( parent && parent !== this ) {
626 parent = parent.parentNode;
629 if ( parent !== this ) {
630 // set the correct event type
631 event.type = event.data;
633 // handle event if we actually just moused on to a non sub-element
634 jQuery.event.handle.apply( this, arguments );
637 // assuming we've left the element since we most likely mousedover a xul element
641 // In case of event delegation, we only need to rename the event.type,
642 // liveHandler will take care of the rest.
643 delegate = function( event ) {
644 event.type = event.data;
645 jQuery.event.handle.apply( this, arguments );
648 // Create mouseenter and mouseleave events
650 mouseenter: "mouseover",
651 mouseleave: "mouseout"
652 }, function( orig, fix ) {
653 jQuery.event.special[ orig ] = {
654 setup: function( data ) {
655 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
657 teardown: function( data ) {
658 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
664 if ( !jQuery.support.submitBubbles ) {
666 jQuery.event.special.submit = {
667 setup: function( data, namespaces ) {
668 if ( this.nodeName.toLowerCase() !== "form" ) {
669 jQuery.event.add(this, "click.specialSubmit", function( e ) {
670 var elem = e.target, type = elem.type;
672 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
673 return trigger( "submit", this, arguments );
677 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
678 var elem = e.target, type = elem.type;
680 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
681 return trigger( "submit", this, arguments );
690 teardown: function( namespaces ) {
691 jQuery.event.remove( this, ".specialSubmit" );
697 // change delegation, happens here so we have bind.
698 if ( !jQuery.support.changeBubbles ) {
700 var formElems = /textarea|input|select/i,
704 getVal = function( elem ) {
705 var type = elem.type, val = elem.value;
707 if ( type === "radio" || type === "checkbox" ) {
710 } else if ( type === "select-multiple" ) {
711 val = elem.selectedIndex > -1 ?
712 jQuery.map( elem.options, function( elem ) {
713 return elem.selected;
717 } else if ( elem.nodeName.toLowerCase() === "select" ) {
718 val = elem.selectedIndex;
724 testChange = function testChange( e ) {
725 var elem = e.target, data, val;
727 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
731 data = jQuery.data( elem, "_change_data" );
734 // the current data will be also retrieved by beforeactivate
735 if ( e.type !== "focusout" || elem.type !== "radio" ) {
736 jQuery.data( elem, "_change_data", val );
739 if ( data === undefined || val === data ) {
743 if ( data != null || val ) {
745 return jQuery.event.trigger( e, arguments[1], elem );
749 jQuery.event.special.change = {
751 focusout: testChange,
753 click: function( e ) {
754 var elem = e.target, type = elem.type;
756 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
757 return testChange.call( this, e );
761 // Change has to be called before submit
762 // Keydown will be called before keypress, which is used in submit-event delegation
763 keydown: function( e ) {
764 var elem = e.target, type = elem.type;
766 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
767 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
768 type === "select-multiple" ) {
769 return testChange.call( this, e );
773 // Beforeactivate happens also before the previous element is blurred
774 // with this event you can't trigger a change event, but you can store
775 // information/focus[in] is not needed anymore
776 beforeactivate: function( e ) {
778 jQuery.data( elem, "_change_data", getVal(elem) );
782 setup: function( data, namespaces ) {
783 if ( this.type === "file" ) {
787 for ( var type in changeFilters ) {
788 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
791 return formElems.test( this.nodeName );
794 teardown: function( namespaces ) {
795 jQuery.event.remove( this, ".specialChange" );
797 return formElems.test( this.nodeName );
801 changeFilters = jQuery.event.special.change.filters;
804 function trigger( type, elem, args ) {
806 return jQuery.event.handle.apply( elem, args );
809 // Create "bubbling" focus and blur events
810 if ( document.addEventListener ) {
811 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
812 jQuery.event.special[ fix ] = {
814 this.addEventListener( orig, handler, true );
816 teardown: function() {
817 this.removeEventListener( orig, handler, true );
821 function handler( e ) {
822 e = jQuery.event.fix( e );
824 return jQuery.event.handle.call( this, e );
829 jQuery.each(["bind", "one"], function( i, name ) {
830 jQuery.fn[ name ] = function( type, data, fn ) {
831 // Handle object literals
832 if ( typeof type === "object" ) {
833 for ( var key in type ) {
834 this[ name ](key, data, type[key], fn);
839 if ( jQuery.isFunction( data ) || data === false ) {
844 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
845 jQuery( this ).unbind( event, handler );
846 return fn.apply( this, arguments );
849 if ( type === "unload" && name !== "one" ) {
850 this.one( type, data, fn );
853 for ( var i = 0, l = this.length; i < l; i++ ) {
854 jQuery.event.add( this[i], type, handler, data );
863 unbind: function( type, fn ) {
864 // Handle object literals
865 if ( typeof type === "object" && !type.preventDefault ) {
866 for ( var key in type ) {
867 this.unbind(key, type[key]);
871 for ( var i = 0, l = this.length; i < l; i++ ) {
872 jQuery.event.remove( this[i], type, fn );
879 delegate: function( selector, types, data, fn ) {
880 return this.live( types, data, fn, selector );
883 undelegate: function( selector, types, fn ) {
884 if ( arguments.length === 0 ) {
885 return this.unbind( "live" );
888 return this.die( types, null, fn, selector );
892 trigger: function( type, data ) {
893 return this.each(function() {
894 jQuery.event.trigger( type, data, this );
898 triggerHandler: function( type, data ) {
900 var event = jQuery.Event( type );
901 event.preventDefault();
902 event.stopPropagation();
903 jQuery.event.trigger( event, data, this[0] );
908 toggle: function( fn ) {
909 // Save reference to arguments for access in closure
910 var args = arguments, i = 1;
912 // link all the functions, so any of them can unbind this click handler
913 while ( i < args.length ) {
914 jQuery.proxy( fn, args[ i++ ] );
917 return this.click( jQuery.proxy( fn, function( event ) {
918 // Figure out which function to execute
919 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
920 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
922 // Make sure that clicks stop
923 event.preventDefault();
925 // and execute the function
926 return args[ lastToggle ].apply( this, arguments ) || false;
930 hover: function( fnOver, fnOut ) {
931 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
938 mouseenter: "mouseover",
939 mouseleave: "mouseout"
942 jQuery.each(["live", "die"], function( i, name ) {
943 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
944 var type, i = 0, match, namespaces, preType,
945 selector = origSelector || this.selector,
946 context = origSelector ? this : jQuery( this.context );
948 if ( jQuery.isFunction( data ) ) {
953 types = (types || "").split(" ");
955 while ( (type = types[ i++ ]) != null ) {
956 match = rnamespaces.exec( type );
960 namespaces = match[0];
961 type = type.replace( rnamespaces, "" );
964 if ( type === "hover" ) {
965 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
971 if ( type === "focus" || type === "blur" ) {
972 types.push( liveMap[ type ] + namespaces );
973 type = type + namespaces;
976 type = (liveMap[ type ] || type) + namespaces;
979 if ( name === "live" ) {
981 for ( var j = 0, l = context.length; j < l; j++ ) {
982 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
983 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
987 // unbind live handler
988 context.unbind( "live." + liveConvert( type, selector ), fn );
996 function liveHandler( event ) {
997 var stop, maxLevel, elems = [], selectors = [],
998 related, match, handleObj, elem, j, i, l, data, close, namespace,
999 events = jQuery.data( this, "events" );
1001 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
1002 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1006 if ( event.namespace ) {
1007 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
1010 event.liveFired = this;
1012 var live = events.live.slice(0);
1014 for ( j = 0; j < live.length; j++ ) {
1015 handleObj = live[j];
1017 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1018 selectors.push( handleObj.selector );
1021 live.splice( j--, 1 );
1025 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1027 for ( i = 0, l = match.length; i < l; i++ ) {
1030 for ( j = 0; j < live.length; j++ ) {
1031 handleObj = live[j];
1033 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
1037 // Those two events require additional checking
1038 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1039 event.type = handleObj.preType;
1040 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1043 if ( !related || related !== elem ) {
1044 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1050 for ( i = 0, l = elems.length; i < l; i++ ) {
1053 if ( maxLevel && match.level > maxLevel ) {
1057 event.currentTarget = match.elem;
1058 event.data = match.handleObj.data;
1059 event.handleObj = match.handleObj;
1061 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1063 if ( ret === false || event.isPropagationStopped() ) {
1064 maxLevel = match.level;
1066 if ( ret === false ) {
1075 function liveConvert( type, selector ) {
1076 return (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
1079 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1080 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1081 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1083 // Handle event binding
1084 jQuery.fn[ name ] = function( data, fn ) {
1090 return arguments.length > 0 ?
1091 this.bind( name, data, fn ) :
1092 this.trigger( name );
1095 if ( jQuery.attrFn ) {
1096 jQuery.attrFn[ name ] = true;
1100 // Prevent memory leaks in IE
1101 // Window isn't included so as not to unbind existing unload events
1103 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1104 if ( window.attachEvent && !window.addEventListener ) {
1105 window.attachEvent("onunload", function() {
1106 for ( var id in jQuery.cache ) {
1107 if ( jQuery.cache[ id ].handle ) {
1108 // Try/Catch is to handle iframes being unloaded, see #4280
1110 jQuery.event.remove( jQuery.cache[ id ].handle.elem );