Mouse: Only detect out of document mouseups after a mousemove

This prevents the firing of mouseup in the case of IE<9, which will
fire a mousemove event if content is placed under the cursor on
mousedown.

Fixes #7778
This commit is contained in:
Mike Sherov 2014-08-19 15:09:28 -04:00
parent 233f08e07f
commit e12e3e12b1
5 changed files with 79 additions and 7 deletions

View File

@ -144,7 +144,7 @@ $.extend( $.simulate.prototype, {
0: 1,
1: 4,
2: 2
}[ event.button ] || event.button;
}[ event.button ] || ( event.button === -1 ? 0 : event.button );
}
return event;

View File

@ -111,6 +111,23 @@ test( "#8269: Removing draggable element on drop", function() {
}
});
// http://bugs.jqueryui.com/ticket/7778
// drag element breaks in IE8 when its content is replaced onmousedown
test( "Stray mousemove after mousedown still drags", function() {
expect( 2 );
var element = $( "#draggable1" ).draggable({ scroll: false });
// In IE8, when content is placed under the mouse (e.g. when draggable content is replaced
// on mousedown), mousemove is triggered on those elements even though the mouse hasn't moved.
// Support: IE <9
element.bind( "mousedown", function() {
$( document ).simulate( "mousemove", { button: -1 });
});
TestHelpers.draggable.shouldMove( element, "element is draggable" );
});
test( "#6258: not following mouse when scrolled and using overflow-y: scroll", function() {
expect( 2 );

View File

@ -0,0 +1,38 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Draggable Visual Test</title>
<link rel="stylesheet" href="../../../themes/base/all.css">
<script src="../../../external/jquery/jquery.js"></script>
<script src="../../../ui/core.js"></script>
<script src="../../../ui/widget.js"></script>
<script src="../../../ui/mouse.js"></script>
<script src="../../../ui/draggable.js"></script>
<script>
$(function() {
$( "#draggable" )
.draggable()
.bind( "mousedown", function() {
$( this ).html( "<div>replaced</div>" );
});
});
</script>
<style>
#draggable {
background: green;
height: 75px;
width: 75px;
}
</style>
</head>
<body>
<p>WHAT: A draggable, whose content is replaced onmousedown.</p>
<p>EXPECTED: In IE8, the draggable can actually be dragged.</p>
<div id="draggable"><div>content</div></div>
</body>
</html>

View File

@ -40,6 +40,11 @@
<li><a href="dialog/stacking.html">Overlapping dialogs</a></li>
</ul>
<h2>Draggable</h2>
<ul>
<li><a href="draggable/replaced.html">Replaced Content On Mousedown</a></li>
</ul>
<h2>Effects</h2>
<ul>
<li><a href="effects/all.html">All</a></li>

View File

@ -70,6 +70,8 @@ return $.widget("ui.mouse", {
return;
}
this._mouseMoved = false;
// we may have missed mouseup (out of window)
(this._mouseStarted && this._mouseUp(event));
@ -123,13 +125,23 @@ return $.widget("ui.mouse", {
},
_mouseMove: function(event) {
// IE mouseup check - mouseup happened when mouse was out of window
if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
return this._mouseUp(event);
// Only check for mouseups outside the document if you've moved inside the document
// at least once. This prevents the firing of mouseup in the case of IE<9, which will
// fire a mousemove event if content is placed under the cursor. See #7778
// Support: IE <9
if ( this._mouseMoved ) {
// IE mouseup check - mouseup happened when mouse was out of window
if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
return this._mouseUp(event);
// Iframe mouseup check - mouseup occurred in another document
} else if ( !event.which ) {
return this._mouseUp( event );
// Iframe mouseup check - mouseup occurred in another document
} else if ( !event.which ) {
return this._mouseUp( event );
}
}
if ( event.which || event.button ) {
this._mouseMoved = true;
}
if (this._mouseStarted) {