зеркало из https://github.com/mozilla/pjs.git
Bug 561634 - Implement constraint validation API for form element. r=smaug sr=sicking a2.0=blocking
This commit is contained in:
Родитель
82d46303be
Коммит
00b52d9848
|
@ -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();
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче