diff options
author | Ryan Oriecuia <ryan.oriecuia@visioncritical.com> | 2016-08-16 16:52:15 -0700 |
---|---|---|
committer | Scott González <scott.gonzalez@gmail.com> | 2016-09-13 08:53:00 -0400 |
commit | 8c66934434214ab92cbcf46240beb739154fdfbf (patch) | |
tree | 7658773c0a719c533cb48325aae48586c2c0b526 | |
parent | 51461d523868c168f2e12eeb547c1cf8b7cf59cf (diff) | |
download | jquery-ui-8c66934434214ab92cbcf46240beb739154fdfbf.tar.gz jquery-ui-8c66934434214ab92cbcf46240beb739154fdfbf.zip |
Draggable: Fix spurious blur in dialogs on mousedown
I was running into a problem with a popup menu control in a dialog; clicks
weren't working (but keyboard was working fine). It turned out that the menu
was getting destroyed before the click event could fire.
Tracked down the issue to the way draggable blurs focused controls; it was
doing the blur before it ran through the logic to figure out if the drag was
actually on the handle. I've moved the blur below these checks, so it'll only
blur things if it actually needs to handle the drag. Otherwise, it asserts no
opinion on what should and shouldn't be focused, which seems like the way
things ought to be.
Also, added a unit test to check for the expected behavior.
Fixes #15046
Closes gh-1730
-rw-r--r-- | tests/unit/draggable/core.js | 30 | ||||
-rw-r--r-- | ui/widgets/draggable.js | 11 |
2 files changed, 35 insertions, 6 deletions
diff --git a/tests/unit/draggable/core.js b/tests/unit/draggable/core.js index 2ec102598..1dd6f572a 100644 --- a/tests/unit/draggable/core.js +++ b/tests/unit/draggable/core.js @@ -338,6 +338,36 @@ QUnit.test( "blur behavior - descendant of handle", function( assert ) { } ); } ); +QUnit.test( "blur behavior - off handle", function( assert ) { + var ready = assert.async(); + assert.expect( 3 ); + + var element = $( "#draggable2" ).draggable( { handle: "span" } ), + focusElement = $( "<div tabindex='1'></div>" ).appendTo( element ); + + // Mock $.ui.safeBlur with a spy + var _safeBlur = $.ui.safeBlur; + var blurCalledCount = 0; + $.ui.safeBlur = function() { + blurCalledCount++; + }; + + testHelper.onFocus( focusElement, function() { + assert.strictEqual( document.activeElement, focusElement.get( 0 ), "test element is focused before mousing down on a draggable" ); + + testHelper.move( element, 1, 1 ); + assert.strictEqual( blurCalledCount, 0, "draggable doesn't blur when mousing down off handle" ); + + testHelper.move( element.find( "span" ), 1, 1 ); + assert.strictEqual( blurCalledCount, 1, "draggable blurs when mousing down on handle" ); + + // Restore safeBlur + $.ui.safeBlur = _safeBlur; + + ready(); + } ); +} ); + QUnit.test( "ui-draggable-handle assigned to appropriate element", function( assert ) { assert.expect( 5 ); diff --git a/ui/widgets/draggable.js b/ui/widgets/draggable.js index 6b862d0d0..9e46c81bb 100644 --- a/ui/widgets/draggable.js +++ b/ui/widgets/draggable.js @@ -103,8 +103,6 @@ $.widget( "ui.draggable", $.ui.mouse, { _mouseCapture: function( event ) { var o = this.options; - this._blurActiveElement( event ); - // Among others, prevent a drag on a resizable-handle if ( this.helper || o.disabled || $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { @@ -117,6 +115,8 @@ $.widget( "ui.draggable", $.ui.mouse, { return false; } + this._blurActiveElement( event ); + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); return true; @@ -147,11 +147,10 @@ $.widget( "ui.draggable", $.ui.mouse, { var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), target = $( event.target ); - // Only blur if the event occurred on an element that is: - // 1) within the draggable handle - // 2) but not within the currently focused element + // Don't blur if the event occurred on an element that is within + // the currently focused element // See #10527, #12472 - if ( this._getHandle( event ) && target.closest( activeElement ).length ) { + if ( target.closest( activeElement ).length ) { return; } |