Bug 1795723 - Unified extensions UI should support High Contrast Mode. r=ayeddi,deskt...
[gecko.git] / dom / html / nsIConstraintValidation.cpp
blobf4e6181c77db757a6200426a5594cca166d8d4c3
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);
87 auto* inputElement = HTMLInputElement::FromNode(element);
88 if (inputElement && inputElement->State().HasState(ElementState::FOCUS)) {
89 inputElement->UpdateValidityUIBits(true);
92 element->UpdateState(true);
93 return false;
96 void nsIConstraintValidation::SetValidityState(ValidityStateType aState,
97 bool aValue) {
98 bool previousValidity = IsValid();
100 if (aValue) {
101 mValidityBitField |= aState;
102 } else {
103 mValidityBitField &= ~aState;
106 // Inform the form and fieldset elements if our validity has changed.
107 if (previousValidity != IsValid() && IsCandidateForConstraintValidation()) {
108 nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this);
109 NS_ASSERTION(formCtrl, "This interface should be used by form elements!");
111 if (HTMLFormElement* form = formCtrl->GetForm()) {
112 form->UpdateValidity(IsValid());
114 HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
115 if (fieldSet) {
116 fieldSet->UpdateValidity(IsValid());
121 void nsIConstraintValidation::SetBarredFromConstraintValidation(bool aBarred) {
122 bool previousBarred = mBarredFromConstraintValidation;
124 mBarredFromConstraintValidation = aBarred;
126 // Inform the form and fieldset elements if our status regarding constraint
127 // validation is going to change.
128 if (!IsValid() && previousBarred != mBarredFromConstraintValidation) {
129 nsCOMPtr<nsIFormControl> formCtrl = do_QueryInterface(this);
130 NS_ASSERTION(formCtrl, "This interface should be used by form elements!");
132 // If the element is going to be barred from constraint validation, we can
133 // inform the form and fieldset that we are now valid. Otherwise, we are now
134 // invalid.
135 if (HTMLFormElement* form = formCtrl->GetForm()) {
136 form->UpdateValidity(aBarred);
138 HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
139 if (fieldSet) {
140 fieldSet->UpdateValidity(aBarred);