unbind handlers with data + test (#935)
[jquery.git] / src / event / event.js
index 0d82045..a3db2f3 100644 (file)
@@ -12,7 +12,7 @@ jQuery.event = {
                // around, causing it to be cloned in the process
                if ( jQuery.browser.msie && element.setInterval != undefined )
                        element = window;
-
+               
                // if data is passed, bind to handler 
                if( data != undefined ) { 
                // Create temporary function pointer to original handler 
@@ -22,39 +22,48 @@ jQuery.event = {
                        handler = function() { 
                                // Pass arguments and context to original handler 
                                return fn.apply(this, arguments); 
-                       }; 
+                       };
 
                        // Store data in unique handler 
-                       handler.data = data; 
+                       handler.data = data;
 
                        // Set the guid of unique handler to the same of original handler, so it can be removed 
-                       handler.guid = fn.guid; 
+                       handler.guid = fn.guid;
                }
 
                // Make sure that the function being executed has a unique ID
-               if ( !handler.guid )
+               if ( !handler.guid ) {
                        handler.guid = this.guid++;
+                       // Don't forget to set guid for the original handler function
+                       if (fn) fn.guid = handler.guid;
+               }
 
                // Init the element's event structure
                if (!element.$events)
                        element.$events = {};
+               
+               if (!element.$handle)
+                       element.$handle = function() {
+                               jQuery.event.handle.apply(element, arguments);
+                       };
 
                // Get the current list of functions bound to this event
                var handlers = element.$events[type];
 
                // Init the event handler queue
-               if (!handlers)
-                       handlers = element.$events[type] = {};
+               if (!handlers) {
+                       handlers = element.$events[type] = {};  
+                       
+                       // And bind the global event handler to the element
+                       if (element.addEventListener)
+                               element.addEventListener(type, element.$handle, false);
+                       else if (element.attachEvent)
+                               element.attachEvent("on" + type, element.$handle);
+               }
 
                // Add the function to the element's handler list
                handlers[handler.guid] = handler;
 
-               // And bind the global event handler to the element
-               if (element.addEventListener)
-                       element.addEventListener(type, this.handle, false);
-               else if (element.attachEvent)
-                       element.attachEvent("on" + type, this.handle, false);
-
                // Remember the function in a global list (for triggering)
                if (!this.global[type])
                        this.global[type] = [];
@@ -92,11 +101,11 @@ jQuery.event = {
                                // remove generic event handler if no more handlers exist
                                for ( ret in events[type] ) break;
                                if ( !ret ) {
-                                       ret = null;
                                        if (element.removeEventListener)
-                                               element.removeEventListener(type, this.handle, false);
+                                               element.removeEventListener(type, element.$handle, false);
                                        else if (element.detachEvent)
-                                               element.detachEvent("on" + type, this.handle, false);
+                                               element.detachEvent("on" + type, element.$handle);
+                                       ret = null;
                                        delete events[type];
                                }
                        }
@@ -104,7 +113,7 @@ jQuery.event = {
                        // Remove the expando if it's no longer used
                        for ( ret in events ) break;
                        if ( !ret )
-                               element.$events = null;
+                               element.$handle = element.$events = null;
                }
        },
 
@@ -268,7 +277,7 @@ jQuery.fn.extend({
         */
        bind: function( type, data, fn ) {
                return this.each(function(){
-                       jQuery.event.add( this, type, fn || data, data );
+                       jQuery.event.add( this, type, fn || data, fn && data );
                });
        },
        
@@ -303,7 +312,7 @@ jQuery.fn.extend({
                        jQuery.event.add( this, type, function(event) {
                                jQuery(this).unbind(event);
                                return (fn || data).apply( this, arguments);
-                       }, data);
+                       }, fn && data);
                });
        },