Skip to content

Commit 2256eed

Browse files
committed
Core: Add methods to work around IE active element bugs
Closes jquerygh-1478 (cherry picked from commit f330278)
1 parent d86df4b commit 2256eed

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
@@ -278,7 +278,7 @@ $.widget( "ui.autocomplete", {
278278
previous = this.previous;
279279

280280
// only trigger when focus was lost (click on menu)
281-
if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
281+
if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
282282
this.element.focus();
283283
this.previous = previous;
284284
// #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
@@ -43,6 +43,31 @@ $.extend( $.ui, {
4343
SPACE: 32,
4444
TAB: 9,
4545
UP: 38
46+
},
47+
48+
// Internal use only
49+
safeActiveElement: function( document ) {
50+
var activeElement;
51+
52+
// Support: IE 9 only
53+
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
54+
try {
55+
activeElement = document.activeElement;
56+
} catch ( error ) {
57+
activeElement = document.body;
58+
}
59+
60+
return activeElement;
61+
},
62+
63+
// Internal use only
64+
safeBlur: function( element ) {
65+
66+
// Support: IE9 - 10 only
67+
// If the <body> is blurred, IE will switch windows, see #9420
68+
if ( element && element.nodeName.toLowerCase() !== "body" ) {
69+
$( element ).blur();
70+
}
4671
}
4772
});
4873

ui/dialog.js

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

185185
close: function( event ) {
186-
var activeElement,
187-
that = this;
186+
var that = this;
188187

189188
if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
190189
return;
@@ -197,21 +196,10 @@ return $.widget( "ui.dialog", {
197196

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

200-
// support: IE9
201-
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
202-
try {
203-
activeElement = this.document[ 0 ].activeElement;
204-
205-
// Support: IE9, IE10
206-
// If the <body> is blurred, IE will switch windows, see #4520
207-
if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
208-
209-
// Hiding a focused element doesn't trigger blur in WebKit
210-
// so in case we have nothing to focus on, explicitly blur the active element
211-
// https://bugs.webkit.org/show_bug.cgi?id=47182
212-
$( activeElement ).blur();
213-
}
214-
} catch ( error ) {}
199+
// Hiding a focused element doesn't trigger blur in WebKit
200+
// so in case we have nothing to focus on, explicitly blur the active element
201+
// https://bugs.webkit.org/show_bug.cgi?id=47182
202+
$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
215203
}
216204

217205
this._hide( this.uiDialog, this.options.hide, function() {
@@ -255,7 +243,7 @@ return $.widget( "ui.dialog", {
255243
}
256244

257245
this._isOpen = true;
258-
this.opener = $( this.document[ 0 ].activeElement );
246+
this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
259247

260248
this._size();
261249
this._position();
@@ -311,7 +299,7 @@ return $.widget( "ui.dialog", {
311299

312300
_keepFocus: function( event ) {
313301
function checkFocus() {
314-
var activeElement = this.document[0].activeElement,
302+
var activeElement = $.ui.safeActiveElement( this.document[0] ),
315303
isActive = this.uiDialog[0] === activeElement ||
316304
$.contains( this.uiDialog[0], activeElement );
317305
if ( !isActive ) {

ui/draggable.js

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

138138
_blurActiveElement: function( event ) {
139-
var document = this.document[ 0 ];
140139

141140
// Only need to blur if the event occurred on the draggable itself, see #10527
142141
if ( !this.handleElement.is( event.target ) ) {
143142
return;
144143
}
145144

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

160149
_mouseStart: function(event) {

ui/menu.js

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

9292
// Redirect focus to the menu
9393
this.element.trigger( "focus", [ true ] );
@@ -126,7 +126,7 @@ return $.widget( "ui.menu", {
126126
},
127127
blur: function( event ) {
128128
this._delay(function() {
129-
if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
129+
if ( !$.contains( this.element[0], $.ui.safeActiveElement( this.document[0] ) ) ) {
130130
this.collapseAll( event );
131131
}
132132
});

ui/spinner.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ return $.widget( "ui.spinner", {
147147
// If the input is focused then this.previous is properly set from
148148
// when the input first received focus. If the input is not focused
149149
// then we need to set this.previous based on the value before spinning.
150-
previous = this.element[0] === this.document[0].activeElement ?
150+
previous = this.element[0] === $.ui.safeActiveElement( this.document[0] ) ?
151151
this.previous : this.element.val();
152152
function checkFocus() {
153-
var isActive = this.element[0] === this.document[0].activeElement;
153+
var isActive = this.element[0] === $.ui.safeActiveElement( this.document[0] );
154154
if ( !isActive ) {
155155
this.element.focus();
156156
this.previous = previous;

ui/tabs.js

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

157157
_tabKeydown: function( event ) {
158-
var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
158+
var focusedTab = $( $.ui.safeActiveElement( this.document[0] ) ).closest( "li" ),
159159
selectedIndex = this.tabs.index( focusedTab ),
160160
goingForward = true;
161161

0 commit comments

Comments
 (0)