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 if ( !handleObj.guid ) {
94 handleObj.guid = handler.guid;
97 // Get the current list of functions bound to this event
98 var handlers = events[ type ],
99 special = jQuery.event.special[ type ] || {};
101 // Init the event handler queue
103 handlers = events[ type ] = [];
105 // Check for a special event handler
106 // Only use addEventListener/attachEvent if the special
107 // events handler returns false
108 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
109 // Bind the global event handler to the element
110 if ( elem.addEventListener ) {
111 elem.addEventListener( type, eventHandle, false );
113 } else if ( elem.attachEvent ) {
114 elem.attachEvent( "on" + type, eventHandle );
120 special.add.call( elem, handleObj );
122 if ( !handleObj.handler.guid ) {
123 handleObj.handler.guid = handler.guid;
127 // Add the function to the element's handler list
128 handlers.push( handleObj );
130 // Keep track of which events have been used, for global triggering
131 jQuery.event.global[ type ] = true;
134 // Nullify elem to prevent memory leaks in IE
140 // Detach an event or set of events from an element
141 remove: function( elem, types, handler, pos ) {
142 // don't do events on text and comment nodes
143 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
147 if ( handler === false ) {
148 handler = returnFalse;
151 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
152 elemData = jQuery.data( elem ),
153 events = elemData && elemData.events;
155 if ( !elemData || !events ) {
159 // types is actually an event object here
160 if ( types && types.type ) {
161 handler = types.handler;
165 // Unbind all events for the element
166 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
169 for ( type in events ) {
170 jQuery.event.remove( elem, type + types );
176 // Handle multiple events separated by a space
177 // jQuery(...).unbind("mouseover mouseout", fn);
178 types = types.split(" ");
180 while ( (type = types[ i++ ]) ) {
183 all = type.indexOf(".") < 0;
187 // Namespaced event handlers
188 namespaces = type.split(".");
189 type = namespaces.shift();
191 namespace = new RegExp("(^|\\.)" +
192 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
195 eventType = events[ type ];
202 for ( j = 0; j < eventType.length; j++ ) {
203 handleObj = eventType[ j ];
205 if ( all || namespace.test( handleObj.namespace ) ) {
206 jQuery.event.remove( elem, origType, handleObj.handler, j );
207 eventType.splice( j--, 1 );
214 special = jQuery.event.special[ type ] || {};
216 for ( j = pos || 0; j < eventType.length; j++ ) {
217 handleObj = eventType[ j ];
219 if ( handler.guid === handleObj.guid ) {
220 // remove the given handler for the given type
221 if ( all || namespace.test( handleObj.namespace ) ) {
223 eventType.splice( j--, 1 );
226 if ( special.remove ) {
227 special.remove.call( elem, handleObj );
237 // remove generic event handler if no more handlers exist
238 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
239 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
240 removeEvent( elem, type, elemData.handle );
244 delete events[ type ];
248 // Remove the expando if it's no longer used
249 if ( jQuery.isEmptyObject( events ) ) {
250 var handle = elemData.handle;
255 delete elemData.events;
256 delete elemData.handle;
258 if ( jQuery.isEmptyObject( elemData ) ) {
259 jQuery.removeData( elem );
264 // bubbling is internal
265 trigger: function( event, data, elem /*, bubbling */ ) {
266 // Event object or event type
267 var type = event.type || event,
268 bubbling = arguments[3];
271 event = typeof event === "object" ?
272 // jQuery.Event object
273 event[ jQuery.expando ] ? event :
275 jQuery.extend( jQuery.Event(type), event ) :
276 // Just the event type (string)
279 if ( type.indexOf("!") >= 0 ) {
280 event.type = type = type.slice(0, -1);
281 event.exclusive = true;
284 // Handle a global trigger
286 // Don't bubble custom events when global (to avoid too much overhead)
287 event.stopPropagation();
289 // Only trigger if we've ever bound an event for it
290 if ( jQuery.event.global[ type ] ) {
291 jQuery.each( jQuery.cache, function() {
292 if ( this.events && this.events[type] ) {
293 jQuery.event.trigger( event, data, this.handle.elem );
299 // Handle triggering a single element
301 // don't do events on text and comment nodes
302 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
306 // Clean up in case it is reused
307 event.result = undefined;
310 // Clone the incoming data, if any
311 data = jQuery.makeArray( data );
312 data.unshift( event );
315 event.currentTarget = elem;
317 // Trigger the event, it is assumed that "handle" is a function
318 var handle = jQuery.data( elem, "handle" );
320 handle.apply( elem, data );
323 var parent = elem.parentNode || elem.ownerDocument;
325 // Trigger an inline bound script
327 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
328 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
329 event.result = false;
333 // prevent IE from throwing an error for some elements with some event types, see #3533
334 } catch (inlineError) {}
336 if ( !event.isPropagationStopped() && parent ) {
337 jQuery.event.trigger( event, data, parent, true );
339 } else if ( !event.isDefaultPrevented() ) {
340 var target = event.target, old, targetType = type.replace(/\..*$/, ""),
341 isClick = jQuery.nodeName(target, "a") && targetType === "click",
342 special = jQuery.event.special[ targetType ] || {};
344 if ( (!special._default || special._default.call( elem, event ) === false) &&
345 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
348 if ( target[ targetType ] ) {
349 // Make sure that we don't accidentally re-trigger the onFOO events
350 old = target[ "on" + targetType ];
353 target[ "on" + targetType ] = null;
356 jQuery.event.triggered = true;
357 target[ targetType ]();
360 // prevent IE from throwing an error for some elements with some event types, see #3533
361 } catch (triggerError) {}
364 target[ "on" + targetType ] = old;
367 jQuery.event.triggered = false;
372 handle: function( event ) {
373 var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
375 event = args[0] = jQuery.event.fix( event || window.event );
376 event.currentTarget = this;
378 // Namespaced event handlers
379 all = event.type.indexOf(".") < 0 && !event.exclusive;
382 namespaces = event.type.split(".");
383 event.type = namespaces.shift();
384 namespace_sort = namespaces.slice(0).sort();
385 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
388 event.namespace = event.namespace || namespace_sort.join(".");
390 events = jQuery.data(this, "events");
391 handlers = (events || {})[ event.type ];
393 if ( events && handlers ) {
394 // Clone the handlers to prevent manipulation
395 handlers = handlers.slice(0);
397 for ( var j = 0, l = handlers.length; j < l; j++ ) {
398 var handleObj = handlers[ j ];
400 // Filter the functions by class
401 if ( all || namespace_re.test( handleObj.namespace ) ) {
402 // Pass in a reference to the handler function itself
403 // So that we can later remove it
404 event.handler = handleObj.handler;
405 event.data = handleObj.data;
406 event.handleObj = handleObj;
408 var ret = handleObj.handler.apply( this, args );
410 if ( ret !== undefined ) {
412 if ( ret === false ) {
413 event.preventDefault();
414 event.stopPropagation();
418 if ( event.isImmediatePropagationStopped() ) {
428 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(" "),
430 fix: function( event ) {
431 if ( event[ jQuery.expando ] ) {
435 // store a copy of the original event object
436 // and "clone" to set read-only properties
437 var originalEvent = event;
438 event = jQuery.Event( originalEvent );
440 for ( var i = this.props.length, prop; i; ) {
441 prop = this.props[ --i ];
442 event[ prop ] = originalEvent[ prop ];
445 // Fix target property, if necessary
446 if ( !event.target ) {
447 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
450 // check if target is a textnode (safari)
451 if ( event.target.nodeType === 3 ) {
452 event.target = event.target.parentNode;
455 // Add relatedTarget, if necessary
456 if ( !event.relatedTarget && event.fromElement ) {
457 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
460 // Calculate pageX/Y if missing and clientX/Y available
461 if ( event.pageX == null && event.clientX != null ) {
462 var doc = document.documentElement, body = document.body;
463 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
464 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
467 // Add which for key events
468 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
469 event.which = event.charCode || event.keyCode;
472 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
473 if ( !event.metaKey && event.ctrlKey ) {
474 event.metaKey = event.ctrlKey;
477 // Add which for click: 1 === left; 2 === middle; 3 === right
478 // Note: button is not normalized, so don't use it
479 if ( !event.which && event.button !== undefined ) {
480 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
486 // Deprecated, use jQuery.guid instead
489 // Deprecated, use jQuery.proxy instead
494 // Make sure the ready event is setup
495 setup: jQuery.bindReady,
496 teardown: jQuery.noop
500 add: function( handleObj ) {
501 jQuery.event.add( this,
502 liveConvert( handleObj.origType, handleObj.selector ),
503 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
506 remove: function( handleObj ) {
507 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
512 setup: function( data, namespaces, eventHandle ) {
513 // We only want to do this special case on windows
514 if ( this.setInterval ) {
515 this.onbeforeunload = eventHandle;
519 teardown: function( namespaces, eventHandle ) {
520 if ( this.onbeforeunload === eventHandle ) {
521 this.onbeforeunload = null;
528 var removeEvent = document.removeEventListener ?
529 function( elem, type, handle ) {
530 if ( elem.removeEventListener ) {
531 elem.removeEventListener( type, handle, false );
534 function( elem, type, handle ) {
535 if ( elem.detachEvent ) {
536 elem.detachEvent( "on" + type, handle );
540 jQuery.Event = function( src ) {
541 // Allow instantiation without the 'new' keyword
542 if ( !this.preventDefault ) {
543 return new jQuery.Event( src );
547 if ( src && src.type ) {
548 this.originalEvent = src;
549 this.type = src.type;
555 // timeStamp is buggy for some events on Firefox(#3843)
556 // So we won't rely on the native value
557 this.timeStamp = jQuery.now();
560 this[ jQuery.expando ] = true;
563 function returnFalse() {
566 function returnTrue() {
570 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
571 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
572 jQuery.Event.prototype = {
573 preventDefault: function() {
574 this.isDefaultPrevented = returnTrue;
576 var e = this.originalEvent;
581 // if preventDefault exists run it on the original event
582 if ( e.preventDefault ) {
585 // otherwise set the returnValue property of the original event to false (IE)
586 e.returnValue = false;
588 stopPropagation: function() {
589 this.isPropagationStopped = returnTrue;
591 var e = this.originalEvent;
595 // if stopPropagation exists run it on the original event
596 if ( e.stopPropagation ) {
599 // otherwise set the cancelBubble property of the original event to true (IE)
600 e.cancelBubble = true;
602 stopImmediatePropagation: function() {
603 this.isImmediatePropagationStopped = returnTrue;
604 this.stopPropagation();
606 isDefaultPrevented: returnFalse,
607 isPropagationStopped: returnFalse,
608 isImmediatePropagationStopped: returnFalse
611 // Checks if an event happened on an element within another element
612 // Used in jQuery.event.special.mouseenter and mouseleave handlers
613 var withinElement = function( event ) {
614 // Check if mouse(over|out) are still within the same parent element
615 var parent = event.relatedTarget;
617 // Firefox sometimes assigns relatedTarget a XUL element
618 // which we cannot access the parentNode property of
620 // Traverse up the tree
621 while ( parent && parent !== this ) {
622 parent = parent.parentNode;
625 if ( parent !== this ) {
626 // set the correct event type
627 event.type = event.data;
629 // handle event if we actually just moused on to a non sub-element
630 jQuery.event.handle.apply( this, arguments );
633 // assuming we've left the element since we most likely mousedover a xul element
637 // In case of event delegation, we only need to rename the event.type,
638 // liveHandler will take care of the rest.
639 delegate = function( event ) {
640 event.type = event.data;
641 jQuery.event.handle.apply( this, arguments );
644 // Create mouseenter and mouseleave events
646 mouseenter: "mouseover",
647 mouseleave: "mouseout"
648 }, function( orig, fix ) {
649 jQuery.event.special[ orig ] = {
650 setup: function( data ) {
651 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
653 teardown: function( data ) {
654 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
660 if ( !jQuery.support.submitBubbles ) {
662 jQuery.event.special.submit = {
663 setup: function( data, namespaces ) {
664 if ( this.nodeName.toLowerCase() !== "form" ) {
665 jQuery.event.add(this, "click.specialSubmit", function( e ) {
666 var elem = e.target, type = elem.type;
668 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
669 return trigger( "submit", this, arguments );
673 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
674 var elem = e.target, type = elem.type;
676 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
677 return trigger( "submit", this, arguments );
686 teardown: function( namespaces ) {
687 jQuery.event.remove( this, ".specialSubmit" );
693 // change delegation, happens here so we have bind.
694 if ( !jQuery.support.changeBubbles ) {
696 var formElems = /textarea|input|select/i,
700 getVal = function( elem ) {
701 var type = elem.type, val = elem.value;
703 if ( type === "radio" || type === "checkbox" ) {
706 } else if ( type === "select-multiple" ) {
707 val = elem.selectedIndex > -1 ?
708 jQuery.map( elem.options, function( elem ) {
709 return elem.selected;
713 } else if ( elem.nodeName.toLowerCase() === "select" ) {
714 val = elem.selectedIndex;
720 testChange = function testChange( e ) {
721 var elem = e.target, data, val;
723 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
727 data = jQuery.data( elem, "_change_data" );
730 // the current data will be also retrieved by beforeactivate
731 if ( e.type !== "focusout" || elem.type !== "radio" ) {
732 jQuery.data( elem, "_change_data", val );
735 if ( data === undefined || val === data ) {
739 if ( data != null || val ) {
741 return jQuery.event.trigger( e, arguments[1], elem );
745 jQuery.event.special.change = {
747 focusout: testChange,
749 click: function( e ) {
750 var elem = e.target, type = elem.type;
752 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
753 return testChange.call( this, e );
757 // Change has to be called before submit
758 // Keydown will be called before keypress, which is used in submit-event delegation
759 keydown: function( e ) {
760 var elem = e.target, type = elem.type;
762 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
763 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
764 type === "select-multiple" ) {
765 return testChange.call( this, e );
769 // Beforeactivate happens also before the previous element is blurred
770 // with this event you can't trigger a change event, but you can store
771 // information/focus[in] is not needed anymore
772 beforeactivate: function( e ) {
774 jQuery.data( elem, "_change_data", getVal(elem) );
778 setup: function( data, namespaces ) {
779 if ( this.type === "file" ) {
783 for ( var type in changeFilters ) {
784 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
787 return formElems.test( this.nodeName );
790 teardown: function( namespaces ) {
791 jQuery.event.remove( this, ".specialChange" );
793 return formElems.test( this.nodeName );
797 changeFilters = jQuery.event.special.change.filters;
800 function trigger( type, elem, args ) {
802 return jQuery.event.handle.apply( elem, args );
805 // Create "bubbling" focus and blur events
806 if ( document.addEventListener ) {
807 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
808 jQuery.event.special[ fix ] = {
810 this.addEventListener( orig, handler, true );
812 teardown: function() {
813 this.removeEventListener( orig, handler, true );
817 function handler( e ) {
818 e = jQuery.event.fix( e );
820 return jQuery.event.handle.call( this, e );
825 jQuery.each(["bind", "one"], function( i, name ) {
826 jQuery.fn[ name ] = function( type, data, fn ) {
827 // Handle object literals
828 if ( typeof type === "object" ) {
829 for ( var key in type ) {
830 this[ name ](key, data, type[key], fn);
835 if ( jQuery.isFunction( data ) || data === false ) {
840 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
841 jQuery( this ).unbind( event, handler );
842 return fn.apply( this, arguments );
845 if ( type === "unload" && name !== "one" ) {
846 this.one( type, data, fn );
849 for ( var i = 0, l = this.length; i < l; i++ ) {
850 jQuery.event.add( this[i], type, handler, data );
859 unbind: function( type, fn ) {
860 // Handle object literals
861 if ( typeof type === "object" && !type.preventDefault ) {
862 for ( var key in type ) {
863 this.unbind(key, type[key]);
867 for ( var i = 0, l = this.length; i < l; i++ ) {
868 jQuery.event.remove( this[i], type, fn );
875 delegate: function( selector, types, data, fn ) {
876 return this.live( types, data, fn, selector );
879 undelegate: function( selector, types, fn ) {
880 if ( arguments.length === 0 ) {
881 return this.unbind( "live" );
884 return this.die( types, null, fn, selector );
888 trigger: function( type, data ) {
889 return this.each(function() {
890 jQuery.event.trigger( type, data, this );
894 triggerHandler: function( type, data ) {
896 var event = jQuery.Event( type );
897 event.preventDefault();
898 event.stopPropagation();
899 jQuery.event.trigger( event, data, this[0] );
904 toggle: function( fn ) {
905 // Save reference to arguments for access in closure
906 var args = arguments, i = 1;
908 // link all the functions, so any of them can unbind this click handler
909 while ( i < args.length ) {
910 jQuery.proxy( fn, args[ i++ ] );
913 return this.click( jQuery.proxy( fn, function( event ) {
914 // Figure out which function to execute
915 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
916 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
918 // Make sure that clicks stop
919 event.preventDefault();
921 // and execute the function
922 return args[ lastToggle ].apply( this, arguments ) || false;
926 hover: function( fnOver, fnOut ) {
927 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
934 mouseenter: "mouseover",
935 mouseleave: "mouseout"
938 jQuery.each(["live", "die"], function( i, name ) {
939 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
940 var type, i = 0, match, namespaces, preType,
941 selector = origSelector || this.selector,
942 context = origSelector ? this : jQuery( this.context );
944 if ( jQuery.isFunction( data ) ) {
949 types = (types || "").split(" ");
951 while ( (type = types[ i++ ]) != null ) {
952 match = rnamespaces.exec( type );
956 namespaces = match[0];
957 type = type.replace( rnamespaces, "" );
960 if ( type === "hover" ) {
961 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
967 if ( type === "focus" || type === "blur" ) {
968 types.push( liveMap[ type ] + namespaces );
969 type = type + namespaces;
972 type = (liveMap[ type ] || type) + namespaces;
975 if ( name === "live" ) {
977 for ( var j = 0, l = context.length; j < l; j++ ) {
978 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
979 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
983 // unbind live handler
984 context.unbind( "live." + liveConvert( type, selector ), fn );
992 function liveHandler( event ) {
993 var stop, maxLevel, elems = [], selectors = [],
994 related, match, handleObj, elem, j, i, l, data, close, namespace,
995 events = jQuery.data( this, "events" );
997 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
998 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1002 if ( event.namespace ) {
1003 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
1006 event.liveFired = this;
1008 var live = events.live.slice(0);
1010 for ( j = 0; j < live.length; j++ ) {
1011 handleObj = live[j];
1013 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1014 selectors.push( handleObj.selector );
1017 live.splice( j--, 1 );
1021 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1023 for ( i = 0, l = match.length; i < l; i++ ) {
1026 for ( j = 0; j < live.length; j++ ) {
1027 handleObj = live[j];
1029 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
1033 // Those two events require additional checking
1034 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1035 event.type = handleObj.preType;
1036 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1039 if ( !related || related !== elem ) {
1040 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1046 for ( i = 0, l = elems.length; i < l; i++ ) {
1049 if ( maxLevel && match.level > maxLevel ) {
1053 event.currentTarget = match.elem;
1054 event.data = match.handleObj.data;
1055 event.handleObj = match.handleObj;
1057 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1059 if ( ret === false || event.isPropagationStopped() ) {
1060 maxLevel = match.level;
1062 if ( ret === false ) {
1071 function liveConvert( type, selector ) {
1072 return (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
1075 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1076 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1077 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1079 // Handle event binding
1080 jQuery.fn[ name ] = function( data, fn ) {
1086 return arguments.length > 0 ?
1087 this.bind( name, data, fn ) :
1088 this.trigger( name );
1091 if ( jQuery.attrFn ) {
1092 jQuery.attrFn[ name ] = true;
1096 // Prevent memory leaks in IE
1097 // Window isn't included so as not to unbind existing unload events
1099 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1100 if ( window.attachEvent && !window.addEventListener ) {
1101 window.attachEvent("onunload", function() {
1102 for ( var id in jQuery.cache ) {
1103 if ( jQuery.cache[ id ].handle ) {
1104 // Try/Catch is to handle iframes being unloaded, see #4280
1106 jQuery.event.remove( jQuery.cache[ id ].handle.elem );