Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / html / nsIConstraintValidation.cpp
blob6ccda2ea7e4ce8c27f2055e28e83bd09068679f6
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() {
33 if (!mValidity) {
34 mValidity = new mozilla::dom::ValidityState(this);
37 return mValidity;
40 bool nsIConstraintValidation::CheckValidity(nsIContent& aEventTarget,
41 bool* aEventDefaultAction) const {
42 if (!IsCandidateForConstraintValidation() || IsValid()) {
43 return true;
46 nsContentUtils::DispatchTrustedEvent(
47 aEventTarget.OwnerDoc(), &aEventTarget, u"invalid"_ns, CanBubble::eNo,
48 Cancelable::eYes, Composed::eDefault, aEventDefaultAction);
49 return false;
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)) {
58 return true;
61 if (!defaultAction) {
62 return false;
65 AutoTArray<RefPtr<Element>, 1> invalidElements;
66 invalidElements.AppendElement(element);
68 AutoJSAPI jsapi;
69 if (!jsapi.Init(element->GetOwnerGlobal())) {
70 return false;
72 JS::Rooted<JS::Value> detail(jsapi.cx());
73 if (!ToJSValue(jsapi.cx(), invalidElements, &detail)) {
74 return false;
77 RefPtr<CustomEvent> event =
78 NS_NewDOMCustomEvent(element->OwnerDoc(), nullptr, nullptr);
79 event->InitCustomEvent(jsapi.cx(), u"MozInvalidForm"_ns,
80 /* CanBubble */ true,
81 /* Cancelable */ true, detail);
82 event->SetTrusted(true);
83 event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
85 element->DispatchEvent(*event);
86 return false;
89 void nsIConstraintValidation::SetValidityState(ValidityStateType aState,
90 bool aValue) {
91 bool previousValidity = IsValid();
93 if (aValue) {
94 mValidityBitField |= aState;
95 } else {
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
126 // invalid.
127 if (HTMLFormElement* form = formCtrl->GetForm()) {
128 form->UpdateValidity(aBarred);
130 HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
131 if (fieldSet) {
132 fieldSet->UpdateValidity(aBarred);