Bug 534833 - click event is occasionally lost in text form controls when focus event changes the value of the control, r=roc
--HG-- extra : rebase_source : 9c90b0ed41ab12c38d264edc839227cdd0d8817f
This commit is contained in:
Родитель
9659386e03
Коммит
9eec6fc2fc
|
@ -969,8 +969,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEventStateManager)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGestureDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGestureDownFrameOwner);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastLeftMouseDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastLeftMouseDownContentParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastMiddleMouseDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastMiddleMouseDownContentParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastRightMouseDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastRightMouseDownContentParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mActiveContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mHoverContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDragOverContent);
|
||||
|
@ -987,8 +990,11 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEventStateManager)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGestureDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGestureDownFrameOwner);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastLeftMouseDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastLeftMouseDownContentParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastMiddleMouseDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastMiddleMouseDownContentParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastRightMouseDownContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastRightMouseDownContentParent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mActiveContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mHoverContent);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDragOverContent);
|
||||
|
@ -3721,6 +3727,12 @@ nsEventStateManager::UpdateDragDataTransfer(nsDragEvent* dragEvent)
|
|||
}
|
||||
}
|
||||
|
||||
nsIContent* GetParentContentForMouseTarget(nsIContent* aContent)
|
||||
{
|
||||
return aContent && aContent->IsInNativeAnonymousSubtree() ?
|
||||
aContent->GetParent() : nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventStateManager::SetClickCount(nsPresContext* aPresContext,
|
||||
nsMouseEvent *aEvent,
|
||||
|
@ -3733,42 +3745,54 @@ nsEventStateManager::SetClickCount(nsPresContext* aPresContext,
|
|||
case nsMouseEvent::eLeftButton:
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||
mLastLeftMouseDownContent = mouseContent;
|
||||
mLastLeftMouseDownContentParent =
|
||||
GetParentContentForMouseTarget(mouseContent);
|
||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||
if (mLastLeftMouseDownContent == mouseContent) {
|
||||
if (mLastLeftMouseDownContent == mouseContent ||
|
||||
mLastLeftMouseDownContentParent == mouseContent) {
|
||||
aEvent->clickCount = mLClickCount;
|
||||
mLClickCount = 0;
|
||||
} else {
|
||||
aEvent->clickCount = 0;
|
||||
}
|
||||
mLastLeftMouseDownContent = nsnull;
|
||||
mLastLeftMouseDownContentParent = nsnull;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsMouseEvent::eMiddleButton:
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||
mLastMiddleMouseDownContent = mouseContent;
|
||||
mLastMiddleMouseDownContentParent =
|
||||
GetParentContentForMouseTarget(mouseContent);
|
||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||
if (mLastMiddleMouseDownContent == mouseContent) {
|
||||
if (mLastMiddleMouseDownContent == mouseContent ||
|
||||
mLastMiddleMouseDownContentParent == mouseContent) {
|
||||
aEvent->clickCount = mMClickCount;
|
||||
mMClickCount = 0;
|
||||
} else {
|
||||
aEvent->clickCount = 0;
|
||||
}
|
||||
// XXX Why we don't clear mLastMiddleMouseDownContent here?
|
||||
mLastMiddleMouseDownContent = nsnull;
|
||||
mLastMiddleMouseDownContentParent = nsnull;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsMouseEvent::eRightButton:
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||
mLastRightMouseDownContent = mouseContent;
|
||||
mLastRightMouseDownContentParent =
|
||||
GetParentContentForMouseTarget(mouseContent);
|
||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||
if (mLastRightMouseDownContent == mouseContent) {
|
||||
if (mLastRightMouseDownContent == mouseContent ||
|
||||
mLastRightMouseDownContentParent == mouseContent) {
|
||||
aEvent->clickCount = mRClickCount;
|
||||
mRClickCount = 0;
|
||||
} else {
|
||||
aEvent->clickCount = 0;
|
||||
}
|
||||
// XXX Why we don't clear mLastRightMouseDownContent here?
|
||||
mLastRightMouseDownContent = nsnull;
|
||||
mLastRightMouseDownContentParent = nsnull;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -360,8 +360,11 @@ protected:
|
|||
PRPackedBool mGestureDownMeta;
|
||||
|
||||
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
|
||||
nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;
|
||||
nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
|
||||
nsCOMPtr<nsIContent> mLastMiddleMouseDownContentParent;
|
||||
nsCOMPtr<nsIContent> mLastRightMouseDownContent;
|
||||
nsCOMPtr<nsIContent> mLastRightMouseDownContentParent;
|
||||
|
||||
nsCOMPtr<nsIContent> mActiveContent;
|
||||
nsCOMPtr<nsIContent> mHoverContent;
|
||||
|
|
|
@ -82,6 +82,7 @@ _TEST_FILES = \
|
|||
test_bug502818.html \
|
||||
test_bug508479.html \
|
||||
test_bug517851.html \
|
||||
test_bug534833.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=534833
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 534833</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="runTests()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534833">Mozilla Bug 534833</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 534833 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var input1GotClick = 0;
|
||||
var input2GotClick = 0;
|
||||
var textarea1GotClick = 0;
|
||||
var textarea2GotClick = 0;
|
||||
var div1GotClick = 0;
|
||||
var div2GotClick = 0;
|
||||
|
||||
var tests = [ { element: "text", clickText: true },
|
||||
{ element: "text2", clickText: false },
|
||||
{ element: "area", clickText: true },
|
||||
{ element: "area2", clickText: false },
|
||||
{ element: "d", clickText: true },
|
||||
{ element: "d", clickText: false },
|
||||
{ element: "d2", clickText: true },
|
||||
{ element: "d2", clickText: false }
|
||||
];
|
||||
|
||||
function nextTest_() {
|
||||
if (!tests.length) {
|
||||
finishTests();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
var el = document.getElementById(test.element);
|
||||
el.scrollIntoView(true);
|
||||
if (test.clickText) {
|
||||
synthesizeMouse(el, 5, 5, {type : "mousedown" });
|
||||
synthesizeMouse(el, 5, 5, {type : "mouseup" });
|
||||
} else {
|
||||
synthesizeMouse(el, el.getBoundingClientRect().width - 5, 5, {type : "mousedown" });
|
||||
synthesizeMouse(el, el.getBoundingClientRect().width - 5, 5, {type : "mouseup" });
|
||||
}
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function nextTest() {
|
||||
document.getElementById("initialfocus").focus();
|
||||
setTimeout(nextTest_, 100);
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
var t = document.getElementById("text");
|
||||
var t2 = document.getElementById("text2");
|
||||
var a = document.getElementById("area");
|
||||
var a2 = document.getElementById("area2");
|
||||
var d = document.getElementById("d");
|
||||
var d2 = document.getElementById("d2");
|
||||
|
||||
// input 1
|
||||
t.onfocus = function(e) {
|
||||
t.value = "";
|
||||
}
|
||||
t.onclick = function(e) {
|
||||
++input1GotClick;
|
||||
}
|
||||
|
||||
// input 2
|
||||
t2.onfocus = function(e) {
|
||||
t2.value = "";
|
||||
}
|
||||
t2.onclick = function(e) {
|
||||
++input2GotClick;
|
||||
}
|
||||
|
||||
// textarea 1
|
||||
a.onfocus = function(e) {
|
||||
a.value = "";
|
||||
}
|
||||
a.onclick = function(e) {
|
||||
++textarea1GotClick;
|
||||
}
|
||||
|
||||
// textarea 2
|
||||
a2.onfocus = function(e) {
|
||||
a2.value = "";
|
||||
}
|
||||
a2.onclick = function(e) {
|
||||
++textarea2GotClick;
|
||||
}
|
||||
|
||||
// div 1
|
||||
var c = 0;
|
||||
d.onmousedown = function(e) {
|
||||
d.textContent = (++c) + " / click before or after |";
|
||||
}
|
||||
d.onclick = function(e) {
|
||||
++div1GotClick;
|
||||
}
|
||||
|
||||
// div 2
|
||||
var c2 = 0;
|
||||
d2.onmousedown = function(e) {
|
||||
d2.firstChild.data = (++c2) + " / click before or after |";
|
||||
}
|
||||
d2.onclick = function(e) {
|
||||
++div2GotClick;
|
||||
}
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function finishTests() {
|
||||
is(input1GotClick, 1, "input element should have got a click!");
|
||||
is(input2GotClick, 1, "input element should have got a click! (2)");
|
||||
is(textarea1GotClick, 1, "textarea element should have got a click!");
|
||||
is(textarea2GotClick, 1, "textarea element should have got a click! (2)");
|
||||
is(div1GotClick, 1, "div element's content text was replaced, it should have got 1 click!");
|
||||
is(div2GotClick, 2, "div element's content text was modified, it should have got 2 clicks!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<input type="text" id="initialfocus"><br>
|
||||
<input type="text" id="text" value="click before |" style="width: 95%;"><br>
|
||||
<input type="text" id="text2" value="click after |" style="width: 95%;">
|
||||
<br>
|
||||
<textarea id="area" rows="2" style="width: 95%;">
|
||||
click before
|
||||
|
|
||||
</textarea><br>
|
||||
<textarea id="area2" rows="2" style="width: 95%;">
|
||||
click after |
|
||||
</textarea>
|
||||
<div id="d" style="border: 1px solid black;">click before or after |</div>
|
||||
<div id="d2" style="border: 1px solid black;">click before or after |</div>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче