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(mGestureDownContent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGestureDownFrameOwner);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGestureDownFrameOwner);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastLeftMouseDownContent);
|
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(mLastMiddleMouseDownContent);
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastMiddleMouseDownContentParent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastRightMouseDownContent);
|
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(mActiveContent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mHoverContent);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mHoverContent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDragOverContent);
|
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(mGestureDownContent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGestureDownFrameOwner);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGestureDownFrameOwner);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastLeftMouseDownContent);
|
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(mLastMiddleMouseDownContent);
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastMiddleMouseDownContentParent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastRightMouseDownContent);
|
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(mActiveContent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mHoverContent);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mHoverContent);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDragOverContent);
|
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
|
nsresult
|
||||||
nsEventStateManager::SetClickCount(nsPresContext* aPresContext,
|
nsEventStateManager::SetClickCount(nsPresContext* aPresContext,
|
||||||
nsMouseEvent *aEvent,
|
nsMouseEvent *aEvent,
|
||||||
|
@ -3733,42 +3745,54 @@ nsEventStateManager::SetClickCount(nsPresContext* aPresContext,
|
||||||
case nsMouseEvent::eLeftButton:
|
case nsMouseEvent::eLeftButton:
|
||||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||||
mLastLeftMouseDownContent = mouseContent;
|
mLastLeftMouseDownContent = mouseContent;
|
||||||
|
mLastLeftMouseDownContentParent =
|
||||||
|
GetParentContentForMouseTarget(mouseContent);
|
||||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||||
if (mLastLeftMouseDownContent == mouseContent) {
|
if (mLastLeftMouseDownContent == mouseContent ||
|
||||||
|
mLastLeftMouseDownContentParent == mouseContent) {
|
||||||
aEvent->clickCount = mLClickCount;
|
aEvent->clickCount = mLClickCount;
|
||||||
mLClickCount = 0;
|
mLClickCount = 0;
|
||||||
} else {
|
} else {
|
||||||
aEvent->clickCount = 0;
|
aEvent->clickCount = 0;
|
||||||
}
|
}
|
||||||
mLastLeftMouseDownContent = nsnull;
|
mLastLeftMouseDownContent = nsnull;
|
||||||
|
mLastLeftMouseDownContentParent = nsnull;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nsMouseEvent::eMiddleButton:
|
case nsMouseEvent::eMiddleButton:
|
||||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||||
mLastMiddleMouseDownContent = mouseContent;
|
mLastMiddleMouseDownContent = mouseContent;
|
||||||
|
mLastMiddleMouseDownContentParent =
|
||||||
|
GetParentContentForMouseTarget(mouseContent);
|
||||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||||
if (mLastMiddleMouseDownContent == mouseContent) {
|
if (mLastMiddleMouseDownContent == mouseContent ||
|
||||||
|
mLastMiddleMouseDownContentParent == mouseContent) {
|
||||||
aEvent->clickCount = mMClickCount;
|
aEvent->clickCount = mMClickCount;
|
||||||
mMClickCount = 0;
|
mMClickCount = 0;
|
||||||
} else {
|
} else {
|
||||||
aEvent->clickCount = 0;
|
aEvent->clickCount = 0;
|
||||||
}
|
}
|
||||||
// XXX Why we don't clear mLastMiddleMouseDownContent here?
|
mLastMiddleMouseDownContent = nsnull;
|
||||||
|
mLastMiddleMouseDownContentParent = nsnull;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nsMouseEvent::eRightButton:
|
case nsMouseEvent::eRightButton:
|
||||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||||
mLastRightMouseDownContent = mouseContent;
|
mLastRightMouseDownContent = mouseContent;
|
||||||
|
mLastRightMouseDownContentParent =
|
||||||
|
GetParentContentForMouseTarget(mouseContent);
|
||||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||||
if (mLastRightMouseDownContent == mouseContent) {
|
if (mLastRightMouseDownContent == mouseContent ||
|
||||||
|
mLastRightMouseDownContentParent == mouseContent) {
|
||||||
aEvent->clickCount = mRClickCount;
|
aEvent->clickCount = mRClickCount;
|
||||||
mRClickCount = 0;
|
mRClickCount = 0;
|
||||||
} else {
|
} else {
|
||||||
aEvent->clickCount = 0;
|
aEvent->clickCount = 0;
|
||||||
}
|
}
|
||||||
// XXX Why we don't clear mLastRightMouseDownContent here?
|
mLastRightMouseDownContent = nsnull;
|
||||||
|
mLastRightMouseDownContentParent = nsnull;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,8 +360,11 @@ protected:
|
||||||
PRPackedBool mGestureDownMeta;
|
PRPackedBool mGestureDownMeta;
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
|
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
|
||||||
|
nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;
|
||||||
nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
|
nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
|
||||||
|
nsCOMPtr<nsIContent> mLastMiddleMouseDownContentParent;
|
||||||
nsCOMPtr<nsIContent> mLastRightMouseDownContent;
|
nsCOMPtr<nsIContent> mLastRightMouseDownContent;
|
||||||
|
nsCOMPtr<nsIContent> mLastRightMouseDownContentParent;
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> mActiveContent;
|
nsCOMPtr<nsIContent> mActiveContent;
|
||||||
nsCOMPtr<nsIContent> mHoverContent;
|
nsCOMPtr<nsIContent> mHoverContent;
|
||||||
|
|
|
@ -82,6 +82,7 @@ _TEST_FILES = \
|
||||||
test_bug502818.html \
|
test_bug502818.html \
|
||||||
test_bug508479.html \
|
test_bug508479.html \
|
||||||
test_bug517851.html \
|
test_bug517851.html \
|
||||||
|
test_bug534833.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
_CHROME_FILES = \
|
_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>
|
Загрузка…
Ссылка в новой задаче