Merge branch 'fix-7340-focusin-focusout-bubble' of https://github.com/dmethvin/jquery into dmethvin-fix-7340-focusin-focusout-bubble

This commit is contained in:
jeresig 2011-03-21 10:53:18 -04:00
commit 5c79f82ec2
2 changed files with 48 additions and 9 deletions

View file

@ -70,10 +70,10 @@ jQuery.event = {
} }
if ( !eventHandle ) { if ( !eventHandle ) {
elemData.handle = eventHandle = function() { elemData.handle = eventHandle = function( e ) {
// Handle the second event of a trigger and when // Handle the second event of a trigger and when
// an event is called after a page has unloaded // an event is called after a page has unloaded
return typeof jQuery !== "undefined" && !jQuery.event.triggered ? return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
jQuery.event.handle.apply( eventHandle.elem, arguments ) : jQuery.event.handle.apply( eventHandle.elem, arguments ) :
undefined; undefined;
}; };
@ -380,7 +380,7 @@ jQuery.event = {
target[ "on" + targetType ] = null; target[ "on" + targetType ] = null;
} }
jQuery.event.triggered = true; jQuery.event.triggered = event.type;
target[ targetType ](); target[ targetType ]();
} }
@ -391,7 +391,7 @@ jQuery.event = {
target[ "on" + targetType ] = old; target[ "on" + targetType ] = old;
} }
jQuery.event.triggered = false; jQuery.event.triggered = undefined;
} }
} }
}, },
@ -868,19 +868,33 @@ function trigger( type, elem, args ) {
// Create "bubbling" focus and blur events // Create "bubbling" focus and blur events
if ( document.addEventListener ) { if ( document.addEventListener ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
// Attach a single capturing handler while someone wants focusin/focusout
var attaches = 0;
jQuery.event.special[ fix ] = { jQuery.event.special[ fix ] = {
setup: function() { setup: function() {
this.addEventListener( orig, handler, true ); if ( attaches++ === 0 ) {
document.addEventListener( orig, handler, true );
}
}, },
teardown: function() { teardown: function() {
this.removeEventListener( orig, handler, true ); if ( --attaches === 0 ) {
document.removeEventListener( orig, handler, true );
}
} }
}; };
function handler( e ) { function handler( donor ) {
e = jQuery.event.fix( e ); // Donor event is always a native one; fix it and switch its type.
// Let focusin/out handler cancel the donor focus/blur event.
var e = jQuery.event.fix( donor );
e.type = fix; e.type = fix;
return jQuery.event.handle.call( this, e ); e.originalEvent = {};
jQuery.event.trigger( e, null, e.target );
if ( e.isDefaultPrevented() ) {
donor.preventDefault();
}
} }
}); });
} }

View file

@ -1966,6 +1966,31 @@ test("window resize", function() {
ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." ); ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
}); });
test("focusin bubbles", function() {
expect(4);
var input = jQuery( '<input type="text" />' ).prependTo( "body" ),
order = 0;
jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){
equals( 1, order++, "focusin on the body second" );
});
input.bind( "focusin.focusinBubblesTest", function(){
equals( 0, order++, "focusin on the element first" );
});
// DOM focus method
input[0].focus();
// jQuery trigger, which calls DOM focus
order = 0;
input[0].blur();
input.trigger( "focus" );
input.remove();
jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
});
/* /*
test("jQuery(function($) {})", function() { test("jQuery(function($) {})", function() {
stop(); stop();