]> source.dussan.org Git - jquery-ui.git/commitdiff
Core: Add methods to work around IE active element bugs
authorScott González <scott.gonzalez@gmail.com>
Mon, 9 Mar 2015 20:03:22 +0000 (16:03 -0400)
committerScott González <scott.gonzalez@gmail.com>
Thu, 9 Jun 2016 16:08:56 +0000 (12:08 -0400)
Closes gh-1478

(cherry picked from commit f33027840cdac5152599da66635981bbe68c6bda)

ui/autocomplete.js
ui/core.js
ui/dialog.js
ui/draggable.js
ui/menu.js
ui/spinner.js
ui/tabs.js

index dc970b5c704b914d1db0d5e0a54d3d0bc4cd0a25..6e477bb41aa1594663e301708571bbeef0c27e59 100644 (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
index 0b2e039509c3b91fd88ed1f7ad771178b22438b0..40703d73dd2ffeff466e35b31b770e910e538f06 100644 (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();
+               }
        }
 });
 
index d33f72c1e920f6362da5dc8d005916ee5a10dcc7..c48d76db3aa0966987de981da910672bd6ec319c 100644 (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 ) {
index c3821ba8eec185da6472b9e135cc3ffb536ca26b..7437be10857441abbd0e3579a19799aa70429570 100644 (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) {
index 4b14359358fdd50547518b7516a67c2e41e24de7..bfd3f4958c84e0831543ad2e858ab8580cd001b0 100644 (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 );
                                        }
                                });
index 9beeb133c5848634120105a934491a7dbbacac7c..ccbce7c96fba41f5cbe08395bc8b77756cf9bba7 100644 (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;
index db4c9726a411077d9c2f7140090a5ceb1b930664..0dd0605b8821f62503d62017c69aa88be4b5e803 100644 (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;