зеркало из https://github.com/mozilla/gecko-dev.git
Bug 589696 - Implement formnovalidate attribute for submit controls. r=smaug a2.0=blocking
This commit is contained in:
Родитель
4a7c360189
Коммит
c29116a8fa
|
@ -393,6 +393,7 @@ GK_ATOM(format, "format")
|
|||
GK_ATOM(formatNumber, "format-number")
|
||||
GK_ATOM(formenctype, "formenctype")
|
||||
GK_ATOM(formmethod, "formmethod")
|
||||
GK_ATOM(formnovalidate, "formnovalidate")
|
||||
GK_ATOM(formtarget, "formtarget")
|
||||
GK_ATOM(frame, "frame")
|
||||
GK_ATOM(frameborder, "frameborder")
|
||||
|
|
|
@ -218,6 +218,7 @@ NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, FormEnctype, formenctype,
|
|||
kFormDefaultEnctype->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, FormMethod, formmethod,
|
||||
kFormDefaultMethod->tag)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLButtonElement, FormNoValidate, formnovalidate)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, FormTarget, formtarget)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Name, name)
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLButtonElement, TabIndex, tabindex, 0)
|
||||
|
@ -508,6 +509,9 @@ nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
|||
// event is not handled if the window is being destroyed.
|
||||
if (presShell && (event.message != NS_FORM_SUBMIT ||
|
||||
mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate) ||
|
||||
// We know the element is a submit control, if this check is moved,
|
||||
// make sure formnovalidate is used only if it's a submit control.
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::formnovalidate) ||
|
||||
mForm->CheckValidFormSubmission())) {
|
||||
// TODO: removing this code and have the submit event sent by the form
|
||||
// see bug 592124.
|
||||
|
|
|
@ -973,6 +973,7 @@ NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, FormEnctype, formenctype,
|
|||
kFormDefaultEnctype->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, FormMethod, formmethod,
|
||||
kFormDefaultMethod->tag)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, FormNoValidate, formnovalidate)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLInputElement, FormTarget, formtarget)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Multiple, multiple)
|
||||
NS_IMPL_NON_NEGATIVE_INT_ATTR(nsHTMLInputElement, MaxLength, maxlength)
|
||||
|
@ -2442,6 +2443,9 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
|||
// form, see bug 592124.
|
||||
if (presShell && (event.message != NS_FORM_SUBMIT ||
|
||||
mForm->HasAttr(kNameSpaceID_None, nsGkAtoms::novalidate) ||
|
||||
// We know the element is a submit control, if this check is moved,
|
||||
// make sure formnovalidate is used only if it's a submit control.
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::formnovalidate) ||
|
||||
mForm->CheckValidFormSubmission())) {
|
||||
// Hold a strong ref while dispatching
|
||||
nsRefPtr<nsHTMLFormElement> form(mForm);
|
||||
|
|
|
@ -224,6 +224,7 @@ _TEST_FILES = \
|
|||
test_bug557628-1.html \
|
||||
test_bug557628-2.html \
|
||||
test_bug592802.html \
|
||||
test_bug589696.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=589696
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 589696</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>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=589696">Mozilla Bug 589696</a>
|
||||
<p id="display"></p>
|
||||
<iframe style='width:50px; height: 50px;' name='t'></iframe>
|
||||
<div id="content">
|
||||
<!-- Next forms should not submit because formnovalidate isn't set on the
|
||||
element used for the submission. -->
|
||||
<form target='t' action='data:text/html,'>
|
||||
<input id='av' required>
|
||||
<input type='submit' formnovalidate>
|
||||
<input id='a' type='submit'>
|
||||
</form>
|
||||
<form target='t' action='data:text/html,'>
|
||||
<input id='bv' type='checkbox' required>
|
||||
<button type='submit' formnovalidate></button>
|
||||
<button id='b' type='submit'></button>
|
||||
</form>
|
||||
<!-- Next form should not submit because formnovalidate only applies for
|
||||
submit controls. -->
|
||||
<form target='t' action='data:text/html,'>
|
||||
<input id='c' required formnovalidate>
|
||||
</form>
|
||||
<!--- Next forms should submit without any validation check. -->
|
||||
<form target='t' action='data:text/html,'>
|
||||
<input id='dv' required>
|
||||
<input id='d' type='submit' formnovalidate>
|
||||
</form>
|
||||
<form target='t' action='data:text/html,'>
|
||||
<input id='ev' type='checkbox' required>
|
||||
<button id='e' type='submit' formnovalidate></button>
|
||||
</form>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 589696 **/
|
||||
|
||||
function checkFormNoValidateAttribute(aElementName)
|
||||
{
|
||||
var element = document.createElement(aElementName);
|
||||
|
||||
ok("formNoValidate" in element, "formNoValidate should be a " + aElementName +
|
||||
" element IDL attribute");
|
||||
|
||||
ok(!element.formNoValidate, "formnovalidate attribute should be disabled");
|
||||
is(element.getAttribute('formnovalidate'), null,
|
||||
"formnovalidate attribute should be disabled");
|
||||
|
||||
element.formNoValidate = true;
|
||||
ok(element.formNoValidate, "formnovalidate attribute should be enabled");
|
||||
isnot(element.getAttribute('formnovalidate'), null,
|
||||
"formnovalidate attribute should be enabled");
|
||||
|
||||
element.removeAttribute('formnovalidate');
|
||||
element.setAttribute('formnovalidate', '');
|
||||
ok(element.formNoValidate, "formnovalidate attribute should be enabled");
|
||||
isnot(element.getAttribute('formnovalidate'), null,
|
||||
"formnovalidate attribute should be enabled");
|
||||
|
||||
element.removeAttribute('formnovalidate');
|
||||
ok(!element.formNoValidate, "formnovalidate attribute should be disabled");
|
||||
is(element.getAttribute('formnovalidate'), null,
|
||||
"formnovalidate attribute should be disabled");
|
||||
}
|
||||
|
||||
checkFormNoValidateAttribute('input');
|
||||
checkFormNoValidateAttribute('button');
|
||||
|
||||
/**
|
||||
* formnovalidate should prevent form validation if set on the submit control
|
||||
* used to submit the form.
|
||||
*
|
||||
* NOTE: if there is no invalidformsubmit observer, the form submission will
|
||||
* never be blocked and this test might be a false-positive but that should not
|
||||
* be a problem.
|
||||
*/
|
||||
document.getElementById('av').addEventListener("invalid", function(aEvent) {
|
||||
aEvent.target.removeAttribute("invalid", arguments.callee, false);
|
||||
ok(true, "formnovalidate should not apply on if not set on the submit " +
|
||||
"control used for the submission");
|
||||
document.getElementById('b').click();
|
||||
}, false);
|
||||
|
||||
document.getElementById('bv').addEventListener("invalid", function(aEvent) {
|
||||
aEvent.target.removeAttribute("invalid", arguments.callee, false);
|
||||
ok(true, "formnovalidate should not apply on if not set on the submit " +
|
||||
"control used for the submission");
|
||||
var c = document.getElementById('c');
|
||||
c.focus(); synthesizeKey("VK_RETURN", {type: "keypress"});
|
||||
}, false);
|
||||
|
||||
document.getElementById('c').addEventListener("invalid", function(aEvent) {
|
||||
aEvent.target.removeAttribute("invalid", arguments.callee, false);
|
||||
ok(true, "formnovalidate should only apply on submit controls");
|
||||
document.getElementById('d').click();
|
||||
}, false);
|
||||
|
||||
document.forms[3].addEventListener("submit", function(aEvent) {
|
||||
aEvent.target.removeAttribute("submit", arguments.callee, false);
|
||||
ok(true, "formnovalidate applies if set on the submit control used for the submission");
|
||||
document.getElementById('e').click();
|
||||
}, false);
|
||||
|
||||
document.forms[4].addEventListener("submit", function(aEvent) {
|
||||
aEvent.target.removeAttribute("submit", arguments.callee, false);
|
||||
ok(true, "formnovalidate applies if set on the submit control used for the submission");
|
||||
SimpleTest.executeSoon(SimpleTest.finish);
|
||||
}, false);
|
||||
|
||||
/**
|
||||
* We have to be sure invalid events behave as expected.
|
||||
* They should be sent before the submit event so we can just create a test
|
||||
* failure if we got one when unexpected. All of them should be catched if sent.
|
||||
* At worst, we got random green which isn't harmful.
|
||||
* If expected, they will be part of the chain reaction.
|
||||
*/
|
||||
function unexpectedInvalid(aEvent)
|
||||
{
|
||||
aEvent.target.removeAttribute("invalid", unexpectedInvalid, false);
|
||||
ok(false, "invalid event should not be sent");
|
||||
}
|
||||
|
||||
document.getElementById('dv').addEventListener("invalid", unexpectedInvalid, false);
|
||||
document.getElementById('ev').addEventListener("invalid", unexpectedInvalid, false);
|
||||
|
||||
/**
|
||||
* Some submission have to be canceled. In that case, the submit events should
|
||||
* not be sent.
|
||||
* Same behavior as unexpected invalid events.
|
||||
*/
|
||||
function unexpectedSubmit(aEvent)
|
||||
{
|
||||
aEvent.target.removeAttribute("submit", unexpectedSubmit, false);
|
||||
ok(false, "submit event should not be sent");
|
||||
}
|
||||
|
||||
document.forms[0].addEventListener("submit", unexpectedSubmit, false);
|
||||
document.forms[1].addEventListener("submit", unexpectedSubmit, false);
|
||||
document.forms[2].addEventListener("submit", unexpectedSubmit, false);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// This is going to call all the tests (with a chain reaction).
|
||||
SimpleTest.waitForFocus(function() {
|
||||
document.getElementById('a').click();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
interface nsIDOMValidityState;
|
||||
|
||||
[scriptable, uuid(d76a7412-f70b-43fe-becb-d30dac13cc7b)]
|
||||
[scriptable, uuid(bcae78a1-9f9b-46bf-abb5-a3fe410d97ae)]
|
||||
interface nsIDOMHTMLButtonElement : nsIDOMHTMLElement
|
||||
{
|
||||
attribute boolean autofocus;
|
||||
|
@ -58,6 +58,7 @@ interface nsIDOMHTMLButtonElement : nsIDOMHTMLElement
|
|||
attribute DOMString formAction;
|
||||
attribute DOMString formEnctype;
|
||||
attribute DOMString formMethod;
|
||||
attribute boolean formNoValidate;
|
||||
attribute DOMString formTarget;
|
||||
|
||||
attribute DOMString name;
|
||||
|
|
|
@ -51,7 +51,7 @@ interface nsIDOMValidityState;
|
|||
* http://www.w3.org/TR/DOM-Level-2-HTML/
|
||||
*/
|
||||
|
||||
[scriptable, uuid(2f79a4be-8143-45fc-ac42-67cd16b2322f)]
|
||||
[scriptable, uuid(0805059d-f18f-4095-ae6b-0bf6df80b7b8)]
|
||||
interface nsIDOMHTMLInputElement : nsIDOMHTMLElement
|
||||
{
|
||||
attribute DOMString accept;
|
||||
|
@ -66,6 +66,7 @@ interface nsIDOMHTMLInputElement : nsIDOMHTMLElement
|
|||
attribute DOMString formAction;
|
||||
attribute DOMString formEnctype;
|
||||
attribute DOMString formMethod;
|
||||
attribute boolean formNoValidate;
|
||||
attribute DOMString formTarget;
|
||||
|
||||
readonly attribute nsIDOMFileList files;
|
||||
|
|
Загрузка…
Ссылка в новой задаче