Skip to content

Commit

Permalink
Dialog: Keep track of instances to focus when elements outside the di…
Browse files Browse the repository at this point in the history
…alog get focus. Works with inheritance. Adds tests for both. Fixes #9241 - Dialog: UI dialog inheritance causes undefined property '_focusTabbable' in IE9
  • Loading branch information
jzaefferer committed Nov 20, 2013
1 parent 32a0060 commit 1096f19
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
48 changes: 48 additions & 0 deletions tests/unit/dialog/dialog_core.js
Expand Up @@ -4,6 +4,7 @@

(function($) {

// TODO add teardown callback to remove dialogs
module("dialog: core");

test("title id", function() {
Expand Down Expand Up @@ -180,4 +181,51 @@ asyncTest( "#9048: multiple modal dialogs opened and closed in different order",
start();
});
});

asyncTest( "interaction between overlay and other dialogs", function() {
$.widget( "ui.testWidget", $.ui.dialog, {
options: {
modal: true,
autoOpen: false
}
});
expect( 2 );
var first = $( "<div><input id='input-1'></div>" ).dialog({
modal: true
}),
firstInput = first.find( "input" ),
second = $( "<div><input id='input-2'></div>" ).testWidget(),
secondInput = second.find( "input" );

// Support: IE8
// For some reason the focus doesn't get set properly if we don't
// focus the body first.
$( "body" ).focus();

// Wait for the modal to init
setTimeout(function() {
second.testWidget( "open" );

// Simulate user tabbing from address bar to an element outside the dialog
$( "#favorite-animal" ).focus();
setTimeout(function() {
equal( document.activeElement, secondInput[ 0 ] );

// Last active dialog must receive focus
firstInput.focus();
$( "#favorite-animal" ).focus();
setTimeout(function() {
equal( document.activeElement, firstInput[ 0 ] );

// Cleanup
first.remove();
second.remove();
delete $.ui.testWidget;
delete $.fn.testWidget;
start();
});
});
});
});

})(jQuery);
23 changes: 21 additions & 2 deletions ui/jquery.ui.dialog.js
Expand Up @@ -182,6 +182,7 @@ $.widget( "ui.dialog", {
this._isOpen = false;
this._focusedElement = null;
this._destroyOverlay();
this._untrackInstance();

if ( !this.opener.filter( ":focusable" ).focus().length ) {

Expand Down Expand Up @@ -562,11 +563,30 @@ $.widget( "ui.dialog", {
_trackFocus: function() {
this._on( this.widget(), {
"focusin": function( event ) {
this._untrackInstance();
this._trackingInstances().unshift( this );
this._focusedElement = $( event.target );
}
});
},

_untrackInstance: function() {
var instances = this._trackingInstances(),
exists = $.inArray( this, instances );
if ( exists !== -1 ) {
instances.splice( exists, 1 );
}
},

_trackingInstances: function() {
var instances = this.document.data( "ui-dialog-instances" );
if ( !instances ) {
instances = [];
this.document.data( "ui-dialog-instances", instances );
}
return instances;
},

_minHeight: function() {
var options = this.options;

Expand Down Expand Up @@ -783,8 +803,7 @@ $.widget( "ui.dialog", {

if ( !this._allowInteraction( event ) ) {
event.preventDefault();
this.document.find( ".ui-dialog:visible:last .ui-dialog-content" )
.data( this.widgetFullName )._focusTabbable();
this._trackingInstances()[ 0 ]._focusTabbable();
}
}
});
Expand Down

0 comments on commit 1096f19

Please sign in to comment.