jquery event: closes #3355. Added stopImmediatePropagation() to events.
[jquery.git] / src / event.js
index 8529d13..e9e1bee 100644 (file)
@@ -190,6 +190,7 @@ jQuery.event = {
                                        target: elem,
                                        preventDefault: function(){},
                                        stopPropagation: function(){},
+                                       stopImmediatePropagation:stopImmediatePropagation,
                                        timeStamp: now()
                                });
                                data[0][expando] = true; // no need to fix fake event
@@ -271,6 +272,10 @@ jQuery.event = {
                                        event.preventDefault();
                                        event.stopPropagation();
                                }
+
+                               if( event._sip )
+                                       break;
+
                        }
                }
 
@@ -280,7 +285,7 @@ jQuery.event = {
        props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" "),
 
        fix: function(event) {
-               if ( event[expando] == true )
+               if ( event[expando] )
                        return event;
 
                // store a copy of the original event object
@@ -313,6 +318,8 @@ jQuery.event = {
                        originalEvent.cancelBubble = true;
                };
 
+               event.stopImmediatePropagation = stopImmediatePropagation;
+
                // Fix timeStamp
                event.timeStamp = event.timeStamp || now();
 
@@ -360,60 +367,51 @@ jQuery.event = {
 
        special: {
                ready: {
-                       setup: function() {
-                               // Make sure the ready event is setup
-                               bindReady();
-                               return;
-                       },
-
-                       teardown: function() { return; }
-               },
-
-               mouseenter: {
-                       setup: function( data ) {
-                               if ( jQuery.browser.msie ) return false;
-                               jQuery(this).bind("mouseover", data, jQuery.event.special.mouseenter.handler);
-                               return true;
-                       },
-
-                       teardown: function() {
-                               if ( jQuery.browser.msie ) return false;
-                               jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
-                               return true;
-                       },
-
-                       handler: function(event) {
-                               // If we actually just moused on to a sub-element, ignore it
-                               if ( withinElement(event, this) ) return true;
-                               // Execute the right handlers by setting the event type to mouseenter
-                               event.type = "mouseenter";
-                               return jQuery.event.handle.apply(this, arguments);
-                       }
-               },
+                       // Make sure the ready event is setup
+                       setup: bindReady,
+                       teardown: function() {}
+               }
+       }
+};
 
-               mouseleave: {
-                       setup: function( data ) {
-                               if ( jQuery.browser.msie ) return false;
-                               jQuery(this).bind("mouseout", data, jQuery.event.special.mouseleave.handler);
-                               return true;
-                       },
+function stopImmediatePropagation(){
+       this._sip = 1;
+       this.stopPropagation();
+}
 
-                       teardown: function() {
-                               if ( jQuery.browser.msie ) return false;
-                               jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
-                               return true;
+if ( !jQuery.browser.msie ){   
+       // Checks if an event happened on an element within another element
+       // Used in jQuery.event.special.mouseenter and mouseleave handlers
+       var withinElement = function(event) {
+               // Check if mouse(over|out) are still within the same parent element
+               var parent = event.relatedTarget;
+               // Traverse up the tree
+               while ( parent && parent != this )
+                       try { parent = parent.parentNode; }
+                       catch(e) { parent = this; }
+               
+               if( parent != this ){
+                       // set the correct event type
+                       event.type = event.data;
+                       // handle event if we actually just moused on to a non sub-element
+                       jQuery.event.handle.apply( this, arguments );
+               }
+       };
+       
+       jQuery.each({ 
+               mouseover: 'mouseenter', 
+               mouseout: 'mouseleave'
+       }, function( orig, fix ){
+               jQuery.event.special[ fix ] = {
+                       setup: function(){
+                               jQuery.event.add( this, orig, withinElement, fix );
                        },
-
-                       handler: function(event) {
-                               // If we actually just moused on to a sub-element, ignore it
-                               if ( withinElement(event, this) ) return true;
-                               // Execute the right handlers by setting the event type to mouseleave
-                               event.type = "mouseleave";
-                               return jQuery.event.handle.apply(this, arguments);
+                       teardown: function(){
+                               jQuery.event.remove( this, orig, withinElement );
                        }
-               }
-       }
-};
+               };                         
+       });
+}
 
 jQuery.fn.extend({
        bind: function( type, data, fn ) {
@@ -589,17 +587,6 @@ jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
        };
 });
 
-// Checks if an event happened on an element within another element
-// Used in jQuery.event.special.mouseenter and mouseleave handlers
-var withinElement = function(event, elem) {
-       // Check if mouse(over|out) are still within the same parent element
-       var parent = event.relatedTarget;
-       // Traverse up the tree
-       while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
-       // Return true if we actually just moused on to a sub-element
-       return parent == elem;
-};
-
 // Prevent memory leaks in IE
 // And prevent errors on refresh with events like mouseover in other browsers
 // Window isn't included so as not to unbind existing unload events