1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsIConstraintValidation.h"
9 #include "nsGenericHTMLElement.h"
10 #include "mozilla/dom/CustomEvent.h"
11 #include "mozilla/dom/HTMLFormElement.h"
12 #include "mozilla/dom/HTMLFieldSetElement.h"
13 #include "mozilla/dom/HTMLInputElement.h"
14 #include "mozilla/dom/ValidityState.h"
15 #include "nsIFormControl.h"
16 #include "nsISimpleEnumerator.h"
17 #include "nsContentUtils.h"
19 const uint16_t nsIConstraintValidation::sContentSpecifiedMaxLengthMessage
= 256;
21 using namespace mozilla
;
22 using namespace mozilla::dom
;
24 nsIConstraintValidation::nsIConstraintValidation()
25 : mValidityBitField(0)
26 // By default, all elements are subjects to constraint validation.
28 mBarredFromConstraintValidation(false) {}
30 nsIConstraintValidation::~nsIConstraintValidation() = default;
32 mozilla::dom::ValidityState
* nsIConstraintValidation::Validity() {
34 mValidity
= new mozilla::dom::ValidityState(this);
40 bool nsIConstraintValidation::CheckValidity(nsIContent
& aEventTarget
,
41 bool* aEventDefaultAction
) const {
42 if (!IsCandidateForConstraintValidation() || IsValid()) {
46 nsContentUtils::DispatchTrustedEvent(
47 aEventTarget
.OwnerDoc(), &aEventTarget
, u
"invalid"_ns
, CanBubble::eNo
,
48 Cancelable::eYes
, Composed::eDefault
, aEventDefaultAction
);
52 bool nsIConstraintValidation::ReportValidity() {
53 nsCOMPtr
<Element
> element
= do_QueryInterface(this);
54 MOZ_ASSERT(element
, "This class should be inherited by HTML elements only!");
56 bool defaultAction
= true;
57 if (CheckValidity(*element
, &defaultAction
)) {
65 AutoTArray
<RefPtr
<Element
>, 1> invalidElements
;
66 invalidElements
.AppendElement(element
);
69 if (!jsapi
.Init(element
->GetOwnerGlobal())) {
72 JS::Rooted
<JS::Value
> detail(jsapi
.cx());
73 if (!ToJSValue(jsapi
.cx(), invalidElements
, &detail
)) {
77 RefPtr
<CustomEvent
> event
=
78 NS_NewDOMCustomEvent(element
->OwnerDoc(), nullptr, nullptr);
79 event
->InitCustomEvent(jsapi
.cx(), u
"MozInvalidForm"_ns
,
81 /* Cancelable */ true, detail
);
82 event
->SetTrusted(true);
83 event
->WidgetEventPtr()->mFlags
.mOnlyChromeDispatch
= true;
85 element
->DispatchEvent(*event
);
89 void nsIConstraintValidation::SetValidityState(ValidityStateType aState
,
91 bool previousValidity
= IsValid();
94 mValidityBitField
|= aState
;
96 mValidityBitField
&= ~aState
;
99 // Inform the form and fieldset elements if our validity has changed.
100 if (previousValidity
!= IsValid() && IsCandidateForConstraintValidation()) {
101 nsCOMPtr
<nsIFormControl
> formCtrl
= do_QueryInterface(this);
102 NS_ASSERTION(formCtrl
, "This interface should be used by form elements!");
104 if (HTMLFormElement
* form
= formCtrl
->GetForm()) {
105 form
->UpdateValidity(IsValid());
107 if (HTMLFieldSetElement
* fieldSet
= formCtrl
->GetFieldSet()) {
108 fieldSet
->UpdateValidity(IsValid());
113 void nsIConstraintValidation::SetBarredFromConstraintValidation(bool aBarred
) {
114 bool previousBarred
= mBarredFromConstraintValidation
;
116 mBarredFromConstraintValidation
= aBarred
;
118 // Inform the form and fieldset elements if our status regarding constraint
119 // validation is going to change.
120 if (!IsValid() && previousBarred
!= mBarredFromConstraintValidation
) {
121 nsCOMPtr
<nsIFormControl
> formCtrl
= do_QueryInterface(this);
122 NS_ASSERTION(formCtrl
, "This interface should be used by form elements!");
124 // If the element is going to be barred from constraint validation, we can
125 // inform the form and fieldset that we are now valid. Otherwise, we are now
127 if (HTMLFormElement
* form
= formCtrl
->GetForm()) {
128 form
->UpdateValidity(aBarred
);
130 HTMLFieldSetElement
* fieldSet
= formCtrl
->GetFieldSet();
132 fieldSet
->UpdateValidity(aBarred
);