mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Event: Use only one focusin/out handler per matching window & document
The `doc` variable in:
https://github.com/jquery/jquery/blob/3.4.1/src/event/focusin.js#L30
matched `document` for `document` & `window` for `window`, creating two
separate wrapper event handlers & calling handlers twice if at least one
`focusout` or `focusin` handler was attached on *both* `window` & `document`,
or on `window` & another regular node.
Also, fix the "focusin from an iframe" test to actually verify the behavior
from commit 1cecf64e5a
- the commit that
introduced the regression - to make sure we don't regress on either front.
Fixes gh-4652
Closes gh-4656
This commit is contained in:
parent
966a709090
commit
9e15d6b469
@ -27,7 +27,10 @@ if ( !support.focusin ) {
|
||||
|
||||
jQuery.event.special[ fix ] = {
|
||||
setup: function() {
|
||||
var doc = this.ownerDocument || this,
|
||||
|
||||
// Handle: regular nodes (via `this.ownerDocument`), window
|
||||
// (via `this.document`) & document (via `this`).
|
||||
var doc = this.ownerDocument || this.document || this,
|
||||
attaches = dataPriv.access( doc, fix );
|
||||
|
||||
if ( !attaches ) {
|
||||
@ -36,7 +39,7 @@ if ( !support.focusin ) {
|
||||
dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
|
||||
},
|
||||
teardown: function() {
|
||||
var doc = this.ownerDocument || this,
|
||||
var doc = this.ownerDocument || this.document || this,
|
||||
attaches = dataPriv.access( doc, fix ) - 1;
|
||||
|
||||
if ( !attaches ) {
|
||||
|
@ -2555,7 +2555,9 @@ testIframe(
|
||||
function( assert, framejQuery, frameWin, frameDoc ) {
|
||||
assert.expect( 1 );
|
||||
|
||||
var input = jQuery( frameDoc ).find( "#frame-input" );
|
||||
var done = assert.async(),
|
||||
focus = false,
|
||||
input = jQuery( frameDoc ).find( "#frame-input" );
|
||||
|
||||
// Create a focusin handler on the parent; shouldn't affect the iframe's fate
|
||||
jQuery( "body" ).on( "focusin.iframeTest", function() {
|
||||
@ -2563,23 +2565,56 @@ testIframe(
|
||||
} );
|
||||
|
||||
input.on( "focusin", function() {
|
||||
focus = true;
|
||||
assert.ok( true, "fired a focusin event in the iframe" );
|
||||
} );
|
||||
|
||||
// Avoid a native event; Chrome can't force focus to another frame
|
||||
input.trigger( "focusin" );
|
||||
|
||||
// Must manually remove handler to avoid leaks in our data store
|
||||
input.remove();
|
||||
|
||||
// Be sure it was removed; nothing should happen
|
||||
input.trigger( "focusin" );
|
||||
input[ 0 ].focus();
|
||||
|
||||
// Remove body handler manually since it's outside the fixture
|
||||
jQuery( "body" ).off( "focusin.iframeTest" );
|
||||
|
||||
setTimeout( function() {
|
||||
|
||||
// DOM focus is unreliable in TestSwarm
|
||||
if ( QUnit.isSwarm && !focus ) {
|
||||
assert.ok( true, "GAP: Could not observe focus change" );
|
||||
}
|
||||
|
||||
done();
|
||||
}, 50 );
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test( "focusin on document & window", function( assert ) {
|
||||
assert.expect( 1 );
|
||||
|
||||
var counter = 0,
|
||||
input = jQuery( "<input />" );
|
||||
|
||||
input.appendTo( "#qunit-fixture" );
|
||||
|
||||
input[ 0 ].focus();
|
||||
|
||||
jQuery( window ).on( "focusout", function() {
|
||||
counter++;
|
||||
} );
|
||||
jQuery( document ).on( "focusout", function() {
|
||||
counter++;
|
||||
} );
|
||||
|
||||
input[ 0 ].blur();
|
||||
|
||||
// DOM focus is unreliable in TestSwarm
|
||||
if ( QUnit.isSwarm && counter === 0 ) {
|
||||
assert.ok( true, "GAP: Could not observe focus change" );
|
||||
}
|
||||
|
||||
assert.strictEqual( counter, 2,
|
||||
"focusout handlers on document/window fired once only" );
|
||||
} );
|
||||
|
||||
testIframe(
|
||||
"jQuery.ready promise",
|
||||
"event/promiseReady.html",
|
||||
|
Loading…
Reference in New Issue
Block a user