mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 478536 Crash by removing a scroll target in MozMouseScrollFailed event handler r+sr=roc
This commit is contained in:
parent
7ae9acbaf5
commit
bcf39be0ea
@ -377,6 +377,8 @@ public:
|
|||||||
static void BeginTransaction(nsIFrame* aTargetFrame,
|
static void BeginTransaction(nsIFrame* aTargetFrame,
|
||||||
PRInt32 aNumLines,
|
PRInt32 aNumLines,
|
||||||
PRBool aScrollHorizontal);
|
PRBool aScrollHorizontal);
|
||||||
|
// Be careful, UpdateTransaction may fire a DOM event, therefore, the target
|
||||||
|
// frame might be destroyed in the event handler.
|
||||||
static PRBool UpdateTransaction(PRInt32 aNumLines,
|
static PRBool UpdateTransaction(PRInt32 aNumLines,
|
||||||
PRBool aScrollHorizontal);
|
PRBool aScrollHorizontal);
|
||||||
static void EndTransaction();
|
static void EndTransaction();
|
||||||
@ -543,6 +545,10 @@ nsMouseWheelTransaction::OnFailToScrollTarget()
|
|||||||
sTargetFrame->GetContent(),
|
sTargetFrame->GetContent(),
|
||||||
NS_LITERAL_STRING("MozMouseScrollFailed"),
|
NS_LITERAL_STRING("MozMouseScrollFailed"),
|
||||||
PR_TRUE, PR_TRUE);
|
PR_TRUE, PR_TRUE);
|
||||||
|
// The target frame might be destroyed in the event handler, at that time,
|
||||||
|
// we need to finish the current transaction
|
||||||
|
if (!sTargetFrame)
|
||||||
|
EndTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2734,6 +2740,12 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
|
|||||||
nsIScrollableViewProvider* svp = do_QueryFrame(lastScrollFrame);
|
nsIScrollableViewProvider* svp = do_QueryFrame(lastScrollFrame);
|
||||||
if (svp && (scrollView = svp->GetScrollableView())) {
|
if (svp && (scrollView = svp->GetScrollableView())) {
|
||||||
nsMouseWheelTransaction::UpdateTransaction(aNumLines, aScrollHorizontal);
|
nsMouseWheelTransaction::UpdateTransaction(aNumLines, aScrollHorizontal);
|
||||||
|
// When the scroll event will not scroll any views, UpdateTransaction
|
||||||
|
// fired MozMouseScrollFailed event which is for automated testing.
|
||||||
|
// In the event handler, the target frame might be destroyed. Then,
|
||||||
|
// we should not keep handling this scroll event.
|
||||||
|
if (!nsMouseWheelTransaction::GetTargetFrame())
|
||||||
|
return NS_OK;
|
||||||
} else {
|
} else {
|
||||||
nsMouseWheelTransaction::EndTransaction();
|
nsMouseWheelTransaction::EndTransaction();
|
||||||
lastScrollFrame = nsnull;
|
lastScrollFrame = nsnull;
|
||||||
|
@ -60,6 +60,8 @@ include $(topsrcdir)/config/rules.mk
|
|||||||
_TEST_FILES = test_bug343416.xul \
|
_TEST_FILES = test_bug343416.xul \
|
||||||
test_bug444800.xul \
|
test_bug444800.xul \
|
||||||
test_bug462106.xul \
|
test_bug462106.xul \
|
||||||
|
test_bug478536.xul \
|
||||||
|
window_bug478536.xul \
|
||||||
test_keycodes.xul \
|
test_keycodes.xul \
|
||||||
test_wheeltransaction.xul \
|
test_wheeltransaction.xul \
|
||||||
window_wheeltransaction.xul \
|
window_wheeltransaction.xul \
|
||||||
|
36
widget/tests/test_bug478536.xul
Normal file
36
widget/tests/test_bug478536.xul
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||||
|
type="text/css"?>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=478536
|
||||||
|
-->
|
||||||
|
<window title="Mozilla Bug 478536"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<title>Test for Bug 478536</title>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script class="testbody" type="application/javascript">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
window.open("window_bug478536.xul", "_blank",
|
||||||
|
"chrome,width=600,height=600");
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</window>
|
204
widget/tests/window_bug478536.xul
Normal file
204
widget/tests/window_bug478536.xul
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<window title="Mozilla Bug 478536"
|
||||||
|
width="600" height="600"
|
||||||
|
onload="onload();"
|
||||||
|
onunload="onunload();"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml" id="body">
|
||||||
|
<style type="text/css">
|
||||||
|
#view {
|
||||||
|
overflow: auto;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border: 1px solid;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<pre id="view" onscroll="onScrollView(event);">
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
Text. Text. Text. Text. Text. Text. Text. Text. Text. Text. Text.
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script class="testbody" type="application/javascript">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
function ok(aCondition, aMessage)
|
||||||
|
{
|
||||||
|
window.opener.wrappedJSObject.SimpleTest.ok(aCondition, aMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is(aLeft, aRight, aMessage)
|
||||||
|
{
|
||||||
|
window.opener.wrappedJSObject.SimpleTest.is(aLeft, aRight, aMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isnot(aLeft, aRight, aMessage)
|
||||||
|
{
|
||||||
|
window.opener.wrappedJSObject.SimpleTest.isnot(aLeft, aRight, aMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gBody = document.getElementById("body");
|
||||||
|
var gView = document.getElementById("view");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* First, lock the wheel scrolling target to "view" at first step.
|
||||||
|
* Next, scroll back to top most of the "view" at second step.
|
||||||
|
* Finally, scroll back again at third step. This fails to scroll the "view",
|
||||||
|
* then, |onMouseScrollFailed| event should be fired. And at that time, we
|
||||||
|
* can remove the "view". So, in post processing of the event firere, the
|
||||||
|
* "view" should not be referred.
|
||||||
|
*
|
||||||
|
* For suppressing random test failure, all tests will be retried if we handle
|
||||||
|
* unexpected timeout event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var gTests = [
|
||||||
|
{ scrollToForward: true, shouldScroll: true },
|
||||||
|
{ scrollToForward: false, shouldScroll: true },
|
||||||
|
{ scrollToForward: false, shouldScroll: false }
|
||||||
|
];
|
||||||
|
var gCurrentTestIndex = -1;
|
||||||
|
var gIgnoreScrollEvent = true;
|
||||||
|
|
||||||
|
var gPrefSvc = Components.classes["@mozilla.org/preferences-service;1"].
|
||||||
|
getService(Components.interfaces.nsIPrefBranch2);
|
||||||
|
const kPrefNameTimeout = "mousewheel.transaction.timeout";
|
||||||
|
const kDefaultTimeout = gPrefSvc.getIntPref(kPrefNameTimeout);
|
||||||
|
|
||||||
|
var gTimeout = kDefaultTimeout;
|
||||||
|
|
||||||
|
gBody.addEventListener("MozMouseScrollFailed", onMouseScrollFailed, false);
|
||||||
|
gBody.addEventListener("MozMouseScrollTransactionTimeout",
|
||||||
|
onTransactionTimeout, false);
|
||||||
|
|
||||||
|
function setTimeoutPrefs(aTimeout)
|
||||||
|
{
|
||||||
|
gPrefSvc.setIntPref(kPrefNameTimeout, aTimeout);
|
||||||
|
gTimeout = aTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetTimeoutPrefs()
|
||||||
|
{
|
||||||
|
if (gTimeout == kDefaultTimeout)
|
||||||
|
return;
|
||||||
|
setTimeoutPrefs(kDefaultTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
function growUpTimeoutPrefs()
|
||||||
|
{
|
||||||
|
if (gTimeout != kDefaultTimeout)
|
||||||
|
return;
|
||||||
|
setTimeoutPrefs(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onload()
|
||||||
|
{
|
||||||
|
disableNonTestMouseEvents(true);
|
||||||
|
setTimeout(runNextTest, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onunload()
|
||||||
|
{
|
||||||
|
resetTimeoutPrefs();
|
||||||
|
disableNonTestMouseEvents(false);
|
||||||
|
window.opener.wrappedJSObject.SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish()
|
||||||
|
{
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// testing code
|
||||||
|
|
||||||
|
var gTimer;
|
||||||
|
function clearTimer()
|
||||||
|
{
|
||||||
|
clearTimeout(gTimer);
|
||||||
|
gTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runNextTest()
|
||||||
|
{
|
||||||
|
clearTimer();
|
||||||
|
if (++gCurrentTestIndex >= gTests.length) {
|
||||||
|
ok(true, "didn't crash, succeeded");
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fireWheelScrollEvent(gTests[gCurrentTestIndex].scrollToForward);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gRetryCount = 5;
|
||||||
|
function retryAllTests()
|
||||||
|
{
|
||||||
|
clearTimer();
|
||||||
|
if (--gRetryCount >= 0) {
|
||||||
|
gView.scrollTop = 0;
|
||||||
|
gView.scrollLeft = 0;
|
||||||
|
gCurrentTestIndex = -1;
|
||||||
|
growUpTimeoutPrefs();
|
||||||
|
ok(true, "WARNING: retry current test-list...");
|
||||||
|
gTimer = setTimeout(runNextTest, 0);
|
||||||
|
} else {
|
||||||
|
ok(false, "Failed by unexpected timeout");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fireWheelScrollEvent(aForward)
|
||||||
|
{
|
||||||
|
gIgnoreScrollEvent = false;
|
||||||
|
var event = { axis: "vertical", delta: aForward ? 4 : -4,
|
||||||
|
type: "DOMMouseScroll" };
|
||||||
|
synthesizeMouseScroll(gView, 5, 5, event, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScrollView(aEvent)
|
||||||
|
{
|
||||||
|
if (gIgnoreScrollEvent)
|
||||||
|
return;
|
||||||
|
gIgnoreScrollEvent = true;
|
||||||
|
clearTimer();
|
||||||
|
ok(gTests[gCurrentTestIndex].shouldScroll, "The view is scrolled");
|
||||||
|
gTimer = setTimeout(runNextTest, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseScrollFailed(aEvent)
|
||||||
|
{
|
||||||
|
clearTimer();
|
||||||
|
gIgnoreScrollEvent = true;
|
||||||
|
ok(!gTests[gCurrentTestIndex].shouldScroll, "The view is not scrolled");
|
||||||
|
if (!gTests[gCurrentTestIndex].shouldScroll)
|
||||||
|
gBody.removeChild(gView);
|
||||||
|
runNextTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTransactionTimeout(aEvent)
|
||||||
|
{
|
||||||
|
if (!gTimer)
|
||||||
|
return;
|
||||||
|
gIgnoreScrollEvent = true;
|
||||||
|
retryAllTests();
|
||||||
|
}
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</window>
|
Loading…
Reference in New Issue
Block a user