Permalink
Browse files

Core: Add methods to work around IE active element bugs

Closes gh-1478
1 parent 6111b17 commit f33027840cdac5152599da66635981bbe68c6bda @scottgonzalez scottgonzalez committed Mar 9, 2015
Showing with 40 additions and 38 deletions.
  1. +1 −1 ui/autocomplete.js
  2. +25 −0 ui/core.js
  3. +7 −19 ui/dialog.js
  4. +2 −13 ui/draggable.js
  5. +2 −2 ui/menu.js
  6. +2 −2 ui/spinner.js
  7. +1 −1 ui/tabs.js
View
@@ -286,7 +286,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
@@ -49,6 +49,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
@@ -194,8 +194,7 @@ $.widget( "ui.dialog", {
enable: $.noop,
close: function( event ) {
- var activeElement,
- that = this;
+ var that = this;
if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
return;
@@ -208,21 +207,10 @@ $.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() {
@@ -266,7 +254,7 @@ $.widget( "ui.dialog", {
}
this._isOpen = true;
- this.opener = $( this.document[ 0 ].activeElement );
+ this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
this._size();
this._position();
@@ -322,7 +310,7 @@ $.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
@@ -141,25 +141,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
@@ -95,7 +95,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 ] );
@@ -135,7 +135,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
@@ -160,10 +160,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
@@ -164,7 +164,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;

0 comments on commit f330278

Please sign in to comment.