зеркало из https://github.com/mozilla/pjs.git
Bug 428135, form submission event shouldn't bubble to parent forms, r=jst,sr=sicking,a=beltzner
This commit is contained in:
Родитель
a41cf08e0f
Коммит
2d1e2b5af5
|
@ -49,10 +49,10 @@ class nsIEventListenerManager;
|
|||
class nsIDOMEventListener;
|
||||
class nsIDOMEventGroup;
|
||||
|
||||
// 360fa72e-c709-42cc-9285-1f755ec90376
|
||||
// f35ffc3b-c8c0-43fd-b0b0-f339e95f574a
|
||||
#define NS_PIDOMEVENTTARGET_IID \
|
||||
{ 0x44a6597b, 0x9fc3, 0x4a8d, \
|
||||
{ 0xb7, 0xa4, 0xd9, 0x00, 0x9a, 0xbf, 0x9d, 0x15 } }
|
||||
{ 0xf35ffc3b, 0xc8c0, 0x43fd, \
|
||||
{ 0xb0, 0xb0, 0xf3, 0x39, 0xe9, 0x5f, 0x57, 0x4a } }
|
||||
|
||||
class nsPIDOMEventTarget : public nsISupports
|
||||
{
|
||||
|
@ -92,6 +92,14 @@ public:
|
|||
*/
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) = 0;
|
||||
|
||||
/**
|
||||
* Called just before possible event handlers on this object will be called.
|
||||
*/
|
||||
virtual nsresult WillHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the bubble phase of the system event group.
|
||||
* The default handling of the event should happen here.
|
||||
|
|
|
@ -194,6 +194,10 @@ nsresult
|
|||
nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor& aVisitor,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
mTarget->WillHandleEvent(aVisitor);
|
||||
if (aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mManager) {
|
||||
mTarget->GetListenerManager(PR_FALSE, getter_AddRefs(mManager));
|
||||
}
|
||||
|
|
|
@ -211,6 +211,7 @@ public:
|
|||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult WillHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
@ -832,6 +833,21 @@ nsHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::WillHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
// If this is the bubble stage and there is a nested form below us which
|
||||
// received a submit event we do *not* want to handle the submit event
|
||||
// for this form too.
|
||||
if ((aVisitor.mEvent->message == NS_FORM_SUBMIT ||
|
||||
aVisitor.mEvent->message == NS_FORM_RESET) &&
|
||||
aVisitor.mEvent->flags & NS_EVENT_FLAG_BUBBLE &&
|
||||
aVisitor.mEvent->originalTarget != static_cast<nsIContent*>(this)) {
|
||||
aVisitor.mEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
|
|
@ -109,6 +109,7 @@ _TEST_FILES = test_bug589.html \
|
|||
test_bug408231.html \
|
||||
test_bug417760.html \
|
||||
file_bug417760.png \
|
||||
test_bug428135.xhtml \
|
||||
test_bug406596.html \
|
||||
test_bug421640.html \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=428135
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 428135</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428135">Mozilla Bug 428135</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 428135 **/
|
||||
|
||||
var expectedCurrentTargets = new Array();
|
||||
|
||||
function d(el, ename) {
|
||||
var e = document.createEvent("Events");
|
||||
e.initEvent(ename, true, true);
|
||||
el.dispatchEvent(e);
|
||||
}
|
||||
|
||||
function testListener(e) {
|
||||
e.preventDefault();
|
||||
var expected = expectedCurrentTargets.shift();
|
||||
ok(expected == e.currentTarget,
|
||||
"Unexpected current target [" + e.currentTarget + "], event=" + e.type +
|
||||
", phase=" + e.eventPhase + ", target should have been " + expected);
|
||||
}
|
||||
|
||||
function getAndAddListeners(elname) {
|
||||
var el = document;
|
||||
if (elname) {
|
||||
el = document.getElementById(elname);
|
||||
}
|
||||
el.addEventListener("submit", testListener, true);
|
||||
el.addEventListener("submit", testListener, false);
|
||||
el.addEventListener("reset", testListener, true);
|
||||
el.addEventListener("reset", testListener, false);
|
||||
el.addEventListener("fooEvent", testListener, true);
|
||||
el.addEventListener("fooEvent", testListener, false);
|
||||
return el;
|
||||
}
|
||||
|
||||
function testSubmitResetEvents() {
|
||||
getAndAddListeners(null);
|
||||
var outerForm = getAndAddListeners("outerForm");
|
||||
var outerSubmit = getAndAddListeners("outerSubmit");
|
||||
var outerReset = getAndAddListeners("outerReset");
|
||||
var outerSubmitDispatcher = getAndAddListeners("outerSubmitDispatcher");
|
||||
var outerResetDispatcher = getAndAddListeners("outerResetDispatcher");
|
||||
var outerChild = getAndAddListeners("outerChild");
|
||||
var innerForm = getAndAddListeners("innerForm");
|
||||
var innerSubmit = getAndAddListeners("innerSubmit");
|
||||
var innerReset = getAndAddListeners("innerReset");
|
||||
var innerSubmitDispatcher = getAndAddListeners("innerSubmitDispatcher");
|
||||
var innerResetDispatcher = getAndAddListeners("innerResetDispatcher");
|
||||
|
||||
expectedCurrentTargets = new Array(document, outerForm, outerForm, document);
|
||||
outerSubmit.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(1) expectedCurrentTargets isn't empty!");
|
||||
|
||||
expectedCurrentTargets = new Array(document, outerForm, outerForm, document);
|
||||
outerReset.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(2) expectedCurrentTargets isn't empty!");
|
||||
|
||||
// Because of bug 428135, submit shouldn't propagate
|
||||
// back to outerForm and document!
|
||||
expectedCurrentTargets =
|
||||
new Array(document, outerForm, outerSubmitDispatcher, outerSubmitDispatcher);
|
||||
outerSubmitDispatcher.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(3) expectedCurrentTargets isn't empty!");
|
||||
|
||||
// Because of bug 428135, reset shouldn't propagate
|
||||
// back to outerForm and document!
|
||||
expectedCurrentTargets =
|
||||
new Array(document, outerForm, outerResetDispatcher, outerResetDispatcher);
|
||||
outerResetDispatcher.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(4) expectedCurrentTargets isn't empty!");
|
||||
|
||||
// Because of bug 428135, submit shouldn't propagate
|
||||
// back to outerForm and document!
|
||||
expectedCurrentTargets =
|
||||
new Array(document, outerForm, outerChild, innerForm, innerForm, outerChild);
|
||||
innerSubmit.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(5) expectedCurrentTargets isn't empty!");
|
||||
|
||||
// Because of bug 428135, reset shouldn't propagate
|
||||
// back to outerForm and document!
|
||||
expectedCurrentTargets =
|
||||
new Array(document, outerForm, outerChild, innerForm, innerForm, outerChild);
|
||||
innerReset.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(6) expectedCurrentTargets isn't empty!");
|
||||
|
||||
// Because of bug 428135, submit shouldn't propagate
|
||||
// back to inner/outerForm or document!
|
||||
expectedCurrentTargets =
|
||||
new Array(document, outerForm, outerChild, innerForm, innerSubmitDispatcher,
|
||||
innerSubmitDispatcher);
|
||||
innerSubmitDispatcher.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(7) expectedCurrentTargets isn't empty!");
|
||||
|
||||
// Because of bug 428135, reset shouldn't propagate
|
||||
// back to inner/outerForm or document!
|
||||
expectedCurrentTargets =
|
||||
new Array(document, outerForm, outerChild, innerForm, innerResetDispatcher,
|
||||
innerResetDispatcher);
|
||||
innerResetDispatcher.click();
|
||||
ok(expectedCurrentTargets.length == 0,
|
||||
"(8) expectedCurrentTargets isn't empty!");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(testSubmitResetEvents);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
<form id="outerForm">
|
||||
<input type="submit" value="outer" id="outerSubmit"/>
|
||||
<input type="reset" value="reset outer" id="outerReset"/>
|
||||
<input type="button" value="dispatch submit" onclick="d(this, 'submit')"
|
||||
id="outerSubmitDispatcher"/>
|
||||
<input type="button" value="dispatch reset" onclick="d(this, 'reset')"
|
||||
id="outerResetDispatcher"/>
|
||||
<div id="outerChild">
|
||||
<form id="innerForm">
|
||||
<input type="submit" value="inner" id="innerSubmit"/>
|
||||
<input type="reset" value="reset inner" id="innerReset"/>
|
||||
<input type="button" value="dispatch submit" onclick="d(this, 'submit')"
|
||||
id="innerSubmitDispatcher"/>
|
||||
<input type="button" value="dispatch reset" onclick="d(this, 'reset')"
|
||||
id="innerResetDispatcher"/>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
Загрузка…
Ссылка в новой задаче