Core: Add methods to work around IE active element bugs

Closes gh-1478

(cherry picked from commit f33027840c)
This commit is contained in:
Scott González 2015-03-09 16:03:22 -04:00
parent d86df4b697
commit 2256eeda45
7 changed files with 40 additions and 38 deletions

View File

@ -278,7 +278,7 @@ $.widget( "ui.autocomplete", {
previous = this.previous;
// only trigger when focus was lost (click on menu)
if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
this.element.focus();
this.previous = previous;
// #6109 - IE triggers two focus events and the second

View File

@ -43,6 +43,31 @@ $.extend( $.ui, {
SPACE: 32,
TAB: 9,
UP: 38
},
// Internal use only
safeActiveElement: function( document ) {
var activeElement;
// Support: IE 9 only
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
try {
activeElement = document.activeElement;
} catch ( error ) {
activeElement = document.body;
}
return activeElement;
},
// Internal use only
safeBlur: function( element ) {
// Support: IE9 - 10 only
// If the <body> is blurred, IE will switch windows, see #9420
if ( element && element.nodeName.toLowerCase() !== "body" ) {
$( element ).blur();
}
}
});

View File

@ -183,8 +183,7 @@ return $.widget( "ui.dialog", {
enable: $.noop,
close: function( event ) {
var activeElement,
that = this;
var that = this;
if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
return;
@ -197,21 +196,10 @@ return $.widget( "ui.dialog", {
if ( !this.opener.filter( ":focusable" ).focus().length ) {
// support: IE9
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
try {
activeElement = this.document[ 0 ].activeElement;
// Support: IE9, IE10
// If the <body> is blurred, IE will switch windows, see #4520
if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
// Hiding a focused element doesn't trigger blur in WebKit
// so in case we have nothing to focus on, explicitly blur the active element
// https://bugs.webkit.org/show_bug.cgi?id=47182
$( activeElement ).blur();
}
} catch ( error ) {}
// Hiding a focused element doesn't trigger blur in WebKit
// so in case we have nothing to focus on, explicitly blur the active element
// https://bugs.webkit.org/show_bug.cgi?id=47182
$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
}
this._hide( this.uiDialog, this.options.hide, function() {
@ -255,7 +243,7 @@ return $.widget( "ui.dialog", {
}
this._isOpen = true;
this.opener = $( this.document[ 0 ].activeElement );
this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
this._size();
this._position();
@ -311,7 +299,7 @@ return $.widget( "ui.dialog", {
_keepFocus: function( event ) {
function checkFocus() {
var activeElement = this.document[0].activeElement,
var activeElement = $.ui.safeActiveElement( this.document[0] ),
isActive = this.uiDialog[0] === activeElement ||
$.contains( this.uiDialog[0], activeElement );
if ( !isActive ) {

View File

@ -136,25 +136,14 @@ $.widget("ui.draggable", $.ui.mouse, {
},
_blurActiveElement: function( event ) {
var document = this.document[ 0 ];
// Only need to blur if the event occurred on the draggable itself, see #10527
if ( !this.handleElement.is( event.target ) ) {
return;
}
// support: IE9
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
try {
// Support: IE9, IE10
// If the <body> is blurred, IE will switch windows, see #9520
if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
// Blur any element that currently has focus, see #4261
$( document.activeElement ).blur();
}
} catch ( error ) {}
// Blur any element that currently has focus, see #4261
$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
},
_mouseStart: function(event) {

View File

@ -87,7 +87,7 @@ return $.widget( "ui.menu", {
// Open submenu on click
if ( target.has( ".ui-menu" ).length ) {
this.expand( event );
} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
} else if ( !this.element.is( ":focus" ) && $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( ".ui-menu" ).length ) {
// Redirect focus to the menu
this.element.trigger( "focus", [ true ] );
@ -126,7 +126,7 @@ return $.widget( "ui.menu", {
},
blur: function( event ) {
this._delay(function() {
if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
if ( !$.contains( this.element[0], $.ui.safeActiveElement( this.document[0] ) ) ) {
this.collapseAll( event );
}
});

View File

@ -147,10 +147,10 @@ return $.widget( "ui.spinner", {
// If the input is focused then this.previous is properly set from
// when the input first received focus. If the input is not focused
// then we need to set this.previous based on the value before spinning.
previous = this.element[0] === this.document[0].activeElement ?
previous = this.element[0] === $.ui.safeActiveElement( this.document[0] ) ?
this.previous : this.element.val();
function checkFocus() {
var isActive = this.element[0] === this.document[0].activeElement;
var isActive = this.element[0] === $.ui.safeActiveElement( this.document[0] );
if ( !isActive ) {
this.element.focus();
this.previous = previous;

View File

@ -155,7 +155,7 @@ return $.widget( "ui.tabs", {
},
_tabKeydown: function( event ) {
var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
var focusedTab = $( $.ui.safeActiveElement( this.document[0] ) ).closest( "li" ),
selectedIndex = this.tabs.index( focusedTab ),
goingForward = true;