1 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsIConstraintValidation.h"
9 #include "nsGenericHTMLElement.h"
10 #include "mozilla/dom/HTMLFormElement.h"
11 #include "mozilla/dom/HTMLFieldSetElement.h"
12 #include "mozilla/dom/ValidityState.h"
13 #include "nsIFormControl.h"
14 #include "nsContentUtils.h"
16 const uint16_t nsIConstraintValidation::sContentSpecifiedMaxLengthMessage
= 256;
18 using namespace mozilla
;
19 using namespace mozilla::dom
;
21 nsIConstraintValidation::nsIConstraintValidation()
22 : mValidityBitField(0)
23 // By default, all elements are subjects to constraint validation.
24 , mBarredFromConstraintValidation(false)
28 nsIConstraintValidation::~nsIConstraintValidation()
32 mozilla::dom::ValidityState
*
33 nsIConstraintValidation::Validity()
36 mValidity
= new mozilla::dom::ValidityState(this);
43 nsIConstraintValidation::GetValidity(nsIDOMValidityState
** aValidity
)
45 NS_ENSURE_ARG_POINTER(aValidity
);
47 NS_ADDREF(*aValidity
= Validity());
53 nsIConstraintValidation::GetValidationMessage(nsAString
& aValidationMessage
)
55 aValidationMessage
.Truncate();
57 if (IsCandidateForConstraintValidation() && !IsValid()) {
58 nsCOMPtr
<nsIContent
> content
= do_QueryInterface(this);
59 NS_ASSERTION(content
, "This class should be inherited by HTML elements only!");
61 nsAutoString authorMessage
;
62 content
->GetAttr(kNameSpaceID_None
, nsGkAtoms::x_moz_errormessage
,
65 if (!authorMessage
.IsEmpty()) {
66 aValidationMessage
.Assign(authorMessage
);
67 if (aValidationMessage
.Length() > sContentSpecifiedMaxLengthMessage
) {
68 aValidationMessage
.Truncate(sContentSpecifiedMaxLengthMessage
);
70 } else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR
)) {
71 aValidationMessage
.Assign(mCustomValidity
);
72 if (aValidationMessage
.Length() > sContentSpecifiedMaxLengthMessage
) {
73 aValidationMessage
.Truncate(sContentSpecifiedMaxLengthMessage
);
75 } else if (GetValidityState(VALIDITY_STATE_TOO_LONG
)) {
76 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_TOO_LONG
);
77 } else if (GetValidityState(VALIDITY_STATE_VALUE_MISSING
)) {
78 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_VALUE_MISSING
);
79 } else if (GetValidityState(VALIDITY_STATE_TYPE_MISMATCH
)) {
80 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_TYPE_MISMATCH
);
81 } else if (GetValidityState(VALIDITY_STATE_PATTERN_MISMATCH
)) {
82 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_PATTERN_MISMATCH
);
83 } else if (GetValidityState(VALIDITY_STATE_RANGE_OVERFLOW
)) {
84 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_RANGE_OVERFLOW
);
85 } else if (GetValidityState(VALIDITY_STATE_RANGE_UNDERFLOW
)) {
86 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_RANGE_UNDERFLOW
);
87 } else if (GetValidityState(VALIDITY_STATE_STEP_MISMATCH
)) {
88 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_STEP_MISMATCH
);
89 } else if (GetValidityState(VALIDITY_STATE_BAD_INPUT
)) {
90 GetValidationMessage(aValidationMessage
, VALIDITY_STATE_BAD_INPUT
);
92 // There should not be other validity states.
93 return NS_ERROR_UNEXPECTED
;
96 aValidationMessage
.Truncate();
103 nsIConstraintValidation::CheckValidity()
105 if (!IsCandidateForConstraintValidation() || IsValid()) {
109 nsCOMPtr
<nsIContent
> content
= do_QueryInterface(this);
110 NS_ASSERTION(content
, "This class should be inherited by HTML elements only!");
112 nsContentUtils::DispatchTrustedEvent(content
->OwnerDoc(), content
,
113 NS_LITERAL_STRING("invalid"),
119 nsIConstraintValidation::CheckValidity(bool* aValidity
)
121 NS_ENSURE_ARG_POINTER(aValidity
);
123 *aValidity
= CheckValidity();
129 nsIConstraintValidation::SetValidityState(ValidityStateType aState
,
132 bool previousValidity
= IsValid();
135 mValidityBitField
|= aState
;
137 mValidityBitField
&= ~aState
;
140 // Inform the form and fieldset elements if our validity has changed.
141 if (previousValidity
!= IsValid() && IsCandidateForConstraintValidation()) {
142 nsCOMPtr
<nsIFormControl
> formCtrl
= do_QueryInterface(this);
143 NS_ASSERTION(formCtrl
, "This interface should be used by form elements!");
145 HTMLFormElement
* form
=
146 static_cast<HTMLFormElement
*>(formCtrl
->GetFormElement());
148 form
->UpdateValidity(IsValid());
150 HTMLFieldSetElement
* fieldSet
= formCtrl
->GetFieldSet();
152 fieldSet
->UpdateValidity(IsValid());
158 nsIConstraintValidation::SetCustomValidity(const nsAString
& aError
)
160 mCustomValidity
.Assign(aError
);
161 SetValidityState(VALIDITY_STATE_CUSTOM_ERROR
, !mCustomValidity
.IsEmpty());
165 nsIConstraintValidation::SetBarredFromConstraintValidation(bool aBarred
)
167 bool previousBarred
= mBarredFromConstraintValidation
;
169 mBarredFromConstraintValidation
= aBarred
;
171 // Inform the form and fieldset elements if our status regarding constraint
172 // validation is going to change.
173 if (!IsValid() && previousBarred
!= mBarredFromConstraintValidation
) {
174 nsCOMPtr
<nsIFormControl
> formCtrl
= do_QueryInterface(this);
175 NS_ASSERTION(formCtrl
, "This interface should be used by form elements!");
177 // If the element is going to be barred from constraint validation, we can
178 // inform the form and fieldset that we are now valid. Otherwise, we are now
180 HTMLFormElement
* form
=
181 static_cast<HTMLFormElement
*>(formCtrl
->GetFormElement());
183 form
->UpdateValidity(aBarred
);
185 HTMLFieldSetElement
* fieldSet
= formCtrl
->GetFieldSet();
187 fieldSet
->UpdateValidity(aBarred
);