Dialog: Workaround broken focus re-triggering in jQuery 3.4/3.5

Focus re-triggering in jQuery 3.4/3.5 makes the original element
have its focus event propagated last, breaking the re-targeting.
Trigger focus in a delay in addition if needed to avoid the issue.

This fixes the "interaction between overlay and other dialogs" core dialog
test when tested against jQuery 3.4/3.5.

Closes gh-1946
Ref jquery/jquery#4382
This commit is contained in:
Michał Gołębiowski-Owczarek 2021-02-22 00:02:02 +01:00 committed by GitHub
parent 5b5fda7cd2
commit 834ee5f7cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -325,22 +325,23 @@ $.widget( "ui.dialog", {
hasFocus.eq( 0 ).trigger( "focus" ); hasFocus.eq( 0 ).trigger( "focus" );
}, },
_keepFocus: function( event ) { _restoreTabbableFocus: function() {
function checkFocus() { var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), isActive = this.uiDialog[ 0 ] === activeElement ||
isActive = this.uiDialog[ 0 ] === activeElement || $.contains( this.uiDialog[ 0 ], activeElement );
$.contains( this.uiDialog[ 0 ], activeElement ); if ( !isActive ) {
if ( !isActive ) { this._focusTabbable();
this._focusTabbable();
}
} }
},
_keepFocus: function( event ) {
event.preventDefault(); event.preventDefault();
checkFocus.call( this ); this._restoreTabbableFocus();
// support: IE // support: IE
// IE <= 8 doesn't prevent moving focus even with event.preventDefault() // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
// so we check again later // so we check again later
this._delay( checkFocus ); this._delay( this._restoreTabbableFocus );
}, },
_createWrapper: function() { _createWrapper: function() {
@ -853,6 +854,8 @@ $.widget( "ui.dialog", {
return; return;
} }
var jqMinor = $.fn.jquery.substring( 0, 4 );
// We use a delay in case the overlay is created from an // We use a delay in case the overlay is created from an
// event that we're going to be cancelling (#2804) // event that we're going to be cancelling (#2804)
var isOpening = true; var isOpening = true;
@ -874,6 +877,15 @@ $.widget( "ui.dialog", {
if ( !instance._allowInteraction( event ) ) { if ( !instance._allowInteraction( event ) ) {
event.preventDefault(); event.preventDefault();
instance._focusTabbable(); instance._focusTabbable();
// Support: jQuery >=3.4 <3.6 only
// Focus re-triggering in jQuery 3.4/3.5 makes the original element
// have its focus event propagated last, breaking the re-targeting.
// Trigger focus in a delay in addition if needed to avoid the issue
// See https://github.com/jquery/jquery/issues/4382
if ( jqMinor === "3.4." || jqMinor === "3.5." ) {
instance._delay( instance._restoreTabbableFocus );
}
} }
}.bind( this ) ); }.bind( this ) );
} }