]> source.dussan.org Git - jquery.git/commitdiff
Tests: Use only one focusin/out handler per matching window & document
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Mon, 27 Apr 2020 19:37:06 +0000 (21:37 +0200)
committerGitHub <noreply@github.com>
Mon, 27 Apr 2020 19:37:06 +0000 (21:37 +0200)
Backport tests from a jQuery 3.x fix that's not needed on `master`.

Also, fix the "focusin from an iframe" test to actually verify the behavior
from commit 1cecf64e5aa415367a7dae0b55c2dd17b591442d - the commit that
introduced the regression - to make sure we don't regress on either front.

The main part of the modified test was checking that focusin handling in an
iframe works and that's still checked. The test was also checking that it
doesn't propagate to the parent document, though, and, apparently, in IE it
does. This one test is now blacklisted in IE.

(cherry picked from 9e15d6b469556eccfa607c5ecf53b20c84529125)
(cherry picked from 1a4f10ddc37c34c6dc3a451ee451b5c6cf367399)

Ref gh-4652
Ref gh-4656
Closes gh-4657

test/unit/event.js

index 7ba6c8f0b2b6c7c15c37c002a7f38f8b0e7abe88..771283c2f63293c53c3866515ff5c842664bd849 100644 (file)
@@ -2560,31 +2560,76 @@ 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() {
-                       assert.ok( false, "fired a focusin event in the parent document" );
+
+                       // Support: IE 9 - 11+
+                       // IE does propagate the event to the parent document. In this test
+                       // we mainly care about the inner element so we'll just skip this one
+                       // assertion in IE.
+                       if ( !document.documentMode ) {
+                               assert.ok( false, "fired a focusin event in the parent document" );
+                       }
                } );
 
                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 />" );
+
+       function increment() {
+               counter++;
+       }
+
+       input.appendTo( "#qunit-fixture" );
+
+       input[ 0 ].focus();
+
+       jQuery( window ).on( "focusout", increment );
+       jQuery( document ).on( "focusout", increment );
+
+       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" );
+
+       jQuery( window ).off( "focusout", increment );
+       jQuery( document ).off( "focusout", increment );
+} );
+
 testIframe(
        "jQuery.ready promise",
        "event/promiseReady.html",