No need to set returnValue if preventDefault exists. Thanks kangax for the catch.
[jquery.git] / src / event.js
index abfdc4f..1fec18c 100644 (file)
@@ -1,3 +1,5 @@
+(function( jQuery ) {
+
 var rnamespaces = /\.(.*)$/,
        fcleanup = function( nm ) {
                return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
@@ -90,7 +92,9 @@ jQuery.event = {
                        }
 
                        handleObj.type = type;
-                       handleObj.guid = handler.guid;
+                       if ( !handleObj.guid ) {
+                               handleObj.guid = handler.guid;
+                       }
 
                        // Get the current list of functions bound to this event
                        var handlers = events[ type ],
@@ -146,7 +150,7 @@ jQuery.event = {
                        handler = returnFalse;
                }
 
-               var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+               var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
                        elemData = jQuery.data( elem ),
                        events = elemData && elemData.events;
 
@@ -197,7 +201,7 @@ jQuery.event = {
                        }
 
                        if ( !handler ) {
-                               for ( var j = 0; j < eventType.length; j++ ) {
+                               for ( j = 0; j < eventType.length; j++ ) {
                                        handleObj = eventType[ j ];
 
                                        if ( all || namespace.test( handleObj.namespace ) ) {
@@ -211,7 +215,7 @@ jQuery.event = {
 
                        special = jQuery.event.special[ type ] || {};
 
-                       for ( var j = pos || 0; j < eventType.length; j++ ) {
+                       for ( j = pos || 0; j < eventType.length; j++ ) {
                                handleObj = eventType[ j ];
 
                                if ( handler.guid === handleObj.guid ) {
@@ -235,7 +239,7 @@ jQuery.event = {
                        // remove generic event handler if no more handlers exist
                        if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
                                if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
-                                       removeEvent( elem, type, elemData.handle );
+                                       jQuery.removeEvent( elem, type, elemData.handle );
                                }
 
                                ret = null;
@@ -268,7 +272,7 @@ jQuery.event = {
                if ( !bubbling ) {
                        event = typeof event === "object" ?
                                // jQuery.Event object
-                               event[expando] ? event :
+                               event[ jQuery.expando ] ? event :
                                // Object literal
                                jQuery.extend( jQuery.Event(type), event ) :
                                // Just the event type (string)
@@ -329,37 +333,37 @@ jQuery.event = {
                        }
 
                // prevent IE from throwing an error for some elements with some event types, see #3533
-               } catch (e) {}
+               } catch (inlineError) {}
 
                if ( !event.isPropagationStopped() && parent ) {
                        jQuery.event.trigger( event, data, parent, true );
 
                } else if ( !event.isDefaultPrevented() ) {
-                       var target = event.target, old,
-                               isClick = jQuery.nodeName(target, "a") && type === "click",
-                               special = jQuery.event.special[ type ] || {};
+                       var target = event.target, old, targetType = type.replace(/\..*$/, ""),
+                               isClick = jQuery.nodeName(target, "a") && targetType === "click",
+                               special = jQuery.event.special[ targetType ] || {};
 
                        if ( (!special._default || special._default.call( elem, event ) === false) && 
                                !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
 
                                try {
-                                       if ( target[ type ] ) {
+                                       if ( target[ targetType ] ) {
                                                // Make sure that we don't accidentally re-trigger the onFOO events
-                                               old = target[ "on" + type ];
+                                               old = target[ "on" + targetType ];
 
                                                if ( old ) {
-                                                       target[ "on" + type ] = null;
+                                                       target[ "on" + targetType ] = null;
                                                }
 
                                                jQuery.event.triggered = true;
-                                               target[ type ]();
+                                               target[ targetType ]();
                                        }
 
                                // prevent IE from throwing an error for some elements with some event types, see #3533
-                               } catch (e) {}
+                               } catch (triggerError) {}
 
                                if ( old ) {
-                                       target[ "on" + type ] = old;
+                                       target[ "on" + targetType ] = old;
                                }
 
                                jQuery.event.triggered = false;
@@ -368,9 +372,9 @@ jQuery.event = {
        },
 
        handle: function( event ) {
-               var all, handlers, namespaces, namespace, events;
+               var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
 
-               event = arguments[0] = jQuery.event.fix( event || window.event );
+               event = args[0] = jQuery.event.fix( event || window.event );
                event.currentTarget = this;
 
                // Namespaced event handlers
@@ -379,9 +383,12 @@ jQuery.event = {
                if ( !all ) {
                        namespaces = event.type.split(".");
                        event.type = namespaces.shift();
-                       namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+                       namespace_sort = namespaces.slice(0).sort();
+                       namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
                }
 
+               event.namespace = event.namespace || namespace_sort.join(".");
+
                events = jQuery.data(this, "events");
                handlers = (events || {})[ event.type ];
 
@@ -393,14 +400,14 @@ jQuery.event = {
                                var handleObj = handlers[ j ];
 
                                // Filter the functions by class
-                               if ( all || namespace.test( handleObj.namespace ) ) {
+                               if ( all || namespace_re.test( handleObj.namespace ) ) {
                                        // Pass in a reference to the handler function itself
                                        // So that we can later remove it
                                        event.handler = handleObj.handler;
                                        event.data = handleObj.data;
                                        event.handleObj = handleObj;
        
-                                       var ret = handleObj.handler.apply( this, arguments );
+                                       var ret = handleObj.handler.apply( this, args );
 
                                        if ( ret !== undefined ) {
                                                event.result = ret;
@@ -423,7 +430,7 @@ jQuery.event = {
        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(" "),
 
        fix: function( event ) {
-               if ( event[ expando ] ) {
+               if ( event[ jQuery.expando ] ) {
                        return event;
                }
 
@@ -493,25 +500,14 @@ jQuery.event = {
 
                live: {
                        add: function( handleObj ) {
-                               jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) ); 
+                               jQuery.event.add( this,
+                                       liveConvert( handleObj.origType, handleObj.selector ),
+                                       jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 
                        },
 
                        remove: function( handleObj ) {
-                               var remove = true,
-                                       type = handleObj.origType.replace(rnamespaces, "");
-                               
-                               jQuery.each( jQuery.data(this, "events").live || [], function() {
-                                       if ( type === this.origType.replace(rnamespaces, "") ) {
-                                               remove = false;
-                                               return false;
-                                       }
-                               });
-
-                               if ( remove ) {
-                                       jQuery.event.remove( this, handleObj.origType, liveHandler );
-                               }
+                               jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
                        }
-
                },
 
                beforeunload: {
@@ -531,7 +527,7 @@ jQuery.event = {
        }
 };
 
-var removeEvent = document.removeEventListener ?
+jQuery.removeEvent = document.removeEventListener ?
        function( elem, type, handle ) {
                if ( elem.removeEventListener ) {
                        elem.removeEventListener( type, handle, false );
@@ -560,10 +556,10 @@ jQuery.Event = function( src ) {
 
        // timeStamp is buggy for some events on Firefox(#3843)
        // So we won't rely on the native value
-       this.timeStamp = now();
+       this.timeStamp = jQuery.now();
 
        // Mark it as fixed
-       this[ expando ] = true;
+       this[ jQuery.expando ] = true;
 };
 
 function returnFalse() {
@@ -587,9 +583,11 @@ jQuery.Event.prototype = {
                // if preventDefault exists run it on the original event
                if ( e.preventDefault ) {
                        e.preventDefault();
-               }
+
                // otherwise set the returnValue property of the original event to false (IE)
-               e.returnValue = false;
+               } else {
+                       e.returnValue = false;
+               }
        },
        stopPropagation: function() {
                this.isPropagationStopped = returnTrue;
@@ -981,13 +979,13 @@ jQuery.each(["live", "die"], function( i, name ) {
                        if ( name === "live" ) {
                                // bind live handler
                                for ( var j = 0, l = context.length; j < l; j++ ) {
-                                       jQuery.event.add( context[j], liveConvert( type, selector ),
+                                       jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
                                                { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
                                }
 
                        } else {
                                // unbind live handler
-                               context.unbind( liveConvert( type, selector ), fn );
+                               context.unbind( "live." + liveConvert( type, selector ), fn );
                        }
                }
                
@@ -997,7 +995,7 @@ jQuery.each(["live", "die"], function( i, name ) {
 
 function liveHandler( event ) {
        var stop, maxLevel, elems = [], selectors = [],
-               related, match, handleObj, elem, j, i, l, data, close,
+               related, match, handleObj, elem, j, i, l, data, close, namespace,
                events = jQuery.data( this, "events" );
 
        // Make sure we avoid non-left-click bubbling in Firefox (#3861)
@@ -1005,6 +1003,10 @@ function liveHandler( event ) {
                return;
        }
 
+       if ( event.namespace ) {
+               namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+       }
+
        event.liveFired = this;
 
        var live = events.live.slice(0);
@@ -1028,7 +1030,7 @@ function liveHandler( event ) {
                for ( j = 0; j < live.length; j++ ) {
                        handleObj = live[j];
 
-                       if ( close.selector === handleObj.selector ) {
+                       if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
                                elem = close.elem;
                                related = null;
 
@@ -1071,7 +1073,7 @@ function liveHandler( event ) {
 }
 
 function liveConvert( type, selector ) {
-       return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
+       return (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
 }
 
 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
@@ -1080,7 +1082,7 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
 
        // Handle event binding
        jQuery.fn[ name ] = function( data, fn ) {
-               if ( fn == undefined ) {
+               if ( fn == null ) {
                        fn = data;
                        data = null;
                }
@@ -1111,3 +1113,5 @@ if ( window.attachEvent && !window.addEventListener ) {
                }
        });
 }
+
+})( jQuery );