Commit ced38641 authored by tkent@chromium.org's avatar tkent@chromium.org

HTMLFormElement::checkValidity() returns incorrect result if 'invalid' events are canceled.

https://bugs.webkit.org/show_bug.cgi?id=52565

Reviewed by Dimitri Glazkov.

Source/WebCore:

* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::validateInteractively):
  Check checkInvalidControlsAndCollectUnhandled() result instead of
  checking emptiness of unhandled invalid controls list.
(WebCore::HTMLFormElement::checkValidity): ditto.
(WebCore::HTMLFormElement::checkInvalidControlsAndCollectUnhandled):
  Renamed from collectUnhandledInvalidControls().
  Returns true if there is any invalid control regardless of event canceling.
* html/HTMLFormElement.h: Rename collectUnhandledInvalidControls() to
  checkInvalidControlsAndCollectUnhandled().

LayoutTests:

Fix tests and results for the behavior change.

* fast/forms/checkValidity-cancel-expected.txt:
* fast/forms/checkValidity-handler-updates-dom-expected.txt:
* fast/forms/interactive-validation-cancel-expected.txt:
* fast/forms/interactive-validation-cancel.html:
* fast/forms/script-tests/checkValidity-cancel.js:
* fast/forms/script-tests/checkValidity-handler-updates-dom.js:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76663 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1b27cba5
2011-01-25 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
HTMLFormElement::checkValidity() returns incorrect result if 'invalid' events are canceled.
https://bugs.webkit.org/show_bug.cgi?id=52565
Fix tests and results for the behavior change.
* fast/forms/checkValidity-cancel-expected.txt:
* fast/forms/checkValidity-handler-updates-dom-expected.txt:
* fast/forms/interactive-validation-cancel-expected.txt:
* fast/forms/interactive-validation-cancel.html:
* fast/forms/script-tests/checkValidity-cancel.js:
* fast/forms/script-tests/checkValidity-handler-updates-dom.js:
2011-01-25 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
......
......@@ -9,7 +9,7 @@ PASS invalidFired = false; !form.checkValidity() && invalidFired is true
"invalid" event is canceled.
PASS input.addEventListener("invalid", cancelListener, false); !input.checkValidity() && invalidFired is true
PASS invalidFired = false; form.checkValidity() && invalidFired is true
PASS invalidFired = false; !form.checkValidity() && invalidFired is true
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
The target form is removed.
PASS document.getElementById("f1").checkValidity() is true
PASS document.getElementById("f1").checkValidity() is false
A control to be checked is removed.
PASS document.getElementById("f1").checkValidity() is false
......
Test if the form is submitted when an "invalid" event for a control is canceled.
Test if the form is not submitted even if an "invalid" event for a control is canceled.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS The form should be submitted.
PASS location.search.indexOf("i0=") != -1 is true
PASS The form was not submitted.
TEST COMPLETE
......@@ -13,7 +13,7 @@
<input type=submit id="s">
</form>
<script>
description('Test if the form is submitted when an "invalid" event for a control is canceled.');
description('Test if the form is not submitted even if an "invalid" event for a control is canceled.');
function cancel(event) {
event.preventDefault();
......@@ -22,17 +22,17 @@ function cancel(event) {
function startOrVerify() {
var query = window.location.search;
if (query.indexOf('submitted=true') != -1) {
testPassed('The form should be submitted.');
testFailed('The form should not be submitted.');
shouldBeTrue('location.search.indexOf("i0=") != -1');
debug('TEST COMPLETE');
if (window.layoutTestController)
layoutTestController.notifyDone();
} else {
document.getElementById('i0').addEventListener('invalid', cancel, false);
// HTMLFormElement::submit() skips validation. Use the submit button.
document.getElementById('s').click();
testFailed('The form was not submitted.');
testPassed('The form was not submitted.');
}
debug('TEST COMPLETE');
if (window.layoutTestController)
layoutTestController.notifyDone();
}
if (window.layoutTestController)
......
......@@ -26,7 +26,7 @@ cancelListener.handleEvent = function(event) {
};
// Even if 'invalid' is canceled, the input.checkValidity() result is still false.
shouldBeTrue('input.addEventListener("invalid", cancelListener, false); !input.checkValidity() && invalidFired');
// form.checkValidity() should be true.
shouldBeTrue('invalidFired = false; form.checkValidity() && invalidFired');
// form.checkValidity() also should be false.
shouldBeTrue('invalidFired = false; !form.checkValidity() && invalidFired');
var successfullyParsed = true;
......@@ -10,9 +10,9 @@ var handler = function(event) {
parent.innerHTML = '';
};
document.getElementById('i').addEventListener('invalid', handler, false);
// The control is invalid, but it is not listed in 'unhandled invalid controls'
// because it is not in any documents.
shouldBeTrue('document.getElementById("f1").checkValidity()');
// The specificiation doesn't define the behavior in this case.
// It's ok if WebKit doesn't crash.
shouldBeFalse('document.getElementById("f1").checkValidity()');
// ----------------------------------------------------------------
debug('');
......
2011-01-25 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
HTMLFormElement::checkValidity() returns incorrect result if 'invalid' events are canceled.
https://bugs.webkit.org/show_bug.cgi?id=52565
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::validateInteractively):
Check checkInvalidControlsAndCollectUnhandled() result instead of
checking emptiness of unhandled invalid controls list.
(WebCore::HTMLFormElement::checkValidity): ditto.
(WebCore::HTMLFormElement::checkInvalidControlsAndCollectUnhandled):
Renamed from collectUnhandledInvalidControls().
Returns true if there is any invalid control regardless of event canceling.
* html/HTMLFormElement.h: Rename collectUnhandledInvalidControls() to
checkInvalidControlsAndCollectUnhandled().
2011-01-25 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
......@@ -221,8 +221,7 @@ bool HTMLFormElement::validateInteractively(Event* event)
}
Vector<RefPtr<FormAssociatedElement> > unhandledInvalidControls;
collectUnhandledInvalidControls(unhandledInvalidControls);
if (unhandledInvalidControls.isEmpty())
if (!checkInvalidControlsAndCollectUnhandled(unhandledInvalidControls))
return true;
// If the form has invalid controls, abort submission.
......@@ -586,8 +585,7 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const
bool HTMLFormElement::checkValidity()
{
Vector<RefPtr<FormAssociatedElement> > controls;
collectUnhandledInvalidControls(controls);
return controls.isEmpty();
return !checkInvalidControlsAndCollectUnhandled(controls);
}
void HTMLFormElement::broadcastFormEvent(const AtomicString& eventName)
......@@ -623,7 +621,7 @@ void HTMLFormElement::dispatchFormChange()
broadcastFormEvent(eventNames().formchangeEvent);
}
void HTMLFormElement::collectUnhandledInvalidControls(Vector<RefPtr<FormAssociatedElement> >& unhandledInvalidControls)
bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >& unhandledInvalidControls)
{
RefPtr<HTMLFormElement> protector(this);
// Copy m_associatedElements because event handlers called from
......@@ -632,10 +630,15 @@ void HTMLFormElement::collectUnhandledInvalidControls(Vector<RefPtr<FormAssociat
elements.reserveCapacity(m_associatedElements.size());
for (unsigned i = 0; i < m_associatedElements.size(); ++i)
elements.append(m_associatedElements[i]);
bool hasInvalidControls = false;
for (unsigned i = 0; i < elements.size(); ++i) {
if (elements[i]->form() == this && elements[i]->isFormControlElement())
static_cast<HTMLFormControlElement*>(elements[i].get())->checkValidity(&unhandledInvalidControls);
if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(elements[i].get());
if (!control->checkValidity(&unhandledInvalidControls) && control->form() == this)
hasInvalidControls = true;
}
}
return hasInvalidControls;
}
HTMLFormControlElement* HTMLFormElement::elementForAlias(const AtomicString& alias)
......
......@@ -144,8 +144,9 @@ private:
bool validateInteractively(Event*);
// Validates each of the controls, and stores controls of which 'invalid'
// event was not canceled to the specified vector.
void collectUnhandledInvalidControls(Vector<RefPtr<FormAssociatedElement> >&);
// event was not canceled to the specified vector. Returns true if there
// are any invalid controls in this form.
bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >&);
void broadcastFormEvent(const AtomicString&);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment