aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/validation.rs
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-10 17:24:27 +0900
committeryvt <i@yvt.jp>2021-07-10 17:55:42 +0900
commit01a7de50ab1843d85295f9dccad7f4c099e7208c (patch)
treeee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/validation.rs
parentff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff)
parent94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff)
downloadservo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz
servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html` was reverted to the upstream version.
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) -> &Element;
+
+ // 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())
+ }
}