summaryrefslogtreecommitdiffstats
path: root/dom/html/nsIConstraintValidation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/html/nsIConstraintValidation.cpp')
-rw-r--r--dom/html/nsIConstraintValidation.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/dom/html/nsIConstraintValidation.cpp b/dom/html/nsIConstraintValidation.cpp
new file mode 100644
index 0000000000..f4e6181c77
--- /dev/null
+++ b/dom/html/nsIConstraintValidation.cpp
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIConstraintValidation.h"
+
+#include "nsGenericHTMLElement.h"
+#include "mozilla/dom/CustomEvent.h"
+#include "mozilla/dom/HTMLFormElement.h"
+#include "mozilla/dom/HTMLFieldSetElement.h"
+#include "mozilla/dom/HTMLInputElement.h"
+#include "mozilla/dom/ValidityState.h"
+#include "nsIFormControl.h"
+#include "nsISimpleEnumerator.h"
+#include "nsContentUtils.h"
+
+const uint16_t nsIConstraintValidation::sContentSpecifiedMaxLengthMessage = 256;
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+nsIConstraintValidation::nsIConstraintValidation()
+ : mValidityBitField(0)
+ // By default, all elements are subjects to constraint validation.
+ ,
+ mBarredFromConstraintValidation(false) {}
+
+nsIConstraintValidation::~nsIConstraintValidation() = default;
+
+mozilla::dom::ValidityState* nsIConstraintValidation::Validity() {
+ if (!mValidity) {
+ mValidity = new mozilla::dom::ValidityState(this);
+ }
+
+ return mValidity;
+}
+
+bool nsIConstraintValidation::CheckValidity(nsIContent& aEventTarget,
+ bool* aEventDefaultAction) const {
+ if (!IsCandidateForConstraintValidation() || IsValid()) {
+ return true;
+ }
+
+ nsContentUtils::DispatchTrustedEvent(
+ aEventTarget.OwnerDoc(), &aEventTarget, u"invalid"_ns, CanBubble::eNo,
+ Cancelable::eYes, Composed::eDefault, aEventDefaultAction);
+ return false;
+}
+
+bool nsIConstraintValidation::ReportValidity() {
+ nsCOMPtr<Element> element = do_QueryInterface(this);
+ MOZ_ASSERT(element, "This class should be inherited by HTML elements only!");
+
+ bool defaultAction = true;
+ if (CheckValidity(*element, &defaultAction)) {
+ return true;
+ }
+
+ if (!defaultAction) {
+ return false;
+ }
+
+ AutoTArray<RefPtr<Element>, 1> invalidElements;
+ invalidElements.AppendElement(element);
+
+ AutoJSAPI jsapi;
+ if (!jsapi.Init(element->GetOwnerGlobal())) {
+ return false;
+ }
+ JS::Rooted<JS::Value> detail(jsapi.cx());
+ if (!ToJSValue(jsapi.cx(), invalidElements, &detail)) {
+ return false;
+ }
+
+ RefPtr<CustomEvent> event =
+ NS_NewDOMCustomEvent(element->OwnerDoc(), nullptr, nullptr);
+ event->InitCustomEvent(jsapi.cx(), u"MozInvalidForm"_ns,
+ /* CanBubble */ true,
+ /* Cancelable */ true, detail);
+ event->SetTrusted(true);
+ event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
+
+ element->DispatchEvent(*event);
+
+ auto* inputElement = HTMLInputElement::FromNode(element);
+ if (inputElement && inputElement->State().HasState(ElementState::FOCUS)) {
+ inputElement->UpdateValidityUIBits(true);
+ }
+
+ element->UpdateState(true);
+ return false;
+}
+
+void nsIConstraintValidation::SetValidityState(ValidityStateType aState,
+ bool aValue) {
+ bool previousValidity = IsValid();
+
+ if (aValue) {
+ mValidityBitField |= aState;
+ } else {
+ mValidityBitField &= ~aState;
+ }
+
+ // Inform the form and fieldset elements 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!");
+
+ if (HTMLFormElement* form = formCtrl->GetForm()) {
+ form->UpdateValidity(IsValid());
+ }
+ HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
+ if (fieldSet) {
+ fieldSet->UpdateValidity(IsValid());
+ }
+ }
+}
+
+void nsIConstraintValidation::SetBarredFromConstraintValidation(bool aBarred) {
+ bool previousBarred = mBarredFromConstraintValidation;
+
+ mBarredFromConstraintValidation = aBarred;
+
+ // Inform the form and fieldset elements 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!");
+
+ // If the element is going to be barred from constraint validation, we can
+ // inform the form and fieldset that we are now valid. Otherwise, we are now
+ // invalid.
+ if (HTMLFormElement* form = formCtrl->GetForm()) {
+ form->UpdateValidity(aBarred);
+ }
+ HTMLFieldSetElement* fieldSet = formCtrl->GetFieldSet();
+ if (fieldSet) {
+ fieldSet->UpdateValidity(aBarred);
+ }
+ }
+}