Skip to content

Commit f330278

Browse files
committed
Core: Add methods to work around IE active element bugs
Closes gh-1478
1 parent 6111b17 commit f330278

File tree

7 files changed

+40
-38
lines changed

7 files changed

+40
-38
lines changed

ui/autocomplete.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ $.widget( "ui.autocomplete", {
286286
previous = this.previous;
287287

288288
// only trigger when focus was lost (click on menu)
289-
if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
289+
if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
290290
this.element.focus();
291291
this.previous = previous;
292292
// #6109 - IE triggers two focus events and the second

ui/core.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,31 @@ $.extend( $.ui, {
4949
SPACE: 32,
5050
TAB: 9,
5151
UP: 38
52+
},
53+
54+
// Internal use only
55+
safeActiveElement: function( document ) {
56+
var activeElement;
57+
58+
// Support: IE 9 only
59+
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
60+
try {
61+
activeElement = document.activeElement;
62+
} catch ( error ) {
63+
activeElement = document.body;
64+
}
65+
66+
return activeElement;
67+
},
68+
69+
// Internal use only
70+
safeBlur: function( element ) {
71+
72+
// Support: IE9 - 10 only
73+
// If the <body> is blurred, IE will switch windows, see #9420
74+
if ( element && element.nodeName.toLowerCase() !== "body" ) {
75+
$( element ).blur();
76+
}
5277
}
5378
});
5479

ui/dialog.js

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ $.widget( "ui.dialog", {
194194
enable: $.noop,
195195

196196
close: function( event ) {
197-
var activeElement,
198-
that = this;
197+
var that = this;
199198

200199
if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
201200
return;
@@ -208,21 +207,10 @@ $.widget( "ui.dialog", {
208207

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

211-
// support: IE9
212-
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
213-
try {
214-
activeElement = this.document[ 0 ].activeElement;
215-
216-
// Support: IE9, IE10
217-
// If the <body> is blurred, IE will switch windows, see #4520
218-
if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
219-
220-
// Hiding a focused element doesn't trigger blur in WebKit
221-
// so in case we have nothing to focus on, explicitly blur the active element
222-
// https://bugs.webkit.org/show_bug.cgi?id=47182
223-
$( activeElement ).blur();
224-
}
225-
} catch ( error ) {}
210+
// Hiding a focused element doesn't trigger blur in WebKit
211+
// so in case we have nothing to focus on, explicitly blur the active element
212+
// https://bugs.webkit.org/show_bug.cgi?id=47182
213+
$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
226214
}
227215

228216
this._hide( this.uiDialog, this.options.hide, function() {
@@ -266,7 +254,7 @@ $.widget( "ui.dialog", {
266254
}
267255

268256
this._isOpen = true;
269-
this.opener = $( this.document[ 0 ].activeElement );
257+
this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
270258

271259
this._size();
272260
this._position();
@@ -322,7 +310,7 @@ $.widget( "ui.dialog", {
322310

323311
_keepFocus: function( event ) {
324312
function checkFocus() {
325-
var activeElement = this.document[0].activeElement,
313+
var activeElement = $.ui.safeActiveElement( this.document[0] ),
326314
isActive = this.uiDialog[0] === activeElement ||
327315
$.contains( this.uiDialog[0], activeElement );
328316
if ( !isActive ) {

ui/draggable.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -141,25 +141,14 @@ $.widget("ui.draggable", $.ui.mouse, {
141141
},
142142

143143
_blurActiveElement: function( event ) {
144-
var document = this.document[ 0 ];
145144

146145
// Only need to blur if the event occurred on the draggable itself, see #10527
147146
if ( !this.handleElement.is( event.target ) ) {
148147
return;
149148
}
150149

151-
// support: IE9
152-
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
153-
try {
154-
155-
// Support: IE9, IE10
156-
// If the <body> is blurred, IE will switch windows, see #9520
157-
if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
158-
159-
// Blur any element that currently has focus, see #4261
160-
$( document.activeElement ).blur();
161-
}
162-
} catch ( error ) {}
150+
// Blur any element that currently has focus, see #4261
151+
$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
163152
},
164153

165154
_mouseStart: function(event) {

ui/menu.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ return $.widget( "ui.menu", {
9595
// Open submenu on click
9696
if ( target.has( ".ui-menu" ).length ) {
9797
this.expand( event );
98-
} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
98+
} else if ( !this.element.is( ":focus" ) && $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( ".ui-menu" ).length ) {
9999

100100
// Redirect focus to the menu
101101
this.element.trigger( "focus", [ true ] );
@@ -135,7 +135,7 @@ return $.widget( "ui.menu", {
135135
},
136136
blur: function( event ) {
137137
this._delay(function() {
138-
if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
138+
if ( !$.contains( this.element[0], $.ui.safeActiveElement( this.document[0] ) ) ) {
139139
this.collapseAll( event );
140140
}
141141
});

ui/spinner.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ return $.widget( "ui.spinner", {
160160
// If the input is focused then this.previous is properly set from
161161
// when the input first received focus. If the input is not focused
162162
// then we need to set this.previous based on the value before spinning.
163-
previous = this.element[0] === this.document[0].activeElement ?
163+
previous = this.element[0] === $.ui.safeActiveElement( this.document[0] ) ?
164164
this.previous : this.element.val();
165165
function checkFocus() {
166-
var isActive = this.element[0] === this.document[0].activeElement;
166+
var isActive = this.element[0] === $.ui.safeActiveElement( this.document[0] );
167167
if ( !isActive ) {
168168
this.element.focus();
169169
this.previous = previous;

ui/tabs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ return $.widget( "ui.tabs", {
164164
},
165165

166166
_tabKeydown: function( event ) {
167-
var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
167+
var focusedTab = $( $.ui.safeActiveElement( this.document[0] ) ).closest( "li" ),
168168
selectedIndex = this.tabs.index( focusedTab ),
169169
goingForward = true;
170170

0 commit comments

Comments
 (0)