1 var rnamespaces = /\.(.*)$/,
2 fcleanup = function( nm ) {
3 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
9 * A number of helper functions used for managing events.
10 * Many of the ideas behind this code originated from
11 * Dean Edwards' addEvent library.
15 // Bind an event to an element
16 // Original by Dean Edwards
17 add: function( elem, types, handler, data ) {
18 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
22 // For whatever reason, IE has trouble passing the window object
23 // around, causing it to be cloned in the process
24 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
28 if ( handler === false ) {
29 handler = returnFalse;
32 var handleObjIn, handleObj;
34 if ( handler.handler ) {
35 handleObjIn = handler;
36 handler = handleObjIn.handler;
39 // Make sure that the function being executed has a unique ID
40 if ( !handler.guid ) {
41 handler.guid = jQuery.guid++;
44 // Init the element's event structure
45 var elemData = jQuery.data( elem );
47 // If no elemData is found then we must be trying to bind to one of the
48 // banned noData elements
53 var events = elemData.events = elemData.events || {},
54 eventHandle = elemData.handle;
57 elemData.handle = eventHandle = function() {
58 // Handle the second event of a trigger and when
59 // an event is called after a page has unloaded
60 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
61 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
66 // Add elem as a property of the handle function
67 // This is to prevent a memory leak with non-native events in IE.
68 eventHandle.elem = elem;
70 // Handle multiple events separated by a space
71 // jQuery(...).bind("mouseover mouseout", fn);
72 types = types.split(" ");
74 var type, i = 0, namespaces;
76 while ( (type = types[ i++ ]) ) {
77 handleObj = handleObjIn ?
78 jQuery.extend({}, handleObjIn) :
79 { handler: handler, data: data };
81 // Namespaced event handlers
82 if ( type.indexOf(".") > -1 ) {
83 namespaces = type.split(".");
84 type = namespaces.shift();
85 handleObj.namespace = namespaces.slice(0).sort().join(".");
89 handleObj.namespace = "";
92 handleObj.type = type;
93 handleObj.guid = handler.guid;
95 // Get the current list of functions bound to this event
96 var handlers = events[ type ],
97 special = jQuery.event.special[ type ] || {};
99 // Init the event handler queue
101 handlers = events[ type ] = [];
103 // Check for a special event handler
104 // Only use addEventListener/attachEvent if the special
105 // events handler returns false
106 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
107 // Bind the global event handler to the element
108 if ( elem.addEventListener ) {
109 elem.addEventListener( type, eventHandle, false );
111 } else if ( elem.attachEvent ) {
112 elem.attachEvent( "on" + type, eventHandle );
118 special.add.call( elem, handleObj );
120 if ( !handleObj.handler.guid ) {
121 handleObj.handler.guid = handler.guid;
125 // Add the function to the element's handler list
126 handlers.push( handleObj );
128 // Keep track of which events have been used, for global triggering
129 jQuery.event.global[ type ] = true;
132 // Nullify elem to prevent memory leaks in IE
138 // Detach an event or set of events from an element
139 remove: function( elem, types, handler, pos ) {
140 // don't do events on text and comment nodes
141 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
145 if ( handler === false ) {
146 handler = returnFalse;
149 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
150 elemData = jQuery.data( elem ),
151 events = elemData && elemData.events;
153 if ( !elemData || !events ) {
157 // types is actually an event object here
158 if ( types && types.type ) {
159 handler = types.handler;
163 // Unbind all events for the element
164 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
167 for ( type in events ) {
168 jQuery.event.remove( elem, type + types );
174 // Handle multiple events separated by a space
175 // jQuery(...).unbind("mouseover mouseout", fn);
176 types = types.split(" ");
178 while ( (type = types[ i++ ]) ) {
181 all = type.indexOf(".") < 0;
185 // Namespaced event handlers
186 namespaces = type.split(".");
187 type = namespaces.shift();
189 namespace = new RegExp("(^|\\.)" +
190 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
193 eventType = events[ type ];
200 for ( j = 0; j < eventType.length; j++ ) {
201 handleObj = eventType[ j ];
203 if ( all || namespace.test( handleObj.namespace ) ) {
204 jQuery.event.remove( elem, origType, handleObj.handler, j );
205 eventType.splice( j--, 1 );
212 special = jQuery.event.special[ type ] || {};
214 for ( j = pos || 0; j < eventType.length; j++ ) {
215 handleObj = eventType[ j ];
217 if ( handler.guid === handleObj.guid ) {
218 // remove the given handler for the given type
219 if ( all || namespace.test( handleObj.namespace ) ) {
221 eventType.splice( j--, 1 );
224 if ( special.remove ) {
225 special.remove.call( elem, handleObj );
235 // remove generic event handler if no more handlers exist
236 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
237 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
238 removeEvent( elem, type, elemData.handle );
242 delete events[ type ];
246 // Remove the expando if it's no longer used
247 if ( jQuery.isEmptyObject( events ) ) {
248 var handle = elemData.handle;
253 delete elemData.events;
254 delete elemData.handle;
256 if ( jQuery.isEmptyObject( elemData ) ) {
257 jQuery.removeData( elem );
262 // bubbling is internal
263 trigger: function( event, data, elem /*, bubbling */ ) {
264 // Event object or event type
265 var type = event.type || event,
266 bubbling = arguments[3];
269 event = typeof event === "object" ?
270 // jQuery.Event object
271 event[expando] ? event :
273 jQuery.extend( jQuery.Event(type), event ) :
274 // Just the event type (string)
277 if ( type.indexOf("!") >= 0 ) {
278 event.type = type = type.slice(0, -1);
279 event.exclusive = true;
282 // Handle a global trigger
284 // Don't bubble custom events when global (to avoid too much overhead)
285 event.stopPropagation();
287 // Only trigger if we've ever bound an event for it
288 if ( jQuery.event.global[ type ] ) {
289 jQuery.each( jQuery.cache, function() {
290 if ( this.events && this.events[type] ) {
291 jQuery.event.trigger( event, data, this.handle.elem );
297 // Handle triggering a single element
299 // don't do events on text and comment nodes
300 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
304 // Clean up in case it is reused
305 event.result = undefined;
308 // Clone the incoming data, if any
309 data = jQuery.makeArray( data );
310 data.unshift( event );
313 event.currentTarget = elem;
315 // Trigger the event, it is assumed that "handle" is a function
316 var handle = jQuery.data( elem, "handle" );
318 handle.apply( elem, data );
321 var parent = elem.parentNode || elem.ownerDocument;
323 // Trigger an inline bound script
325 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
326 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
327 event.result = false;
331 // prevent IE from throwing an error for some elements with some event types, see #3533
332 } catch (inlineError) {}
334 if ( !event.isPropagationStopped() && parent ) {
335 jQuery.event.trigger( event, data, parent, true );
337 } else if ( !event.isDefaultPrevented() ) {
338 var target = event.target, old,
339 isClick = jQuery.nodeName(target, "a") && type === "click",
340 special = jQuery.event.special[ type ] || {};
342 if ( (!special._default || special._default.call( elem, event ) === false) &&
343 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
346 if ( target[ type ] ) {
347 // Make sure that we don't accidentally re-trigger the onFOO events
348 old = target[ "on" + type ];
351 target[ "on" + type ] = null;
354 jQuery.event.triggered = true;
358 // prevent IE from throwing an error for some elements with some event types, see #3533
359 } catch (triggerError) {}
362 target[ "on" + type ] = old;
365 jQuery.event.triggered = false;
370 handle: function( event ) {
371 var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
373 event = args[0] = jQuery.event.fix( event || window.event );
374 event.currentTarget = this;
376 // Namespaced event handlers
377 all = event.type.indexOf(".") < 0 && !event.exclusive;
380 namespaces = event.type.split(".");
381 event.type = namespaces.shift();
382 namespace_sort = namespaces.slice(0).sort();
383 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
384 event.namespace = namespace_sort.join(".");
387 events = jQuery.data(this, "events");
388 handlers = (events || {})[ event.type ];
390 if ( events && handlers ) {
391 // Clone the handlers to prevent manipulation
392 handlers = handlers.slice(0);
394 for ( var j = 0, l = handlers.length; j < l; j++ ) {
395 var handleObj = handlers[ j ];
397 // Filter the functions by class
398 if ( all || namespace_re.test( handleObj.namespace ) ) {
399 // Pass in a reference to the handler function itself
400 // So that we can later remove it
401 event.handler = handleObj.handler;
402 event.data = handleObj.data;
403 event.handleObj = handleObj;
405 var ret = handleObj.handler.apply( this, args );
407 if ( ret !== undefined ) {
409 if ( ret === false ) {
410 event.preventDefault();
411 event.stopPropagation();
415 if ( event.isImmediatePropagationStopped() ) {
425 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(" "),
427 fix: function( event ) {
428 if ( event[ expando ] ) {
432 // store a copy of the original event object
433 // and "clone" to set read-only properties
434 var originalEvent = event;
435 event = jQuery.Event( originalEvent );
437 for ( var i = this.props.length, prop; i; ) {
438 prop = this.props[ --i ];
439 event[ prop ] = originalEvent[ prop ];
442 // Fix target property, if necessary
443 if ( !event.target ) {
444 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
447 // check if target is a textnode (safari)
448 if ( event.target.nodeType === 3 ) {
449 event.target = event.target.parentNode;
452 // Add relatedTarget, if necessary
453 if ( !event.relatedTarget && event.fromElement ) {
454 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
457 // Calculate pageX/Y if missing and clientX/Y available
458 if ( event.pageX == null && event.clientX != null ) {
459 var doc = document.documentElement, body = document.body;
460 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
461 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
464 // Add which for key events
465 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
466 event.which = event.charCode || event.keyCode;
469 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
470 if ( !event.metaKey && event.ctrlKey ) {
471 event.metaKey = event.ctrlKey;
474 // Add which for click: 1 === left; 2 === middle; 3 === right
475 // Note: button is not normalized, so don't use it
476 if ( !event.which && event.button !== undefined ) {
477 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
483 // Deprecated, use jQuery.guid instead
486 // Deprecated, use jQuery.proxy instead
491 // Make sure the ready event is setup
492 setup: jQuery.bindReady,
493 teardown: jQuery.noop
497 add: function( handleObj ) {
498 jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
501 remove: function( handleObj ) {
503 type = handleObj.origType.replace(rnamespaces, "");
505 jQuery.each( jQuery.data(this, "events").live || [], function() {
506 if ( type === this.origType.replace(rnamespaces, "") ) {
513 jQuery.event.remove( this, handleObj.origType, liveHandler );
520 setup: function( data, namespaces, eventHandle ) {
521 // We only want to do this special case on windows
522 if ( this.setInterval ) {
523 this.onbeforeunload = eventHandle;
527 teardown: function( namespaces, eventHandle ) {
528 if ( this.onbeforeunload === eventHandle ) {
529 this.onbeforeunload = null;
536 var removeEvent = document.removeEventListener ?
537 function( elem, type, handle ) {
538 if ( elem.removeEventListener ) {
539 elem.removeEventListener( type, handle, false );
542 function( elem, type, handle ) {
543 if ( elem.detachEvent ) {
544 elem.detachEvent( "on" + type, handle );
548 jQuery.Event = function( src ) {
549 // Allow instantiation without the 'new' keyword
550 if ( !this.preventDefault ) {
551 return new jQuery.Event( src );
555 if ( src && src.type ) {
556 this.originalEvent = src;
557 this.type = src.type;
563 // timeStamp is buggy for some events on Firefox(#3843)
564 // So we won't rely on the native value
565 this.timeStamp = now();
568 this[ expando ] = true;
571 function returnFalse() {
574 function returnTrue() {
578 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
579 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
580 jQuery.Event.prototype = {
581 preventDefault: function() {
582 this.isDefaultPrevented = returnTrue;
584 var e = this.originalEvent;
589 // if preventDefault exists run it on the original event
590 if ( e.preventDefault ) {
593 // otherwise set the returnValue property of the original event to false (IE)
594 e.returnValue = false;
596 stopPropagation: function() {
597 this.isPropagationStopped = returnTrue;
599 var e = this.originalEvent;
603 // if stopPropagation exists run it on the original event
604 if ( e.stopPropagation ) {
607 // otherwise set the cancelBubble property of the original event to true (IE)
608 e.cancelBubble = true;
610 stopImmediatePropagation: function() {
611 this.isImmediatePropagationStopped = returnTrue;
612 this.stopPropagation();
614 isDefaultPrevented: returnFalse,
615 isPropagationStopped: returnFalse,
616 isImmediatePropagationStopped: returnFalse
619 // Checks if an event happened on an element within another element
620 // Used in jQuery.event.special.mouseenter and mouseleave handlers
621 var withinElement = function( event ) {
622 // Check if mouse(over|out) are still within the same parent element
623 var parent = event.relatedTarget;
625 // Firefox sometimes assigns relatedTarget a XUL element
626 // which we cannot access the parentNode property of
628 // Traverse up the tree
629 while ( parent && parent !== this ) {
630 parent = parent.parentNode;
633 if ( parent !== this ) {
634 // set the correct event type
635 event.type = event.data;
637 // handle event if we actually just moused on to a non sub-element
638 jQuery.event.handle.apply( this, arguments );
641 // assuming we've left the element since we most likely mousedover a xul element
645 // In case of event delegation, we only need to rename the event.type,
646 // liveHandler will take care of the rest.
647 delegate = function( event ) {
648 event.type = event.data;
649 jQuery.event.handle.apply( this, arguments );
652 // Create mouseenter and mouseleave events
654 mouseenter: "mouseover",
655 mouseleave: "mouseout"
656 }, function( orig, fix ) {
657 jQuery.event.special[ orig ] = {
658 setup: function( data ) {
659 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
661 teardown: function( data ) {
662 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
668 if ( !jQuery.support.submitBubbles ) {
670 jQuery.event.special.submit = {
671 setup: function( data, namespaces ) {
672 if ( this.nodeName.toLowerCase() !== "form" ) {
673 jQuery.event.add(this, "click.specialSubmit", function( e ) {
674 var elem = e.target, type = elem.type;
676 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
677 return trigger( "submit", this, arguments );
681 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
682 var elem = e.target, type = elem.type;
684 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
685 return trigger( "submit", this, arguments );
694 teardown: function( namespaces ) {
695 jQuery.event.remove( this, ".specialSubmit" );
701 // change delegation, happens here so we have bind.
702 if ( !jQuery.support.changeBubbles ) {
704 var formElems = /textarea|input|select/i,
708 getVal = function( elem ) {
709 var type = elem.type, val = elem.value;
711 if ( type === "radio" || type === "checkbox" ) {
714 } else if ( type === "select-multiple" ) {
715 val = elem.selectedIndex > -1 ?
716 jQuery.map( elem.options, function( elem ) {
717 return elem.selected;
721 } else if ( elem.nodeName.toLowerCase() === "select" ) {
722 val = elem.selectedIndex;
728 testChange = function testChange( e ) {
729 var elem = e.target, data, val;
731 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
735 data = jQuery.data( elem, "_change_data" );
738 // the current data will be also retrieved by beforeactivate
739 if ( e.type !== "focusout" || elem.type !== "radio" ) {
740 jQuery.data( elem, "_change_data", val );
743 if ( data === undefined || val === data ) {
747 if ( data != null || val ) {
749 return jQuery.event.trigger( e, arguments[1], elem );
753 jQuery.event.special.change = {
755 focusout: testChange,
757 click: function( e ) {
758 var elem = e.target, type = elem.type;
760 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
761 return testChange.call( this, e );
765 // Change has to be called before submit
766 // Keydown will be called before keypress, which is used in submit-event delegation
767 keydown: function( e ) {
768 var elem = e.target, type = elem.type;
770 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
771 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
772 type === "select-multiple" ) {
773 return testChange.call( this, e );
777 // Beforeactivate happens also before the previous element is blurred
778 // with this event you can't trigger a change event, but you can store
779 // information/focus[in] is not needed anymore
780 beforeactivate: function( e ) {
782 jQuery.data( elem, "_change_data", getVal(elem) );
786 setup: function( data, namespaces ) {
787 if ( this.type === "file" ) {
791 for ( var type in changeFilters ) {
792 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
795 return formElems.test( this.nodeName );
798 teardown: function( namespaces ) {
799 jQuery.event.remove( this, ".specialChange" );
801 return formElems.test( this.nodeName );
805 changeFilters = jQuery.event.special.change.filters;
808 function trigger( type, elem, args ) {
810 return jQuery.event.handle.apply( elem, args );
813 // Create "bubbling" focus and blur events
814 if ( document.addEventListener ) {
815 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
816 jQuery.event.special[ fix ] = {
818 this.addEventListener( orig, handler, true );
820 teardown: function() {
821 this.removeEventListener( orig, handler, true );
825 function handler( e ) {
826 e = jQuery.event.fix( e );
828 return jQuery.event.handle.call( this, e );
833 jQuery.each(["bind", "one"], function( i, name ) {
834 jQuery.fn[ name ] = function( type, data, fn ) {
835 // Handle object literals
836 if ( typeof type === "object" ) {
837 for ( var key in type ) {
838 this[ name ](key, data, type[key], fn);
843 if ( jQuery.isFunction( data ) || data === false ) {
848 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
849 jQuery( this ).unbind( event, handler );
850 return fn.apply( this, arguments );
853 if ( type === "unload" && name !== "one" ) {
854 this.one( type, data, fn );
857 for ( var i = 0, l = this.length; i < l; i++ ) {
858 jQuery.event.add( this[i], type, handler, data );
867 unbind: function( type, fn ) {
868 // Handle object literals
869 if ( typeof type === "object" && !type.preventDefault ) {
870 for ( var key in type ) {
871 this.unbind(key, type[key]);
875 for ( var i = 0, l = this.length; i < l; i++ ) {
876 jQuery.event.remove( this[i], type, fn );
883 delegate: function( selector, types, data, fn ) {
884 return this.live( types, data, fn, selector );
887 undelegate: function( selector, types, fn ) {
888 if ( arguments.length === 0 ) {
889 return this.unbind( "live" );
892 return this.die( types, null, fn, selector );
896 trigger: function( type, data ) {
897 return this.each(function() {
898 jQuery.event.trigger( type, data, this );
902 triggerHandler: function( type, data ) {
904 var event = jQuery.Event( type );
905 event.preventDefault();
906 event.stopPropagation();
907 jQuery.event.trigger( event, data, this[0] );
912 toggle: function( fn ) {
913 // Save reference to arguments for access in closure
914 var args = arguments, i = 1;
916 // link all the functions, so any of them can unbind this click handler
917 while ( i < args.length ) {
918 jQuery.proxy( fn, args[ i++ ] );
921 return this.click( jQuery.proxy( fn, function( event ) {
922 // Figure out which function to execute
923 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
924 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
926 // Make sure that clicks stop
927 event.preventDefault();
929 // and execute the function
930 return args[ lastToggle ].apply( this, arguments ) || false;
934 hover: function( fnOver, fnOut ) {
935 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
942 mouseenter: "mouseover",
943 mouseleave: "mouseout"
946 jQuery.each(["live", "die"], function( i, name ) {
947 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
948 var type, i = 0, match, namespaces, preType,
949 selector = origSelector || this.selector,
950 context = origSelector ? this : jQuery( this.context );
952 if ( jQuery.isFunction( data ) ) {
957 types = (types || "").split(" ");
959 while ( (type = types[ i++ ]) != null ) {
960 match = rnamespaces.exec( type );
964 namespaces = match[0];
965 type = type.replace( rnamespaces, "" );
968 if ( type === "hover" ) {
969 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
975 if ( type === "focus" || type === "blur" ) {
976 types.push( liveMap[ type ] + namespaces );
977 type = type + namespaces;
980 type = (liveMap[ type ] || type) + namespaces;
983 if ( name === "live" ) {
985 for ( var j = 0, l = context.length; j < l; j++ ) {
986 jQuery.event.add( context[j], liveConvert( type, selector ),
987 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
991 // unbind live handler
992 context.unbind( liveConvert( type, selector ), fn );
1000 function liveHandler( event ) {
1001 var stop, maxLevel, elems = [], selectors = [],
1002 related, match, handleObj, elem, j, i, l, data, close, namespace,
1003 events = jQuery.data( this, "events" );
1005 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
1006 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
1010 if ( event.namespace ) {
1011 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
1014 event.liveFired = this;
1016 var live = events.live.slice(0);
1018 for ( j = 0; j < live.length; j++ ) {
1019 handleObj = live[j];
1021 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
1022 selectors.push( handleObj.selector );
1025 live.splice( j--, 1 );
1029 match = jQuery( event.target ).closest( selectors, event.currentTarget );
1031 for ( i = 0, l = match.length; i < l; i++ ) {
1034 for ( j = 0; j < live.length; j++ ) {
1035 handleObj = live[j];
1037 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
1041 // Those two events require additional checking
1042 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
1043 event.type = handleObj.preType;
1044 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
1047 if ( !related || related !== elem ) {
1048 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
1054 for ( i = 0, l = elems.length; i < l; i++ ) {
1057 if ( maxLevel && match.level > maxLevel ) {
1061 event.currentTarget = match.elem;
1062 event.data = match.handleObj.data;
1063 event.handleObj = match.handleObj;
1065 ret = match.handleObj.origHandler.apply( match.elem, arguments );
1067 if ( ret === false || event.isPropagationStopped() ) {
1068 maxLevel = match.level;
1070 if ( ret === false ) {
1079 function liveConvert( type, selector ) {
1080 return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
1083 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
1084 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
1085 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
1087 // Handle event binding
1088 jQuery.fn[ name ] = function( data, fn ) {
1094 return arguments.length > 0 ?
1095 this.bind( name, data, fn ) :
1096 this.trigger( name );
1099 if ( jQuery.attrFn ) {
1100 jQuery.attrFn[ name ] = true;
1104 // Prevent memory leaks in IE
1105 // Window isn't included so as not to unbind existing unload events
1107 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
1108 if ( window.attachEvent && !window.addEventListener ) {
1109 window.attachEvent("onunload", function() {
1110 for ( var id in jQuery.cache ) {
1111 if ( jQuery.cache[ id ].handle ) {
1112 // Try/Catch is to handle iframes being unloaded, see #4280
1114 jQuery.event.remove( jQuery.cache[ id ].handle.elem );