Bug 561634 - Implement constraint validation API for form element. r=smaug sr=sicking a2.0=blocking

This commit is contained in:
Mounir Lamouri 2010-08-21 20:51:38 +02:00
Родитель 82d46303be
Коммит 00b52d9848
17 изменённых файлов: 324 добавлений и 75 удалений

Просмотреть файл

@ -101,8 +101,8 @@ PR_STATIC_ASSERT((PRUint32)eButtonElementTypesMax < (PRUint32)NS_FORM_INPUT_ELEM
PR_STATIC_ASSERT((PRUint32)eInputElementTypesMax < 1<<8);
#define NS_IFORMCONTROL_IID \
{ 0xc2f7723a, 0x106a, 0x47ef, \
{ 0xa9, 0xff, 0x4b, 0x4f, 0x73, 0x47, 0xe7, 0xa6 } }
{ 0x218eb090, 0x32eb, 0x4e2a, \
{ 0x96, 0x42, 0xcd, 0xcd, 0x33, 0xae, 0xdb, 0x95 } }
/**
* Interface which all form controls (e.g. buttons, checkboxes, text,
@ -207,6 +207,12 @@ public:
* @return Whether this is a labelable form control.
*/
virtual PRBool IsLabelableControl() const = 0;
/**
* Returns true if this is a submittable form control.
* @return Whether this is a submittable form control.
*/
virtual PRBool IsSubmittableControl() const = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFormControl, NS_IFORMCONTROL_IID)

Просмотреть файл

@ -69,20 +69,11 @@ nsConstraintValidation::GetValidity(nsIDOMValidityState** aValidity)
}
nsresult
nsConstraintValidation::GetWillValidate(PRBool* aWillValidate,
nsGenericHTMLFormElement* aElement)
{
*aWillValidate = IsCandidateForConstraintValidation(aElement);
return NS_OK;
}
nsresult
nsConstraintValidation::GetValidationMessage(nsAString& aValidationMessage,
nsGenericHTMLFormElement* aElement)
nsConstraintValidation::GetValidationMessage(nsAString& aValidationMessage)
{
aValidationMessage.Truncate();
if (IsCandidateForConstraintValidation(aElement) && !IsValid()) {
if (IsCandidateForConstraintValidation() && !IsValid()) {
if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
aValidationMessage.Assign(mCustomValidity);
} else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) {
@ -107,32 +98,32 @@ nsConstraintValidation::GetValidationMessage(nsAString& aValidationMessage,
}
nsresult
nsConstraintValidation::CheckValidity(PRBool* aValidity,
nsGenericHTMLFormElement* aElement)
nsConstraintValidation::CheckValidity(PRBool* aValidity)
{
if (!IsCandidateForConstraintValidation(aElement) || IsValid()) {
if (!IsCandidateForConstraintValidation() || IsValid()) {
*aValidity = PR_TRUE;
return NS_OK;
}
*aValidity = PR_FALSE;
return nsContentUtils::DispatchTrustedEvent(aElement->GetOwnerDoc(),
static_cast<nsIContent*>(aElement),
nsCOMPtr<nsIContent> content = do_QueryInterface(this);
NS_ASSERTION(content, "This class should be inherited by HTML elements only!");
return nsContentUtils::DispatchTrustedEvent(content->GetOwnerDoc(), content,
NS_LITERAL_STRING("invalid"),
PR_FALSE, PR_TRUE);
}
nsresult
void
nsConstraintValidation::SetCustomValidity(const nsAString& aError)
{
mCustomValidity.Assign(aError);
SetValidityState(VALIDITY_STATE_CUSTOM_ERROR, !mCustomValidity.IsEmpty());
return NS_OK;
}
PRBool
nsConstraintValidation::IsCandidateForConstraintValidation(const nsGenericHTMLFormElement* const aElement) const
nsConstraintValidation::IsCandidateForConstraintValidation() const
{
/**
* An element is never candidate for constraint validation if:
@ -142,13 +133,17 @@ nsConstraintValidation::IsCandidateForConstraintValidation(const nsGenericHTMLFo
* |IsBarredFromConstraintValidation| function.
*/
// At the moment, every elements which can be candidate for constraint
// validation can be disabled. However, using |CanBeDisabled| is future-proof.
if (aElement->CanBeDisabled() &&
aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
return PR_FALSE;
}
nsCOMPtr<nsIContent> content =
do_QueryInterface(const_cast<nsConstraintValidation*>(this));
NS_ASSERTION(content, "This class should be inherited by HTML elements only!");
return !IsBarredFromConstraintValidation();
// For the moment, all elements that are not barred from constraint validation
// accept the disabled attribute and elements that are always barred from
// constraint validation do not accept it (objects, fieldset, output).
// If one of these elements change and become not always barred from
// constraint validation or another element appear with constraint validation
// support and can't be disabled, this code will have to be changed.
return !content->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) &&
!IsBarredFromConstraintValidation();
}

Просмотреть файл

@ -38,6 +38,7 @@
#ifndef nsConstraintValidition_h___
#define nsConstraintValidition_h___
#include "nsISupports.h"
#include "nsAutoPtr.h"
#include "nsString.h"
@ -45,21 +46,31 @@ class nsDOMValidityState;
class nsIDOMValidityState;
class nsGenericHTMLFormElement;
#define NS_CONSTRAINTVALIDATION_IID \
{ 0xca3824dc, 0x4f5c, 0x4878, \
{ 0xa6, 0x8a, 0x95, 0x54, 0x5f, 0xfa, 0x4b, 0xf9 } }
/**
* This interface is used for form elements implementing the
* This class is used for form elements implementing the
* validity constraint API.
* See: http://dev.w3.org/html5/spec/forms.html#the-constraint-validation-api
*
* This class has to be inherited by all elements implementing the API.
* This class has to be used by all elements implementing the API.
*/
class nsConstraintValidation
class nsConstraintValidation : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CONSTRAINTVALIDATION_IID);
friend class nsDOMValidityState;
virtual ~nsConstraintValidation();
PRBool IsValid() const { return mValidityBitField == 0; }
PRBool IsCandidateForConstraintValidation() const;
protected:
enum ValidityStateType
@ -78,15 +89,9 @@ protected:
nsConstraintValidation();
nsresult GetValidity(nsIDOMValidityState** aValidity);
nsresult GetWillValidate(PRBool* aWillValidate,
nsGenericHTMLFormElement* aElement);
nsresult GetValidationMessage(nsAString& aValidationMessage,
nsGenericHTMLFormElement* aElement);
nsresult CheckValidity(PRBool* aValidity,
nsGenericHTMLFormElement* aElement);
nsresult SetCustomValidity(const nsAString& aError);
PRBool IsValid() const { return mValidityBitField == 0; }
nsresult GetValidationMessage(nsAString& aValidationMessage);
nsresult CheckValidity(PRBool* aValidity);
void SetCustomValidity(const nsAString& aError);
bool GetValidityState(ValidityStateType mState) const {
return mValidityBitField & mState;
@ -100,8 +105,6 @@ protected:
}
}
PRBool IsCandidateForConstraintValidation(const nsGenericHTMLFormElement* const aElement) const;
virtual PRBool IsBarredFromConstraintValidation() const { return PR_FALSE; }
virtual nsresult GetValidationMessage(nsAString& aValidationMessage,
@ -137,19 +140,21 @@ private:
return nsConstraintValidation::GetValidity(aValidity); \
} \
NS_IMETHOD GetWillValidate(PRBool* aWillValidate) { \
return nsConstraintValidation::GetWillValidate(aWillValidate, this); \
*aWillValidate = IsCandidateForConstraintValidation(); \
return NS_OK; \
} \
NS_IMETHOD GetValidationMessage(nsAString& aValidationMessage) { \
return nsConstraintValidation::GetValidationMessage(aValidationMessage, this); \
return nsConstraintValidation::GetValidationMessage(aValidationMessage); \
} \
NS_IMETHOD CheckValidity(PRBool* aValidity) { \
return nsConstraintValidation::CheckValidity(aValidity, this); \
return nsConstraintValidation::CheckValidity(aValidity); \
}
#define NS_FORWARD_NSCONSTRAINTVALIDATION \
NS_FORWARD_NSCONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY \
NS_IMETHOD SetCustomValidity(const nsAString& aError) { \
return nsConstraintValidation::SetCustomValidity(aError); \
nsConstraintValidation::SetCustomValidity(aError); \
return NS_OK; \
}
@ -159,21 +164,24 @@ private:
return nsConstraintValidation::GetValidity(aValidity); \
} \
NS_IMETHODIMP _from::GetWillValidate(PRBool* aWillValidate) { \
return nsConstraintValidation::GetWillValidate(aWillValidate, this); \
*aWillValidate = IsCandidateForConstraintValidation(); \
return NS_OK; \
} \
NS_IMETHODIMP _from::GetValidationMessage(nsAString& aValidationMessage) { \
return nsConstraintValidation::GetValidationMessage(aValidationMessage, this); \
return nsConstraintValidation::GetValidationMessage(aValidationMessage); \
} \
NS_IMETHODIMP _from::CheckValidity(PRBool* aValidity) { \
return nsConstraintValidation::CheckValidity(aValidity, this); \
return nsConstraintValidation::CheckValidity(aValidity); \
}
#define NS_IMPL_NSCONSTRAINTVALIDATION(_from) \
NS_IMPL_NSCONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY(_from) \
NS_IMETHODIMP _from::SetCustomValidity(const nsAString& aError) { \
return nsConstraintValidation::SetCustomValidity(aError); \
nsConstraintValidation::SetCustomValidity(aError); \
return NS_OK; \
}
NS_DEFINE_STATIC_IID_ACCESSOR(nsConstraintValidation, NS_CONSTRAINTVALIDATION_IID)
#endif // nsConstraintValidation_h___

Просмотреть файл

@ -72,6 +72,7 @@ protected:
mConstraintValidation->GetValidityState(aState);
}
// Weak reference to owner which will call Disconnect() when being destroyed.
nsConstraintValidation* mConstraintValidation;
};

Просмотреть файл

@ -2727,6 +2727,18 @@ nsGenericHTMLFormElement::IsLabelableControl() const
type != NS_FORM_OBJECT;
}
PRBool
nsGenericHTMLFormElement::IsSubmittableControl() const
{
// TODO: keygen should be in that list, see bug 101019.
PRInt32 type = GetType();
return type == NS_FORM_OBJECT ||
type == NS_FORM_TEXTAREA ||
type == NS_FORM_SELECT ||
type & NS_FORM_BUTTON_ELEMENT ||
type & NS_FORM_INPUT_ELEMENT;
}
PRInt32
nsGenericHTMLFormElement::IntrinsicState() const
{

Просмотреть файл

@ -829,6 +829,8 @@ public:
PRBool IsLabelableControl() const;
PRBool IsSubmittableControl() const;
// nsIContent
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,

Просмотреть файл

@ -183,8 +183,9 @@ DOMCI_NODE_DATA(HTMLButtonElement, nsHTMLButtonElement)
// QueryInterface implementation for nsHTMLButtonElement
NS_INTERFACE_TABLE_HEAD(nsHTMLButtonElement)
NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLButtonElement,
nsIDOMHTMLButtonElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLButtonElement,
nsIDOMHTMLButtonElement,
nsConstraintValidation)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLButtonElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLButtonElement)
@ -663,7 +664,7 @@ nsHTMLButtonElement::IntrinsicState() const
{
PRInt32 state = nsGenericHTMLFormElement::IntrinsicState();
if (IsCandidateForConstraintValidation(this)) {
if (IsCandidateForConstraintValidation()) {
state |= IsValid() ? NS_EVENT_STATE_VALID : NS_EVENT_STATE_INVALID;
}
@ -675,7 +676,7 @@ nsHTMLButtonElement::IntrinsicState() const
NS_IMETHODIMP
nsHTMLButtonElement::SetCustomValidity(const nsAString& aError)
{
nsresult rv = nsConstraintValidation::SetCustomValidity(aError);
nsConstraintValidation::SetCustomValidity(aError);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
@ -683,7 +684,7 @@ nsHTMLButtonElement::SetCustomValidity(const nsAString& aError)
NS_EVENT_STATE_VALID);
}
return rv;
return NS_OK;
}
PRBool

Просмотреть файл

@ -102,8 +102,9 @@ DOMCI_NODE_DATA(HTMLFieldSetElement, nsHTMLFieldSetElement)
// QueryInterface implementation for nsHTMLFieldSetElement
NS_INTERFACE_TABLE_HEAD(nsHTMLFieldSetElement)
NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLFieldSetElement,
nsIDOMHTMLFieldSetElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLFieldSetElement,
nsIDOMHTMLFieldSetElement,
nsConstraintValidation)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLFieldSetElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLFieldSetElement)

Просмотреть файл

@ -79,6 +79,8 @@
#include "mozAutoDocUpdate.h"
#include "nsIHTMLCollection.h"
#include "nsConstraintValidation.h"
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
// nsHTMLFormElement
@ -405,6 +407,13 @@ nsHTMLFormElement::Reset()
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFormElement::CheckValidity(PRBool* retVal)
{
*retVal = CheckFormValidity();
return NS_OK;
}
PRBool
nsHTMLFormElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
@ -679,6 +688,16 @@ nsHTMLFormElement::DoSubmit(nsEvent* aEvent)
return NS_OK;
}
#ifdef DEBUG
if (!CheckFormValidity()) {
printf("= The form is not valid!\n");
#if 0
// TODO: uncomment this code whith a patch introducing a UI.
return NS_OK;
#endif // 0
}
#endif // DEBUG
// Mark us as submitting so that we don't try to submit again
mIsSubmitting = PR_TRUE;
NS_ASSERTION(!mWebProgress && !mSubmittingRequest, "Web progress / submitting request should not exist here!");
@ -1537,6 +1556,49 @@ nsHTMLFormElement::ForgetCurrentSubmission()
mWebProgress = nsnull;
}
PRBool
nsHTMLFormElement::CheckFormValidity() const
{
PRBool ret = PR_TRUE;
nsTArray<nsGenericHTMLFormElement*> sortedControls;
if (NS_FAILED(mControls->GetSortedControls(sortedControls))) {
return PR_FALSE;
}
PRUint32 len = sortedControls.Length();
// Hold a reference to the elements so they can't be deleted while calling
// the invalid events.
for (PRUint32 i = 0; i < len; ++i) {
static_cast<nsGenericHTMLElement*>(sortedControls[i])->AddRef();
}
for (PRUint32 i = 0; i < len; ++i) {
if (!sortedControls[i]->IsSubmittableControl()) {
continue;
}
nsCOMPtr<nsConstraintValidation> cvElmt =
do_QueryInterface((nsGenericHTMLElement*)sortedControls[i]);
if (cvElmt && cvElmt->IsCandidateForConstraintValidation() &&
!cvElmt->IsValid()) {
ret = PR_FALSE;
nsContentUtils::DispatchTrustedEvent(sortedControls[i]->GetOwnerDoc(),
static_cast<nsIContent*>(sortedControls[i]),
NS_LITERAL_STRING("invalid"),
PR_FALSE, PR_TRUE);
}
}
// Release the references.
for (PRUint32 i = 0; i < len; ++i) {
static_cast<nsGenericHTMLElement*>(sortedControls[i])->Release();
}
return ret;
}
// nsIWebProgressListener
NS_IMETHODIMP
nsHTMLFormElement::OnStateChange(nsIWebProgress* aWebProgress,

Просмотреть файл

@ -330,6 +330,17 @@ protected:
*/
nsresult GetActionURL(nsIURI** aActionURL, nsIContent* aOriginatingElement);
/**
* Check the form validity following this algorithm:
* http://www.whatwg.org/specs/web-apps/current-work/#statically-validate-the-constraints
*
* TODO: add a [out] parameter to have the list of unhandled invalid controls
* but not needed until we have a UI to test it.
*
* @return Whether the form is currently valid.
*/
PRBool CheckFormValidity() const;
public:
/**
* Flush a possible pending submission. If there was a scripted submission

Просмотреть файл

@ -297,7 +297,7 @@ DOMCI_NODE_DATA(HTMLInputElement, nsHTMLInputElement)
// QueryInterface implementation for nsHTMLInputElement
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
NS_HTML_CONTENT_INTERFACE_TABLE8(nsHTMLInputElement,
NS_HTML_CONTENT_INTERFACE_TABLE9(nsHTMLInputElement,
nsIDOMHTMLInputElement,
nsITextControlElement,
nsIFileControlElement,
@ -305,7 +305,8 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
imgIDecoderObserver,
nsIImageLoadingContent,
imgIContainerObserver,
nsIDOMNSEditableElement)
nsIDOMNSEditableElement,
nsConstraintValidation)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLInputElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLInputElement)
@ -2791,7 +2792,7 @@ nsHTMLInputElement::IntrinsicState() const
state |= NS_EVENT_STATE_OPTIONAL;
}
if (IsCandidateForConstraintValidation(this)) {
if (IsCandidateForConstraintValidation()) {
state |= IsValid() ? NS_EVENT_STATE_VALID : NS_EVENT_STATE_INVALID;
}
@ -3182,7 +3183,7 @@ nsHTMLInputElement::DoesPatternApply() const
NS_IMETHODIMP
nsHTMLInputElement::SetCustomValidity(const nsAString& aError)
{
nsresult rv = nsConstraintValidation::SetCustomValidity(aError);
nsConstraintValidation::SetCustomValidity(aError);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
@ -3190,7 +3191,7 @@ nsHTMLInputElement::SetCustomValidity(const nsAString& aError)
NS_EVENT_STATE_VALID);
}
return rv;
return NS_OK;
}
PRBool

Просмотреть файл

@ -130,9 +130,10 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLOutputElement, nsGenericElement)
DOMCI_NODE_DATA(HTMLOutputElement, nsHTMLOutputElement)
NS_INTERFACE_TABLE_HEAD(nsHTMLOutputElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLOutputElement,
NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLOutputElement,
nsIDOMHTMLOutputElement,
nsIMutationObserver)
nsIMutationObserver,
nsConstraintValidation)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLOutputElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLOutputElement)

Просмотреть файл

@ -181,9 +181,10 @@ DOMCI_NODE_DATA(HTMLSelectElement, nsHTMLSelectElement)
// QueryInterface implementation for nsHTMLSelectElement
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSelectElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLSelectElement,
NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLSelectElement,
nsIDOMHTMLSelectElement,
nsISelectElement)
nsISelectElement,
nsConstraintValidation)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLSelectElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLSelectElement)
@ -200,7 +201,7 @@ NS_IMPL_NSCONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY(nsHTMLSelectElement)
NS_IMETHODIMP
nsHTMLSelectElement::SetCustomValidity(const nsAString& aError)
{
nsresult rv = nsConstraintValidation::SetCustomValidity(aError);
nsConstraintValidation::SetCustomValidity(aError);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
@ -208,7 +209,7 @@ nsHTMLSelectElement::SetCustomValidity(const nsAString& aError)
NS_EVENT_STATE_VALID);
}
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -1471,7 +1472,7 @@ nsHTMLSelectElement::IntrinsicState() const
{
PRInt32 state = nsGenericHTMLFormElement::IntrinsicState();
if (IsCandidateForConstraintValidation(this)) {
if (IsCandidateForConstraintValidation()) {
state |= IsValid() ? NS_EVENT_STATE_VALID : NS_EVENT_STATE_INVALID;
}

Просмотреть файл

@ -300,12 +300,13 @@ DOMCI_NODE_DATA(HTMLTextAreaElement, nsHTMLTextAreaElement)
// QueryInterface implementation for nsHTMLTextAreaElement
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLTextAreaElement)
NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLTextAreaElement,
NS_HTML_CONTENT_INTERFACE_TABLE6(nsHTMLTextAreaElement,
nsIDOMHTMLTextAreaElement,
nsIDOMNSHTMLTextAreaElement,
nsITextControlElement,
nsIDOMNSEditableElement,
nsIMutationObserver)
nsIMutationObserver,
nsConstraintValidation)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLTextAreaElement,
nsGenericHTMLFormElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTextAreaElement)
@ -966,7 +967,7 @@ nsHTMLTextAreaElement::IntrinsicState() const
state |= NS_EVENT_STATE_OPTIONAL;
}
if (IsCandidateForConstraintValidation(this)) {
if (IsCandidateForConstraintValidation()) {
state |= IsValid() ? NS_EVENT_STATE_VALID : NS_EVENT_STATE_INVALID;
}
@ -1095,7 +1096,7 @@ nsHTMLTextAreaElement::IsMutable() const
NS_IMETHODIMP
nsHTMLTextAreaElement::SetCustomValidity(const nsAString& aError)
{
nsresult rv = nsConstraintValidation::SetCustomValidity(aError);
nsConstraintValidation::SetCustomValidity(aError);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
@ -1103,7 +1104,7 @@ nsHTMLTextAreaElement::SetCustomValidity(const nsAString& aError)
NS_EVENT_STATE_VALID);
}
return rv;
return NS_OK;
}
PRBool

Просмотреть файл

@ -204,6 +204,7 @@ _TEST_FILES = \
test_bug582412-2.html \
test_bug558788-1.html \
test_bug558788-2.html \
test_bug561634.html \
$(NULL)
libs:: $(_TEST_FILES)

Просмотреть файл

@ -0,0 +1,144 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=561634
-->
<head>
<title>Test for Bug 561634</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/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=561634">Mozilla Bug 561634</a>
<p id="display"></p>
<!--<div id="content" style="display: none">-->
<div id="content">
<form>
</form>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 561634 **/
function checkEmptyForm()
{
ok(document.forms[0].checkValidity(), "An empty form is valid");
}
function checkInvalidNonSubmittable()
{
var f = document.forms[0];
var o = document.createElement('output');
var fs = document.createElement('fieldset');
f.appendChild(o);
f.appendChild(fs);
o.setCustomValidity("foo");
fs.setCustomValidity("foo");
ok(f.checkValidity(),
"A form with invalid non-submittable elements is valid");
f.removeChild(o);
f.removeChild(fs);
}
function checkBarredFromConstraintValidation()
{
var f = document.forms[0];
var i = document.createElement('input');
i.type = 'hidden';
f.appendChild(i);
i.setCustomValidity("foo");
ok(f.checkValidity(),
"A form with invalid submittable element barred from constraint validation is valid");
f.removeChild(i);
}
function checkValid()
{
var f = document.forms[0];
var i = document.createElement('input');
f.appendChild(i);
ok(f.checkValidity(), "A form with valid elements is valid");
f.removeChild(i);
}
function checkInvalid()
{
var f = document.forms[0];
var i = document.createElement('input');
f.appendChild(i);
i.setCustomValidity("foo");
ok(!f.checkValidity(), "A form with invalid elements is invalid");
var i2 = document.createElement('input');
f.appendChild(i2);
ok(!f.checkValidity(),
"A form with at least one invalid element is invalid");
// Check event is fired
i.addEventListener("invalid", function (e) {
ok(true, "invalid event should have been fired on invalid elements");
SimpleTest.finish();
}, false);
f.removeChild(i2);
f.removeChild(i);
}
function checkInvalidEvent()
{
var f = document.forms[0];
var i = document.createElement('input');
f.appendChild(i);
var i2 = document.createElement('input');
f.appendChild(i2);
i.setCustomValidity("foo");
var invalidEventForInvalidElement = false;
var invalidEventForValidElement = false;
i.addEventListener("invalid", function (e) {
invalidEventForInvalidElement = true;
ok(e.cancelable, "invalid event should be cancelable");
ok(!e.bubbles, "invalid event should not bubble");
}, false);
i2.addEventListener("invalid", function (e) {
invalidEventForValidElement = true;
}, false);
f.checkValidity();
SimpleTest.executeSoon(function () {
ok(invalidEventForInvalidElement,
"invalid event should be fired on invalid elements");
ok(!invalidEventForValidElement,
"invalid event should not be fired on valid elements");
});
f.removeChild(i2);
f.removeChild(i);
}
checkEmptyForm();
checkInvalidNonSubmittable();
checkBarredFromConstraintValidation();
checkValid();
checkInvalid();
checkInvalidEvent();
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -41,9 +41,10 @@
interface nsIDOMFormData;
[scriptable, uuid(a5735b98-7a5f-4242-8c9a-3805f3f61b76)]
[scriptable, uuid(55bdaf9b-eacb-49d6-b4b1-a27e61ed54fc)]
interface nsIDOMNSHTMLFormElement : nsISupports
{
attribute DOMString encoding;
nsIDOMFormData getFormData();
boolean checkValidity();
};