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 ] = {
|
jQuery.event.special[ fix ] = {
|
||||||
setup: function() {
|
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 );
|
attaches = dataPriv.access( doc, fix );
|
||||||
|
|
||||||
if ( !attaches ) {
|
if ( !attaches ) {
|
||||||
@ -36,7 +39,7 @@ if ( !support.focusin ) {
|
|||||||
dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
|
dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
|
||||||
},
|
},
|
||||||
teardown: function() {
|
teardown: function() {
|
||||||
var doc = this.ownerDocument || this,
|
var doc = this.ownerDocument || this.document || this,
|
||||||
attaches = dataPriv.access( doc, fix ) - 1;
|
attaches = dataPriv.access( doc, fix ) - 1;
|
||||||
|
|
||||||
if ( !attaches ) {
|
if ( !attaches ) {
|
||||||
|
@ -2555,7 +2555,9 @@ testIframe(
|
|||||||
function( assert, framejQuery, frameWin, frameDoc ) {
|
function( assert, framejQuery, frameWin, frameDoc ) {
|
||||||
assert.expect( 1 );
|
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
|
// Create a focusin handler on the parent; shouldn't affect the iframe's fate
|
||||||
jQuery( "body" ).on( "focusin.iframeTest", function() {
|
jQuery( "body" ).on( "focusin.iframeTest", function() {
|
||||||
@ -2563,23 +2565,56 @@ testIframe(
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
input.on( "focusin", function() {
|
input.on( "focusin", function() {
|
||||||
|
focus = true;
|
||||||
assert.ok( true, "fired a focusin event in the iframe" );
|
assert.ok( true, "fired a focusin event in the iframe" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Avoid a native event; Chrome can't force focus to another frame
|
// Avoid a native event; Chrome can't force focus to another frame
|
||||||
input.trigger( "focusin" );
|
input[ 0 ].focus();
|
||||||
|
|
||||||
// Must manually remove handler to avoid leaks in our data store
|
|
||||||
input.remove();
|
|
||||||
|
|
||||||
// Be sure it was removed; nothing should happen
|
|
||||||
input.trigger( "focusin" );
|
|
||||||
|
|
||||||
// Remove body handler manually since it's outside the fixture
|
// Remove body handler manually since it's outside the fixture
|
||||||
jQuery( "body" ).off( "focusin.iframeTest" );
|
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(
|
testIframe(
|
||||||
"jQuery.ready promise",
|
"jQuery.ready promise",
|
||||||
"event/promiseReady.html",
|
"event/promiseReady.html",
|
||||||
|
Loading…
Reference in New Issue
Block a user