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)
588 e.returnValue = false;
590 stopPropagation: function() {
591 this.isPropagationStopped = returnTrue;
593 var e = this.originalEvent;
597 // if stopPropagation exists run it on the original event
598 if ( e.stopPropagation ) {
601 // otherwise set the cancelBubble property of the original event to true (IE)
602 e.cancelBubble = true;
604 stopImmediatePropagation: function() {
605 this.isImmediatePropagationStopped = returnTrue;
606 this.stopPropagation();
608 isDefaultPrevented: returnFalse,
609 isPropagationStopped: returnFalse,
610 isImmediatePropagationStopped: returnFalse
613 // Checks if an event happened on an element within another element
614 // Used in jQuery.event.special.mouseenter and mouseleave handlers
615 var withinElement = function( event ) {
616 // Check if mouse(over|out) are still within the same parent element
617 var parent = event.relatedTarget;
619 // Firefox sometimes assigns relatedTarget a XUL element
620 // which we cannot access the parentNode property of
622 // Traverse up the tree
623 while ( parent && parent !== this ) {
624 parent = parent.parentNode;
627 if ( parent !== this ) {
628 // set the correct event type
629 event.type = event.data;
631 // handle event if we actually just moused on to a non sub-element
632 jQuery.event.handle.apply( this, arguments );
635 // assuming we've left the element since we most likely mousedover a xul element
639 // In case of event delegation, we only need to rename the event.type,
640 // liveHandler will take care of the rest.
641 delegate = function( event ) {
642 event.type = event.data;
643 jQuery.event.handle.apply( this, arguments );
646 // Create mouseenter and mouseleave events
648 mouseenter: "mouseover",
649 mouseleave: "mouseout"
650 }, function( orig, fix ) {
651 jQuery.event.special[ orig ] = {
652 setup: function( data ) {
653 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
655 teardown: function( data ) {
656 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
662 if ( !jQuery.support.submitBubbles ) {
664 jQuery.event.special.submit = {
665 setup: function( data, namespaces ) {
666 if ( this.nodeName.toLowerCase() !== "form" ) {
667 jQuery.event.add(this, "click.specialSubmit", function( e ) {
668 var elem = e.target, type = elem.type;
670 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
671 return trigger( "submit", this, arguments );
675 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
676 var elem = e.target, type = elem.type;
678 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
679 return trigger( "submit", this, arguments );
688 teardown: function( namespaces ) {
689 jQuery.event.remove( this, ".specialSubmit" );
695 // change delegation, happens here so we have bind.
696 if ( !jQuery.support.changeBubbles ) {
698 var formElems = /textarea|input|select/i,
702 getVal = function( elem ) {
703 var type = elem.type, val = elem.value;
705 if ( type === "radio" || type === "checkbox" ) {
708 } else if ( type === "select-multiple" ) {
709 val = elem.selectedIndex > -1 ?
710 jQuery.map( elem.options, function( elem ) {
711 return elem.selected;
715 } else if ( elem.nodeName.toLowerCase() === "select" ) {
716 val = elem.selectedIndex;
722 testChange = function testChange( e ) {
723 var elem = e.target, data, val;
725 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
729 data = jQuery.data( elem, "_change_data" );
732 // the current data will be also retrieved by beforeactivate
733 if ( e.type !== "focusout" || elem.type !== "radio" ) {
734 jQuery.data( elem, "_change_data", val );
737 if ( data === undefined || val === data ) {
741 if ( data != null || val ) {
743 return jQuery.event.trigger( e, arguments[1], elem );
747 jQuery.event.special.change = {
749 focusout: testChange,
751 click: function( e ) {
752 var elem = e.target, type = elem.type;
754 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
755 return testChange.call( this, e );
759 // Change has to be called before submit
760 // Keydown will be called before keypress, which is used in submit-event delegation
761 keydown: function( e ) {
762 var elem = e.target, type = elem.type;
764 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
765 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
766 type === "select-multiple" ) {
767 return testChange.call( this, e );
771 // Beforeactivate happens also before the previous element is blurred
772 // with this event you can't trigger a change event, but you can store
773 // information/focus[in] is not needed anymore
774 beforeactivate: function( e ) {
776 jQuery.data( elem, "_change_data", getVal(elem) );
780 setup: function( data, namespaces ) {
781 if ( this.type === "file" ) {
785 for ( var type in changeFilters ) {
786 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
789 return formElems.test( this.nodeName );
792 teardown: function( namespaces ) {
793 jQuery.event.remove( this, ".specialChange" );
795 return formElems.test( this.nodeName );
799 changeFilters = jQuery.event.special.change.filters;
802 function trigger( type, elem, args ) {
804 return jQuery.event.handle.apply( elem, args );
807 // Create "bubbling" focus and blur events
808 if ( document.addEventListener ) {
809 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
810 jQuery.event.special[ fix ] = {
812 this.addEventListener( orig, handler, true );
814 teardown: function() {
815 this.removeEventListener( orig, handler, true );
819 function handler( e ) {
820 e = jQuery.event.fix( e );
822 return jQuery.event.handle.call( this, e );
827 jQuery.each(["bind", "one"], function( i, name ) {
828 jQuery.fn[ name ] = function( type, data, fn ) {
829 // Handle object literals
830 if ( typeof type === "object" ) {
831 for ( var key in type ) {
832 this[ name ](key, data, type[key], fn);
837 if ( jQuery.isFunction( data ) || data === false ) {
842 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
843 jQuery( this ).unbind( event, handler );
844 return fn.apply( this, arguments );
847 if ( type === "unload" && name !== "one" ) {
848 this.one( type, data, fn );
851 for ( var i = 0, l = this.length; i < l; i++ ) {
852 jQuery.event.add( this[i], type, handler, data );
861 unbind: function( type, fn ) {
862 // Handle object literals
863 if ( typeof type === "object" && !type.preventDefault ) {
864 for ( var key in type ) {
865 this.unbind(key, type[key]);
869 for ( var i = 0, l = this.length; i < l; i++ ) {
870 jQuery.event.remove( this[i], type, fn );
877 delegate: function( selector, types, data, fn ) {
878 return this.live( types, data, fn, selector );
881 undelegate: function( selector, types, fn ) {
882 if ( arguments.length === 0 ) {
883 return this.unbind( "live" );
886 return this.die( types, null, fn, selector );
890 trigger: function( type, data ) {
891 return this.each(function() {
892 jQuery.event.trigger( type, data, this );
896 triggerHandler: function( type, data ) {
898 var event = jQuery.Event( type );
899 event.preventDefault();
900 event.stopPropagation();
901 jQuery.event.trigger( event, data, this[0] );
906 toggle: function( fn ) {
907 // Save reference to arguments for access in closure
908 var args = arguments, i = 1;
910 // link all the functions, so any of them can unbind this click handler
911 while ( i < args.length ) {
912 jQuery.proxy( fn, args[ i++ ] );
915 return this.click( jQuery.proxy( fn, function( event ) {
916 // Figure out which function to execute
917 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
918 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
920 // Make sure that clicks stop
921 event.preventDefault();
923 // and execute the function
924 return args[ lastToggle ].apply( this, arguments ) || false;
928 hover: function( fnOver, fnOut ) {
929 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
936 mouseenter: "mouseover",
937 mouseleave: "mouseout"
940 jQuery.each(["live", "die"], function( i, name ) {
941 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
942 var type, i = 0, match, namespaces, preType,
943 selector = origSelector || this.selector,
944 context = origSelector ? this : jQuery( this.context );
946 if ( jQuery.isFunction( data ) ) {
951 types = (types || "").split(" ");
953 while ( (type = types[ i++ ]) != null ) {
954 match = rnamespaces.exec( type );
958 namespaces = match[0];
959 type = type.replace( rnamespaces, "" );
962 if ( type === "hover" ) {
963 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
969 if ( type === "focus" || type === "blur" ) {
970 types.push( liveMap[ type ] + namespaces );
971 type = type + namespaces;
974 type = (liveMap[ type ] || type) + namespaces;
977 if ( name === "live" ) {
979 for ( var j = 0, l = context.length; j < l; j++ ) {
980 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
981 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
985 // unbind live handler
986 context.unbind( "live." + liveConvert( type, selector ), fn );
994 function liveHandler( event ) {
995 var stop, maxLevel, elems = [], selectors = [],
996 related, match, handleObj, elem, j, i, l, data, close, namespace,
997 events = jQuery.data( this, "events" );
999 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
1000 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1004 if ( event.namespace ) {
1005 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
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 && (!namespace || namespace.test( handleObj.namespace )) ) {
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 (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 );