Skip to content

Commit 8c66934

Browse files
Ryan Oriecuiascottgonzalez
Ryan Oriecuia
authored andcommitted
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 jquerygh-1730
1 parent 51461d5 commit 8c66934

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

tests/unit/draggable/core.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,36 @@ QUnit.test( "blur behavior - descendant of handle", function( assert ) {
338338
} );
339339
} );
340340

341+
QUnit.test( "blur behavior - off handle", function( assert ) {
342+
var ready = assert.async();
343+
assert.expect( 3 );
344+
345+
var element = $( "#draggable2" ).draggable( { handle: "span" } ),
346+
focusElement = $( "<div tabindex='1'></div>" ).appendTo( element );
347+
348+
// Mock $.ui.safeBlur with a spy
349+
var _safeBlur = $.ui.safeBlur;
350+
var blurCalledCount = 0;
351+
$.ui.safeBlur = function() {
352+
blurCalledCount++;
353+
};
354+
355+
testHelper.onFocus( focusElement, function() {
356+
assert.strictEqual( document.activeElement, focusElement.get( 0 ), "test element is focused before mousing down on a draggable" );
357+
358+
testHelper.move( element, 1, 1 );
359+
assert.strictEqual( blurCalledCount, 0, "draggable doesn't blur when mousing down off handle" );
360+
361+
testHelper.move( element.find( "span" ), 1, 1 );
362+
assert.strictEqual( blurCalledCount, 1, "draggable blurs when mousing down on handle" );
363+
364+
// Restore safeBlur
365+
$.ui.safeBlur = _safeBlur;
366+
367+
ready();
368+
} );
369+
} );
370+
341371
QUnit.test( "ui-draggable-handle assigned to appropriate element", function( assert ) {
342372
assert.expect( 5 );
343373

ui/widgets/draggable.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,6 @@ $.widget( "ui.draggable", $.ui.mouse, {
103103
_mouseCapture: function( event ) {
104104
var o = this.options;
105105

106-
this._blurActiveElement( event );
107-
108106
// Among others, prevent a drag on a resizable-handle
109107
if ( this.helper || o.disabled ||
110108
$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
@@ -117,6 +115,8 @@ $.widget( "ui.draggable", $.ui.mouse, {
117115
return false;
118116
}
119117

118+
this._blurActiveElement( event );
119+
120120
this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
121121

122122
return true;
@@ -147,11 +147,10 @@ $.widget( "ui.draggable", $.ui.mouse, {
147147
var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
148148
target = $( event.target );
149149

150-
// Only blur if the event occurred on an element that is:
151-
// 1) within the draggable handle
152-
// 2) but not within the currently focused element
150+
// Don't blur if the event occurred on an element that is within
151+
// the currently focused element
153152
// See #10527, #12472
154-
if ( this._getHandle( event ) && target.closest( activeElement ).length ) {
153+
if ( target.closest( activeElement ).length ) {
155154
return;
156155
}
157156

0 commit comments

Comments
 (0)