]> source.dussan.org Git - jquery.git/commitdiff
Fixes for IE8. Avoid killer recursion in special events during removal. Use q instead...
authorDave Methvin <dave.methvin@gmail.com>
Wed, 7 Sep 2011 03:20:48 +0000 (23:20 -0400)
committertimmywil <timmywillisn@gmail.com>
Mon, 19 Sep 2011 19:42:31 +0000 (15:42 -0400)
src/event.js
test/unit/event.js

index ede6d4c2d63f4d0cfd663b94e6e82f7af6e031f7..ecfe630016f358e771ceda130f6a619b73d7a316 100644 (file)
@@ -17,7 +17,7 @@ var rnamespaces = /\.(.*)$/,
                var quick = rquickIs.exec( selector );
                if ( quick ) {
                        //   0  1    2   3      4         5          6
-                       // [ _, tag, id, class, attrName, attrValue, pseudo(:empty :first-child :last-child) ]
+                       // [ _, tag, id, class, attrName, attrValue, :(empty first-child last-child) ]
                        quick[1] = ( quick[1] || "" ).toLowerCase();
                        quick[3] = quick[3] && new RegExp( "\\b" + quick[3] + "\\b" );
                        quick[6] = quickPseudoMap[ quick[6] ];
@@ -32,14 +32,14 @@ var rnamespaces = /\.(.*)$/,
                        (!m[4] || elem.getAttribute( m[4] ) == m[5]) &&
                        (!m[6] || !elem[ m[6] ])
                );
+       },
+       useNativeMethod = function( event ) {
+               // IE throws error on focus/blur of a hidden element (#1486)
+               if ( !event.isDefaultPrevented() && this[ event.type ] && event.target && event.target.offsetWidth !== 0 ) {
+                       this[ event.type ]();
+                       return false;
+               }
        };
-       
-function useNativeMethod( event ) {
-       if ( !event.isDefaultPrevented() && this[ event.type ] ) {
-               this[ event.type ]();
-               return false;
-       }
-}
 
 /*
  * A number of helper functions used for managing events.
@@ -168,7 +168,7 @@ jQuery.event = {
        remove: function( elem, types, handler, selector ) {
 
                var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
-                       t, tns, type, namespaces, 
+                       t, tns, type, namespaces, origCount,
                        j, events, special, handle, eventType, handleObj;
                                
                if ( !elemData || !(events = elemData.events) ) {
@@ -201,6 +201,7 @@ jQuery.event = {
                        special = jQuery.event.special[ type ] || {};
                        type = (selector? special.delegateType : special.bindType ) || type;
                        eventType = events[ type ] || [];
+                       origCount = eventType.length;
                        namespaces =  namespaces? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
 
                        // Only need to loop for special events or selective removal
@@ -228,8 +229,9 @@ jQuery.event = {
                                eventType.length = 0;
                        }
 
-                       // remove generic event handler if no more handlers exist
-                       if ( eventType.length === 0 ) {
+                       // Remove generic event handler if we removed something and no more handlers exist
+                       // (avoids potential for endless recursion during removal of special event handlers)
+                       if ( eventType.length === 0 && origCount !== eventType.length ) {
                                if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
                                        jQuery.removeEvent( elem, type, elemData.handle );
                                }
index 9e49a1e13f207607381f0c5f494323eaebd14e75..5bc20801ac54ce19de5f644a3dc385b059c7d8fa 100644 (file)
@@ -2311,7 +2311,16 @@ test(".on and .off", function() {
 
 test("delegated events quickIs", function() {
        expect(23);
-       var markup = jQuery( '<div#quickis><p class="D">dead<b devo="cool">beat</b>club</p><quote id="famous">worked<em>or</em>borked?<em></em></quote></div>' ),
+       var markup = jQuery( 
+                       '<div>'+
+                               '<p class="D">'+
+                                       'dead<b devo="cool">beat</b>club'+
+                               '</p>'+
+                               '<q id="famous">'+
+                                       'worked<em>or</em>borked?<em></em>'+
+                               '</q>'+
+                       '</div>'
+               ),
                str,
                check = function(el, expect){ 
                        str = "";
@@ -2326,7 +2335,7 @@ test("delegated events quickIs", function() {
 
        // tag#id.class[name=value]
        markup
-               .appendTo( "body " )
+               .appendTo( "body" )
                .on( "blink", "em", func )
                .on( "blink", ".D", func )
                .on( "blink", ".d", func )
@@ -2342,7 +2351,7 @@ test("delegated events quickIs", function() {
        check( "[devo='']", "" );
        check( "p", "p|.D p|:first-child" );
        check( "b", "b|[devo=cool] p|.D p|:first-child" );
-       check( "em", "em|em quote|#famous em|em em|em:empty em|em:last-child quote|#famous" );
+       check( "em", "em|em q|#famous em|em em|em:empty em|em:last-child q|#famous" );
        
        markup.find( "b" ).attr( "devo", "NO" );
        check( "b", "b|[devo='NO'] p|.D p|:first-child" );