aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/event.js24
-rw-r--r--test/unit/event.js15
2 files changed, 25 insertions, 14 deletions
diff --git a/src/event.js b/src/event.js
index ede6d4c2d..ecfe63001 100644
--- a/src/event.js
+++ b/src/event.js
@@ -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 );
}
diff --git a/test/unit/event.js b/test/unit/event.js
index 9e49a1e13..5bc20801a 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -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" );