aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/validation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/validation.rs')
-rwxr-xr-xcomponents/script/dom/validation.rs114
1 files changed, 110 insertions, 4 deletions
diff --git a/components/script/dom/validation.rs b/components/script/dom/validation.rs
index 7ba915092a2..e6b36ec809d 100755
--- a/components/script/dom/validation.rs
+++ b/components/script/dom/validation.rs
@@ -1,9 +1,115 @@
/* 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/. */
-use dom::validitystate::ValidationFlags;
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
+use crate::dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
+use crate::dom::bindings::inheritance::Castable;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::bindings::str::DOMString;
+use crate::dom::element::Element;
+use crate::dom::eventtarget::EventTarget;
+use crate::dom::htmldatalistelement::HTMLDataListElement;
+use crate::dom::htmlelement::HTMLElement;
+use crate::dom::node::Node;
+use crate::dom::validitystate::{ValidationFlags, ValidityState};
+/// Trait for elements with constraint validation support
pub trait Validatable {
- fn is_instance_validatable(&self) -> bool { true }
- fn validate(&self, _validate_flags: ValidationFlags) -> bool { true }
+ fn as_element(&self) -> ∈
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-validity
+ fn validity_state(&self) -> DomRoot<ValidityState>;
+
+ // https://html.spec.whatwg.org/multipage/#candidate-for-constraint-validation
+ fn is_instance_validatable(&self) -> bool;
+
+ // Check if element satisfies its constraints, excluding custom errors
+ fn perform_validation(&self, _validate_flags: ValidationFlags) -> ValidationFlags {
+ ValidationFlags::empty()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#concept-fv-valid
+ fn validate(&self, validate_flags: ValidationFlags) -> ValidationFlags {
+ let mut failed_flags = self.perform_validation(validate_flags);
+
+ // https://html.spec.whatwg.org/multipage/#suffering-from-a-custom-error
+ if validate_flags.contains(ValidationFlags::CUSTOM_ERROR) {
+ if !self.validity_state().custom_error_message().is_empty() {
+ failed_flags.insert(ValidationFlags::CUSTOM_ERROR);
+ }
+ }
+
+ failed_flags
+ }
+
+ // https://html.spec.whatwg.org/multipage/#check-validity-steps
+ fn check_validity(&self) -> bool {
+ if self.is_instance_validatable() && !self.validate(ValidationFlags::all()).is_empty() {
+ self.as_element()
+ .upcast::<EventTarget>()
+ .fire_cancelable_event(atom!("invalid"));
+ false
+ } else {
+ true
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#report-validity-steps
+ fn report_validity(&self) -> bool {
+ // Step 1.
+ if !self.is_instance_validatable() {
+ return true;
+ }
+
+ let flags = self.validate(ValidationFlags::all());
+ if flags.is_empty() {
+ return true;
+ }
+
+ // Step 1.1.
+ let event = self
+ .as_element()
+ .upcast::<EventTarget>()
+ .fire_cancelable_event(atom!("invalid"));
+
+ // Step 1.2.
+ if !event.DefaultPrevented() {
+ println!(
+ "Validation error: {}",
+ validation_message_for_flags(&self.validity_state(), flags)
+ );
+ if let Some(html_elem) = self.as_element().downcast::<HTMLElement>() {
+ html_elem.Focus();
+ }
+ }
+
+ // Step 1.3.
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-validationmessage
+ fn validation_message(&self) -> DOMString {
+ if self.is_instance_validatable() {
+ let flags = self.validate(ValidationFlags::all());
+ validation_message_for_flags(&self.validity_state(), flags)
+ } else {
+ DOMString::new()
+ }
+ }
+}
+
+// https://html.spec.whatwg.org/multipage/#the-datalist-element%3Abarred-from-constraint-validation
+pub fn is_barred_by_datalist_ancestor(elem: &Node) -> bool {
+ elem.upcast::<Node>()
+ .ancestors()
+ .any(|node| node.is::<HTMLDataListElement>())
+}
+
+// Get message for given validation flags or custom error message
+fn validation_message_for_flags(state: &ValidityState, failed_flags: ValidationFlags) -> DOMString {
+ if failed_flags.contains(ValidationFlags::CUSTOM_ERROR) {
+ state.custom_error_message().clone()
+ } else {
+ DOMString::from(failed_flags.to_string())
+ }
}