mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 580575 - Implement :-moz-submit-invalid pseudo-class applying on submit buttons when the form is invalid. r=bz sr=sicking a2.0=roc
This commit is contained in:
parent
a1d45586a0
commit
795e4b9f4e
@ -220,4 +220,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIEventStateManager, NS_IEVENTSTATEMANAGER_IID)
|
||||
// Content shows its placeholder
|
||||
#define NS_EVENT_STATE_MOZ_PLACEHOLDER (1 << 30)
|
||||
|
||||
// Content is a submit control and the form isn't valid.
|
||||
#define NS_EVENT_STATE_MOZ_SUBMITINVALID (1U << 31)
|
||||
|
||||
/**
|
||||
* WARNING:
|
||||
* (1U << 31) should work but we currently handle event states with PRInt32
|
||||
* so it's an edge case.
|
||||
* DO NOT ADD AN EVENT STATE after NS_EVENT_STATE_MOZ_SUBMITINVALID until we
|
||||
* move to PRUint64 and we introduce a type to handle event states.
|
||||
* See bug 595036.
|
||||
*/
|
||||
|
||||
#endif // nsIEventStateManager_h__
|
||||
|
@ -44,7 +44,6 @@
|
||||
|
||||
class nsDOMValidityState;
|
||||
class nsIDOMValidityState;
|
||||
class nsGenericHTMLFormElement;
|
||||
|
||||
#define NS_ICONSTRAINTVALIDATION_IID \
|
||||
{ 0xca3824dc, 0x4f5c, 0x4878, \
|
||||
@ -69,7 +68,9 @@ public:
|
||||
|
||||
PRBool IsValid() const { return mValidityBitField == 0; }
|
||||
|
||||
PRBool IsCandidateForConstraintValidation() const;
|
||||
PRBool IsCandidateForConstraintValidation() const {
|
||||
return !mBarredFromConstraintValidation;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetValidationMessage(nsAString& aValidationMessage);
|
||||
|
||||
@ -98,15 +99,10 @@ protected:
|
||||
return mValidityBitField & mState;
|
||||
}
|
||||
|
||||
void SetValidityState(ValidityStateType mState, PRBool mValue) {
|
||||
if (mValue) {
|
||||
mValidityBitField |= mState;
|
||||
} else {
|
||||
mValidityBitField &= ~mState;
|
||||
}
|
||||
}
|
||||
void SetValidityState(ValidityStateType mState,
|
||||
PRBool mValue);
|
||||
|
||||
virtual PRBool IsBarredFromConstraintValidation() const { return PR_FALSE; }
|
||||
void SetBarredFromConstraintValidation(PRBool aBarred);
|
||||
|
||||
virtual nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidityStateType aType) {
|
||||
@ -126,6 +122,11 @@ private:
|
||||
*/
|
||||
nsRefPtr<nsDOMValidityState> mValidity;
|
||||
|
||||
/**
|
||||
* Keeps track whether the element is barred from constraint validation.
|
||||
*/
|
||||
PRBool mBarredFromConstraintValidation;
|
||||
|
||||
/**
|
||||
* The string representing the custom error.
|
||||
*/
|
||||
|
@ -137,7 +137,7 @@ public:
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
// nsIConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation() const;
|
||||
void UpdateBarredFromConstraintValidation();
|
||||
|
||||
protected:
|
||||
virtual PRBool AcceptAutofocus() const
|
||||
@ -615,18 +615,27 @@ nsresult
|
||||
nsHTMLButtonElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aName == nsGkAtoms::type) {
|
||||
if (!aValue) {
|
||||
mType = kButtonDefaultType->value;
|
||||
PRInt32 states = 0;
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::type) {
|
||||
if (!aValue) {
|
||||
mType = kButtonDefaultType->value;
|
||||
}
|
||||
|
||||
UpdateBarredFromConstraintValidation();
|
||||
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID |
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
} else if (aName == nsGkAtoms::disabled) {
|
||||
UpdateBarredFromConstraintValidation();
|
||||
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
if (aNotify && states) {
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
doc->ContentStatesChanged(this, nsnull,
|
||||
NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID);
|
||||
doc->ContentStatesChanged(this, nsnull, states);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -672,6 +681,10 @@ nsHTMLButtonElement::IntrinsicState() const
|
||||
state |= IsValid() ? NS_EVENT_STATE_VALID : NS_EVENT_STATE_INVALID;
|
||||
}
|
||||
|
||||
if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
|
||||
state |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
}
|
||||
|
||||
return state | NS_EVENT_STATE_OPTIONAL;
|
||||
}
|
||||
|
||||
@ -692,10 +705,12 @@ nsHTMLButtonElement::SetCustomValidity(const nsAString& aError)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLButtonElement::IsBarredFromConstraintValidation() const
|
||||
void
|
||||
nsHTMLButtonElement::UpdateBarredFromConstraintValidation()
|
||||
{
|
||||
return (mType == NS_FORM_BUTTON_BUTTON ||
|
||||
mType == NS_FORM_BUTTON_RESET);
|
||||
SetBarredFromConstraintValidation(mType == NS_FORM_BUTTON_BUTTON ||
|
||||
mType == NS_FORM_BUTTON_RESET ||
|
||||
HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::disabled));
|
||||
}
|
||||
|
||||
|
@ -75,9 +75,6 @@ public:
|
||||
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
// nsIConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation() const { return PR_TRUE; };
|
||||
};
|
||||
|
||||
// construction, destruction
|
||||
@ -89,6 +86,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
|
||||
nsHTMLFieldSetElement::nsHTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericHTMLFormElement(aNodeInfo)
|
||||
{
|
||||
// <fieldset> is always barred from constraint validation.
|
||||
SetBarredFromConstraintValidation(PR_TRUE);
|
||||
}
|
||||
|
||||
nsHTMLFieldSetElement::~nsHTMLFieldSetElement()
|
||||
|
@ -80,6 +80,7 @@
|
||||
#include "nsIHTMLCollection.h"
|
||||
|
||||
#include "nsIConstraintValidation.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
|
||||
|
||||
@ -250,7 +251,8 @@ nsHTMLFormElement::nsHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
mSubmittingRequest(nsnull),
|
||||
mDefaultSubmitElement(nsnull),
|
||||
mFirstSubmitInElements(nsnull),
|
||||
mFirstSubmitNotInElements(nsnull)
|
||||
mFirstSubmitNotInElements(nsnull),
|
||||
mInvalidElementsCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -484,6 +486,16 @@ CollectOrphans(nsINode* aRemovalRoot, nsTArray<nsGenericHTMLFormElement*> aArray
|
||||
node->UnsetFlags(MAYBE_ORPHAN_FORM_ELEMENT);
|
||||
if (!nsContentUtils::ContentIsDescendantOf(node, aRemovalRoot)) {
|
||||
node->ClearForm(PR_TRUE, PR_TRUE);
|
||||
|
||||
// When submit controls have no more form, they need to be updated.
|
||||
if (node->IsSubmitControl()) {
|
||||
nsIDocument* doc = node->GetCurrentDoc();
|
||||
if (doc) {
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
doc->ContentStatesChanged(node, nsnull,
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
removed = PR_TRUE;
|
||||
#endif
|
||||
@ -1200,6 +1212,15 @@ nsHTMLFormElement::AddElement(nsGenericHTMLFormElement* aChild,
|
||||
}
|
||||
}
|
||||
|
||||
// If the element is subject to constraint validaton and is invalid, we need
|
||||
// to update our internal counter.
|
||||
nsCOMPtr<nsIConstraintValidation> cvElmt =
|
||||
do_QueryInterface(static_cast<nsGenericHTMLElement*>(aChild));
|
||||
if (cvElmt &&
|
||||
cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
|
||||
UpdateValidity(PR_FALSE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1267,6 +1288,15 @@ nsHTMLFormElement::RemoveElement(nsGenericHTMLFormElement* aChild,
|
||||
// own notifications.
|
||||
}
|
||||
|
||||
// If the element was subject to constraint validaton and is invalid, we need
|
||||
// to update our internal counter.
|
||||
nsCOMPtr<nsIConstraintValidation> cvElmt =
|
||||
do_QueryInterface(static_cast<nsGenericHTMLElement*>(aChild));
|
||||
if (cvElmt &&
|
||||
cvElmt->IsCandidateForConstraintValidation() && !cvElmt->IsValid()) {
|
||||
UpdateValidity(PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1616,6 +1646,60 @@ nsHTMLFormElement::CheckFormValidity() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLFormElement::UpdateValidity(PRBool aElementValidity)
|
||||
{
|
||||
if (aElementValidity) {
|
||||
--mInvalidElementsCount;
|
||||
} else {
|
||||
++mInvalidElementsCount;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mInvalidElementsCount >= 0, "Something went seriously wrong!");
|
||||
|
||||
// The form validity has just changed if:
|
||||
// - there are no more invalid elements ;
|
||||
// - or there is one invalid elmement and an element just became invalid.
|
||||
// If we have invalid elements and we used to before as well, do nothing.
|
||||
if (mInvalidElementsCount &&
|
||||
(mInvalidElementsCount != 1 || aElementValidity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are going to call ContentStatesChanged assuming submit controls want to
|
||||
* be notified because we can't know.
|
||||
* UpdateValidity shouldn't be called so much during parsing so it _should_
|
||||
* be safe.
|
||||
*/
|
||||
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
|
||||
// Inform submit controls that the form validity has changed.
|
||||
for (PRUint32 i = 0, length = mControls->mElements.Length();
|
||||
i < length; ++i) {
|
||||
if (mControls->mElements[i]->IsSubmitControl()) {
|
||||
doc->ContentStatesChanged(mControls->mElements[i], nsnull,
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID);
|
||||
}
|
||||
}
|
||||
|
||||
// Because of backward compatibility, <input type='image'> is not in elements
|
||||
// so we have to check for controls not in elements too.
|
||||
PRUint32 length = mControls->mNotInElements.Length();
|
||||
for (PRUint32 i = 0; i < length; ++i) {
|
||||
if (mControls->mNotInElements[i]->IsSubmitControl()) {
|
||||
doc->ContentStatesChanged(mControls->mNotInElements[i], nsnull,
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nsIWebProgressListener
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFormElement::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
|
@ -34,6 +34,10 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsHTMLFormElement_h__
|
||||
#define nsHTMLFormElement_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsIFormControl.h"
|
||||
@ -244,6 +248,29 @@ public:
|
||||
void OnSubmitClickBegin(nsIContent* aOriginatingElement);
|
||||
void OnSubmitClickEnd();
|
||||
|
||||
/**
|
||||
* This method will update the form validity so the submit controls states
|
||||
* will be updated (for -moz-submit-invalid pseudo-class).
|
||||
* This method has to be called by form elements whenever their validity state
|
||||
* or status regarding constraint validation changes.
|
||||
*
|
||||
* @note This method isn't used for CheckValidity().
|
||||
* @note If an element becomes barred from constraint validation, it has to be
|
||||
* considered as valid.
|
||||
*
|
||||
* @param aElementValidityState the new validity state of the element
|
||||
*/
|
||||
void UpdateValidity(PRBool aElementValidityState);
|
||||
|
||||
/**
|
||||
* Returns the form validity based on the last UpdateValidity() call.
|
||||
*
|
||||
* @return Whether the form was valid the last time UpdateValidity() was called.
|
||||
*
|
||||
* @note This method may not return the *current* validity state!
|
||||
*/
|
||||
PRBool GetValidity() const { return !mInvalidElementsCount; }
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
protected:
|
||||
class RemoveElementRunnable;
|
||||
@ -391,9 +418,18 @@ protected:
|
||||
/** The first submit element in mNotInElements -- WEAK */
|
||||
nsGenericHTMLFormElement* mFirstSubmitNotInElements;
|
||||
|
||||
/**
|
||||
* Number of invalid and candidate for constraint validation elements in the
|
||||
* form the last time UpdateValidity has been called.
|
||||
* @note Should only be used by UpdateValidity() and GetValidity()!
|
||||
*/
|
||||
PRInt32 mInvalidElementsCount;
|
||||
|
||||
protected:
|
||||
/** Detection of first form to notify observers */
|
||||
static PRBool gFirstFormSubmitted;
|
||||
/** Detection of first password input to initialize the password manager */
|
||||
static PRBool gPasswordManagerInitialized;
|
||||
};
|
||||
|
||||
#endif // nsHTMLFormElement_h__
|
||||
|
@ -850,7 +850,9 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
// null) doesn't call ParseAttribute.
|
||||
HandleTypeChange(kInputDefaultType->value);
|
||||
}
|
||||
|
||||
|
||||
UpdateBarredFromConstraintValidation();
|
||||
|
||||
// If we are changing type from File/Text/Tel/Passwd to other input types
|
||||
// we need save the mValue into value attribute
|
||||
if (mInputData.mValue &&
|
||||
@ -899,12 +901,19 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
NS_EVENT_STATE_VALID |
|
||||
NS_EVENT_STATE_INVALID |
|
||||
NS_EVENT_STATE_INDETERMINATE |
|
||||
NS_EVENT_STATE_MOZ_PLACEHOLDER;
|
||||
NS_EVENT_STATE_MOZ_PLACEHOLDER |
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
}
|
||||
|
||||
if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
|
||||
aName == nsGkAtoms::readonly) {
|
||||
UpdateValueMissingValidityState();
|
||||
|
||||
// This *has* to be called *after* validity has changed.
|
||||
if (aName == nsGkAtoms::readonly || aName == nsGkAtoms::disabled) {
|
||||
UpdateBarredFromConstraintValidation();
|
||||
}
|
||||
|
||||
states |= NS_EVENT_STATE_REQUIRED | NS_EVENT_STATE_OPTIONAL |
|
||||
NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
|
||||
} else if (aName == nsGkAtoms::maxlength) {
|
||||
@ -3207,6 +3216,10 @@ nsHTMLInputElement::IntrinsicState() const
|
||||
}
|
||||
}
|
||||
|
||||
if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
|
||||
state |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -3766,13 +3779,14 @@ nsHTMLInputElement::UpdateAllValidityStates(PRBool aNotify)
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLInputElement::IsBarredFromConstraintValidation() const
|
||||
void
|
||||
nsHTMLInputElement::UpdateBarredFromConstraintValidation()
|
||||
{
|
||||
return mType == NS_FORM_INPUT_HIDDEN ||
|
||||
mType == NS_FORM_INPUT_BUTTON ||
|
||||
mType == NS_FORM_INPUT_RESET ||
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
|
||||
SetBarredFromConstraintValidation(mType == NS_FORM_INPUT_HIDDEN ||
|
||||
mType == NS_FORM_INPUT_BUTTON ||
|
||||
mType == NS_FORM_INPUT_RESET ||
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::readonly) ||
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::disabled));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -273,7 +273,7 @@ public:
|
||||
void UpdateTypeMismatchValidityState();
|
||||
void UpdatePatternMismatchValidityState();
|
||||
void UpdateAllValidityStates(PRBool aNotify);
|
||||
PRBool IsBarredFromConstraintValidation() const;
|
||||
void UpdateBarredFromConstraintValidation();
|
||||
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidityStateType aType);
|
||||
|
||||
|
@ -130,9 +130,6 @@ public:
|
||||
|
||||
void StartObjectLoad() { StartObjectLoad(PR_TRUE); }
|
||||
|
||||
// nsIConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation() const { return PR_TRUE; }
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLObjectElement,
|
||||
nsGenericHTMLFormElement)
|
||||
|
||||
@ -157,6 +154,9 @@ nsHTMLObjectElement::nsHTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo
|
||||
{
|
||||
RegisterFreezableElement();
|
||||
SetIsNetworkCreated(aFromParser == NS_FROM_PARSER_NETWORK);
|
||||
|
||||
// <object> is always barred from constraint validation.
|
||||
SetBarredFromConstraintValidation(PR_TRUE);
|
||||
}
|
||||
|
||||
nsHTMLObjectElement::~nsHTMLObjectElement()
|
||||
|
@ -83,9 +83,6 @@ public:
|
||||
// has to be used to update the defaultValue attribute.
|
||||
void DescendantsChanged();
|
||||
|
||||
// nsIConstraintValidation
|
||||
PRBool IsBarredFromConstraintValidation() const { return PR_TRUE; }
|
||||
|
||||
// nsIMutationObserver
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
||||
@ -116,6 +113,8 @@ nsHTMLOutputElement::nsHTMLOutputElement(already_AddRefed<nsINodeInfo> aNodeInfo
|
||||
, mValueModeFlag(eModeDefault)
|
||||
{
|
||||
AddMutationObserver(this);
|
||||
// <output> is always barred from constraint validation.
|
||||
SetBarredFromConstraintValidation(PR_TRUE);
|
||||
}
|
||||
|
||||
nsHTMLOutputElement::~nsHTMLOutputElement()
|
||||
|
@ -1321,6 +1321,26 @@ nsHTMLSelectElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLSelectElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aName == nsGkAtoms::disabled && aNameSpaceID == kNameSpaceID_None) {
|
||||
SetBarredFromConstraintValidation(!!aValue);
|
||||
if (aNotify) {
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
doc->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_VALID |
|
||||
NS_EVENT_STATE_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLSelectElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
|
@ -287,6 +287,8 @@ public:
|
||||
*/
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
|
@ -208,7 +208,7 @@ public:
|
||||
PRBool IsValueMissing() const;
|
||||
void UpdateTooLongValidityState();
|
||||
void UpdateValueMissingValidityState();
|
||||
PRBool IsBarredFromConstraintValidation() const;
|
||||
void UpdateBarredFromConstraintValidation();
|
||||
nsresult GetValidationMessage(nsAString& aValidationMessage,
|
||||
ValidityStateType aType);
|
||||
|
||||
@ -1076,7 +1076,14 @@ nsHTMLTextAreaElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
|
||||
aName == nsGkAtoms::readonly) {
|
||||
UpdateValueMissingValidityState();
|
||||
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
|
||||
|
||||
// This *has* to be called *after* validity has changed.
|
||||
if (aName == nsGkAtoms::readonly || aName == nsGkAtoms::disabled) {
|
||||
UpdateBarredFromConstraintValidation();
|
||||
}
|
||||
|
||||
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID |
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID;
|
||||
} else if (aName == nsGkAtoms::maxlength) {
|
||||
UpdateTooLongValidityState();
|
||||
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
|
||||
@ -1180,10 +1187,13 @@ nsHTMLTextAreaElement::UpdateValueMissingValidityState()
|
||||
SetValidityState(VALIDITY_STATE_VALUE_MISSING, IsValueMissing());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLTextAreaElement::IsBarredFromConstraintValidation() const
|
||||
void
|
||||
nsHTMLTextAreaElement::UpdateBarredFromConstraintValidation()
|
||||
{
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
|
||||
SetBarredFromConstraintValidation(HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::readonly) ||
|
||||
HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::disabled));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -41,11 +41,15 @@
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
#include "nsDOMValidityState.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
|
||||
|
||||
nsIConstraintValidation::nsIConstraintValidation()
|
||||
: mValidityBitField(0)
|
||||
, mValidity(nsnull)
|
||||
// By default, all elements are subjects to constraint validation.
|
||||
, mBarredFromConstraintValidation(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -115,6 +119,31 @@ nsIConstraintValidation::CheckValidity(PRBool* aValidity)
|
||||
PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nsIConstraintValidation::SetValidityState(ValidityStateType aState,
|
||||
PRBool aValue)
|
||||
{
|
||||
PRBool previousValidity = IsValid();
|
||||
|
||||
if (aValue) {
|
||||
mValidityBitField |= aState;
|
||||
} else {
|
||||
mValidityBitField &= ~aState;
|
||||
}
|
||||
|
||||
// Inform the form element if our validity has changed.
|
||||
if (previousValidity != IsValid() && IsCandidateForConstraintValidation()) {
|
||||
nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this);
|
||||
NS_ASSERTION(formCtrl, "This interface should be used by form elements!");
|
||||
|
||||
nsHTMLFormElement* form =
|
||||
static_cast<nsHTMLFormElement*>(formCtrl->GetFormElement());
|
||||
if (form) {
|
||||
form->UpdateValidity(IsValid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsIConstraintValidation::SetCustomValidity(const nsAString& aError)
|
||||
{
|
||||
@ -122,28 +151,27 @@ nsIConstraintValidation::SetCustomValidity(const nsAString& aError)
|
||||
SetValidityState(VALIDITY_STATE_CUSTOM_ERROR, !mCustomValidity.IsEmpty());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsIConstraintValidation::IsCandidateForConstraintValidation() const
|
||||
void
|
||||
nsIConstraintValidation::SetBarredFromConstraintValidation(PRBool aBarred)
|
||||
{
|
||||
/**
|
||||
* An element is never candidate for constraint validation if:
|
||||
* - it is disabled ;
|
||||
* - TODO: or it's ancestor is a datalist element (bug 555840).
|
||||
* We are doing these checks here to prevent writing them in every
|
||||
* |IsBarredFromConstraintValidation| function.
|
||||
*/
|
||||
PRBool previousBarred = mBarredFromConstraintValidation;
|
||||
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(const_cast<nsIConstraintValidation*>(this));
|
||||
NS_ASSERTION(content, "This class should be inherited by HTML elements only!");
|
||||
mBarredFromConstraintValidation = aBarred;
|
||||
|
||||
// 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();
|
||||
// Inform the form element if our status regarding constraint validation
|
||||
// is going to change.
|
||||
if (!IsValid() && previousBarred != mBarredFromConstraintValidation) {
|
||||
nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this);
|
||||
NS_ASSERTION(formCtrl, "This interface should be used by form elements!");
|
||||
|
||||
nsHTMLFormElement* form =
|
||||
static_cast<nsHTMLFormElement*>(formCtrl->GetFormElement());
|
||||
if (form) {
|
||||
// If the element is going to be barred from constraint validation,
|
||||
// we can inform the form that we are now valid.
|
||||
// Otherwise, we are now invalid.
|
||||
form->UpdateValidity(aBarred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<input id='i' type='email' value='foo'>
|
||||
<form>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].appendChild(document.getElementById('b'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<button id='b' type='submit'></button>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('b').type = 'button';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<button id='b' type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('b').type = 'submit';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<button id='b'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' value='foo' required readonly>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').readOnly = 'ro';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').removeAttribute('readonly');
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required readonly>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' value='foo' required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required readonly>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type='email' value='foo'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<table id='t'>
|
||||
<form>
|
||||
<tr><td><input required></td></tr>
|
||||
<tr><td><button type='submit'></button></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,16 @@
|
||||
== static-valid.html valid-ref.html
|
||||
== dynamic-valid.html valid-ref.html
|
||||
== static-invalid.html invalid-ref.html
|
||||
== dynamic-invalid.html invalid-ref.html
|
||||
== dynamic-invalid-barred.html invalid-barred-ref.html
|
||||
== dynamic-invalid-barred-2.html invalid-barred-ref.html
|
||||
== dynamic-invalid-not-barred.html invalid-ref.html
|
||||
== static-invalid-barred.html invalid-barred-ref.html
|
||||
== remove-invalid-element.html valid-ref-2.html
|
||||
== add-invalid-element.html invalid-ref-2.html
|
||||
== add-submit-control.html invalid-ref.html
|
||||
== remove-submit-control.html valid-ref-3.html
|
||||
== change-type-submit-control.html invalid-ref.html
|
||||
== change-type-not-submit-control.html valid-ref-4.html
|
||||
== self-invalid.html about:blank
|
||||
== remove-form.html invalid-ref-3.html
|
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('t').removeChild(document.forms[0]);
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<table id='t'>
|
||||
<form>
|
||||
<tr><td><input required></td></tr>
|
||||
<tr><td><button type='submit'></button></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].removeChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' type='email' value='foo'>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.body.appendChild(document.getElementById('b'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<button id='b' type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('b').setCustomValidity('foo');
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<button id='b' type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input required readonly>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input value='foo' required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
<button type='submit'></button>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
<button></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input value='foo' required>
|
||||
<button type='submit'></button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<input id='i' type='email' value='foo'>
|
||||
<form>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<input id='i' type='image'>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').type = 'text';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<input id='i' type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').type = 'image';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<input id='i'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' value='foo' required readonly>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').readOnly = 'ro';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').removeAttribute('readonly');
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required readonly>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' value='foo' required>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required readonly>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type='email' value='foo'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<table id='t'>
|
||||
<form>
|
||||
<tr><td><input required></td></tr>
|
||||
<tr><td><input type='image'></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
16
layout/reftests/css-submit-invalid/input-image/reftest.list
Normal file
16
layout/reftests/css-submit-invalid/input-image/reftest.list
Normal file
@ -0,0 +1,16 @@
|
||||
== static-valid.html valid-ref.html
|
||||
== dynamic-valid.html valid-ref.html
|
||||
== static-invalid.html invalid-ref.html
|
||||
== dynamic-invalid.html invalid-ref.html
|
||||
== dynamic-invalid-barred.html invalid-barred-ref.html
|
||||
== dynamic-invalid-barred-2.html invalid-barred-ref.html
|
||||
== dynamic-invalid-not-barred.html invalid-ref.html
|
||||
== static-invalid-barred.html invalid-barred-ref.html
|
||||
== remove-invalid-element.html valid-ref-2.html
|
||||
== add-invalid-element.html invalid-ref-2.html
|
||||
== add-submit-control.html invalid-ref.html
|
||||
== remove-submit-control.html valid-ref-3.html
|
||||
== change-type-submit-control.html invalid-ref.html
|
||||
== change-type-not-submit-control.html valid-ref-4.html
|
||||
== self-invalid.html about:blank
|
||||
== remove-form.html invalid-ref-3.html
|
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('t').removeChild(document.forms[0]);
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<table id='t'>
|
||||
<form>
|
||||
<tr><td><input required></td></tr>
|
||||
<tr><td><input type='image'></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].removeChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' type='email' value='foo'>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.body.appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<input id='i' type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').setCustomValidity('foo');
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input required readonly>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input value='foo' required>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
<input type='image'>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
<input>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input value='foo' required>
|
||||
<input type='image'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<input id='i' type='email' value='foo'>
|
||||
<form>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<input id='i' type='submit'>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').type = 'text';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<input id='i' type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').type = 'submit';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<input id='i'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' value='foo' required readonly>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').readOnly = 'ro';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').removeAttribute('readonly');
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required readonly>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = '';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' value='foo' required>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').value = 'foo';
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' required>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required readonly>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type='email' value='foo'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<table id='t'>
|
||||
<form>
|
||||
<tr><td><input required></td></tr>
|
||||
<tr><td><input type='submit'></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
16
layout/reftests/css-submit-invalid/input-submit/reftest.list
Normal file
16
layout/reftests/css-submit-invalid/input-submit/reftest.list
Normal file
@ -0,0 +1,16 @@
|
||||
== static-valid.html valid-ref.html
|
||||
== dynamic-valid.html valid-ref.html
|
||||
== static-invalid.html invalid-ref.html
|
||||
== dynamic-invalid.html invalid-ref.html
|
||||
== dynamic-invalid-barred.html invalid-barred-ref.html
|
||||
== dynamic-invalid-barred-2.html invalid-barred-ref.html
|
||||
== dynamic-invalid-not-barred.html invalid-ref.html
|
||||
== static-invalid-barred.html invalid-barred-ref.html
|
||||
== remove-invalid-element.html valid-ref-2.html
|
||||
== add-invalid-element.html invalid-ref-2.html
|
||||
== add-submit-control.html invalid-ref.html
|
||||
== remove-submit-control.html valid-ref-3.html
|
||||
== change-type-submit-control.html invalid-ref.html
|
||||
== change-type-not-submit-control.html valid-ref-4.html
|
||||
== self-invalid.html about:blank
|
||||
== remove-form.html invalid-ref-3.html
|
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('t').removeChild(document.forms[0]);
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<table id='t'>
|
||||
<form>
|
||||
<tr><td><input required></td></tr>
|
||||
<tr><td><input type='submit'></td></tr>
|
||||
</form>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.forms[0].removeChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' type='email' value='foo'>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.body.appendChild(document.getElementById('i'));
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input required>
|
||||
<input id='i' type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html class='reftest-wait'>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<script>
|
||||
function onloadHandler()
|
||||
{
|
||||
document.getElementById('i').setCustomValidity('foo');
|
||||
document.documentElement.className = '';
|
||||
}
|
||||
</script>
|
||||
<body onload='onloadHandler();'>
|
||||
<form>
|
||||
<input id='i' type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input required readonly>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
:-moz-submit-invalid { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<input value='foo' required>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
</form>
|
||||
<input type='submit'>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input required>
|
||||
<input>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input value='foo' required>
|
||||
<input type='submit'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
3
layout/reftests/css-submit-invalid/reftest.list
Normal file
3
layout/reftests/css-submit-invalid/reftest.list
Normal file
@ -0,0 +1,3 @@
|
||||
include button-submit/reftest.list
|
||||
include input-image/reftest.list
|
||||
include input-submit/reftest.list
|
@ -80,6 +80,9 @@ include css-valid/reftest.list
|
||||
# css invalid
|
||||
include css-invalid/reftest.list
|
||||
|
||||
# css-submit-invalid
|
||||
include css-submit-invalid/reftest.list
|
||||
|
||||
# css transitions
|
||||
include css-transitions/reftest.list
|
||||
|
||||
|
@ -176,6 +176,8 @@ CSS_STATE_PSEUDO_CLASS(mozReadWrite, ":-moz-read-write",
|
||||
NS_EVENT_STATE_MOZ_READWRITE)
|
||||
CSS_STATE_PSEUDO_CLASS(mozPlaceholder, ":-moz-placeholder",
|
||||
NS_EVENT_STATE_MOZ_PLACEHOLDER)
|
||||
CSS_STATE_PSEUDO_CLASS(mozSubmitInvalid, ":-moz-submit-invalid",
|
||||
NS_EVENT_STATE_MOZ_SUBMITINVALID)
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#undef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
|
Loading…
Reference in New Issue
Block a user