From 2a408778518050d3632ad5c2694a96ae0b219cd9 Mon Sep 17 00:00:00 2001 From: Bhavya Bansal Date: Fri, 28 Oct 2016 18:12:20 -0700 Subject: [PATCH] html form validation initial steps with test html file, added stub methods, added code to handle validations --- components/script/dom/htmlbuttonelement.rs | 13 +++++- components/script/dom/htmlformelement.rs | 45 +++++++++++++++++--- components/script/dom/htmlinputelement.rs | 12 +++++- components/script/dom/htmlobjectelement.rs | 13 +++++- components/script/dom/htmlselectelement.rs | 13 +++++- components/script/dom/htmltextareaelement.rs | 1 + components/script/dom/validation.rs | 6 ++- components/script/dom/validitystate.rs | 15 +++++++ tests/html/html_validation_test.html | 21 +++++++++ 9 files changed, 124 insertions(+), 15 deletions(-) mode change 100644 => 100755 components/script/dom/htmlbuttonelement.rs mode change 100644 => 100755 components/script/dom/htmlformelement.rs mode change 100644 => 100755 components/script/dom/htmlinputelement.rs mode change 100644 => 100755 components/script/dom/htmlobjectelement.rs mode change 100644 => 100755 components/script/dom/htmlselectelement.rs mode change 100644 => 100755 components/script/dom/htmltextareaelement.rs mode change 100644 => 100755 components/script/dom/validation.rs mode change 100644 => 100755 components/script/dom/validitystate.rs create mode 100644 tests/html/html_validation_test.html diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs old mode 100644 new mode 100755 index 95b85d0da8d..6e6932b4843 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -21,7 +21,7 @@ use dom::htmlformelement::HTMLFormElement; use dom::node::{Node, UnbindContext, document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::validation::Validatable; -use dom::validitystate::ValidityState; +use dom::validitystate::{ValidityState, ValidationFlags}; use dom::virtualmethods::VirtualMethods; use std::cell::Cell; use string_cache::Atom; @@ -238,7 +238,16 @@ impl VirtualMethods for HTMLButtonElement { impl FormControl for HTMLButtonElement {} -impl Validatable for HTMLButtonElement {} +impl Validatable for HTMLButtonElement { + fn is_instance_validatable(&self) -> bool { + true + } + fn validate(&self, validate_flags: ValidationFlags) -> bool { + if validate_flags.is_empty() {} + // Need more flag check for different validation types later + true + } +} impl Activatable for HTMLButtonElement { fn as_element(&self) -> &Element { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs old mode 100644 new mode 100755 index 78167022773..6a9f0196cd4 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -36,6 +36,7 @@ use dom::htmloutputelement::HTMLOutputElement; use dom::htmlselectelement::HTMLSelectElement; use dom::htmltextareaelement::HTMLTextAreaElement; use dom::node::{Node, document_from_node, window_from_node}; +use dom::validitystate::ValidationFlags; use dom::virtualmethods::VirtualMethods; use encoding::EncodingRef; use encoding::all::UTF_8; @@ -469,12 +470,22 @@ impl HTMLFormElement { // form, refactor this when html5ever's form owner PR lands // Step 1-3 let invalid_controls = node.traverse_preorder().filter_map(|field| { - if let Some(_el) = field.downcast::() { - None // Remove this line if you decide to refactor - - // XXXKiChjang: Form control elements should each have a candidate_for_validation - // and satisfies_constraints methods - + if let Some(el) = field.downcast::() { + if el.disabled_state() { + None + } else { + let validatable = match el.as_maybe_validatable() { + Some(v) => v, + None => return None + }; + if !validatable.is_instance_validatable() { + None + } else if validatable.validate(ValidationFlags::empty()) { + None + } else { + Some(FormSubmittableElement::from_element(&el)) + } + } } else { None } @@ -700,7 +711,7 @@ pub enum FormSubmittableElement { // KeygenElement(&'a HTMLKeygenElement), ObjectElement(Root), SelectElement(Root), - TextAreaElement(Root) + TextAreaElement(Root), } impl FormSubmittableElement { @@ -713,6 +724,26 @@ impl FormSubmittableElement { FormSubmittableElement::TextAreaElement(ref textarea) => textarea.upcast() } } + + fn from_element(element: &Element) -> FormSubmittableElement { + if let Some(input) = element.downcast::() { + FormSubmittableElement::InputElement(Root::from_ref(&input)) + } + else if let Some(input) = element.downcast::() { + FormSubmittableElement::ButtonElement(Root::from_ref(&input)) + } + else if let Some(input) = element.downcast::() { + FormSubmittableElement::ObjectElement(Root::from_ref(&input)) + } + else if let Some(input) = element.downcast::() { + FormSubmittableElement::SelectElement(Root::from_ref(&input)) + } + else if let Some(input) = element.downcast::() { + FormSubmittableElement::TextAreaElement(Root::from_ref(&input)) + } else { + unreachable!() + } + } } #[derive(Copy, Clone, HeapSizeOf)] diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs old mode 100644 new mode 100755 index 049d765b831..d2de2b5246f --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -31,6 +31,7 @@ use dom::node::{Node, NodeDamage, UnbindContext}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::validation::Validatable; +use dom::validitystate::ValidationFlags; use dom::virtualmethods::VirtualMethods; use ipc_channel::ipc::{self, IpcSender}; use mime_guess; @@ -1143,7 +1144,16 @@ impl VirtualMethods for HTMLInputElement { impl FormControl for HTMLInputElement {} -impl Validatable for HTMLInputElement {} +impl Validatable for HTMLInputElement { + fn is_instance_validatable(&self) -> bool { + // https://html.spec.whatwg.org/multipage/#candidate-for-constraint-validation + true + } + fn validate(&self, _validate_flags: ValidationFlags) -> bool { + // call stub methods defined in validityState.rs file here according to the flags set in validate_flags + true + } +} impl Activatable for HTMLInputElement { fn as_element(&self) -> &Element { diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs old mode 100644 new mode 100755 index 6e82b9f9bd6..e90676fb81b --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs @@ -15,7 +15,7 @@ use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormControl, HTMLFormElement}; use dom::node::{Node, window_from_node}; use dom::validation::Validatable; -use dom::validitystate::ValidityState; +use dom::validitystate::{ValidityState, ValidationFlags}; use dom::virtualmethods::VirtualMethods; use net_traits::image::base::Image; use std::sync::Arc; @@ -89,7 +89,16 @@ impl HTMLObjectElementMethods for HTMLObjectElement { } } -impl Validatable for HTMLObjectElement {} +impl Validatable for HTMLObjectElement { + fn is_instance_validatable(&self) -> bool { + true + } + fn validate(&self, validate_flags: ValidationFlags) -> bool { + if validate_flags.is_empty() {} + // Need more flag check for different validation types later + true + } +} impl VirtualMethods for HTMLObjectElement { fn super_type(&self) -> Option<&VirtualMethods> { diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs old mode 100644 new mode 100755 index c44dac71000..f3727aa0ee7 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -28,7 +28,7 @@ use dom::htmloptionscollection::HTMLOptionsCollection; use dom::node::{Node, UnbindContext, window_from_node}; use dom::nodelist::NodeList; use dom::validation::Validatable; -use dom::validitystate::ValidityState; +use dom::validitystate::{ValidityState, ValidationFlags}; use dom::virtualmethods::VirtualMethods; use string_cache::Atom; use style::attr::AttrValue; @@ -384,4 +384,13 @@ impl VirtualMethods for HTMLSelectElement { impl FormControl for HTMLSelectElement {} -impl Validatable for HTMLSelectElement {} +impl Validatable for HTMLSelectElement { + fn is_instance_validatable(&self) -> bool { + true + } + fn validate(&self, validate_flags: ValidationFlags) -> bool { + if validate_flags.is_empty() {} + // Need more flag check for different validation types later + true + } +} diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs old mode 100644 new mode 100755 index 7023b47c31b..289a28d04d1 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -406,4 +406,5 @@ impl VirtualMethods for HTMLTextAreaElement { impl FormControl for HTMLTextAreaElement {} + impl Validatable for HTMLTextAreaElement {} diff --git a/components/script/dom/validation.rs b/components/script/dom/validation.rs old mode 100644 new mode 100755 index e9a6a156848..7ba915092a2 --- a/components/script/dom/validation.rs +++ b/components/script/dom/validation.rs @@ -1,5 +1,9 @@ /* 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; -pub trait Validatable {} +pub trait Validatable { + fn is_instance_validatable(&self) -> bool { true } + fn validate(&self, _validate_flags: ValidationFlags) -> bool { true } +} diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs old mode 100644 new mode 100755 index 938320b7254..6bd7061e0ec --- a/components/script/dom/validitystate.rs +++ b/components/script/dom/validitystate.rs @@ -26,6 +26,21 @@ pub enum ValidityStatus { Valid } +bitflags!{ + pub flags ValidationFlags: u32 { + const VALUE_MISSING = 0b0000000001, + const TYPE_MISMATCH = 0b0000000010, + const PATTERN_MISMATCH = 0b0000000100, + const TOO_LONG = 0b0000001000, + const TOO_SHORT = 0b0000010000, + const RANGE_UNDERFLOW = 0b0000100000, + const RANGE_OVERFLOW = 0b0001000000, + const STEP_MISMATCH = 0b0010000000, + const BAD_INPUT = 0b0100000000, + const CUSTOM_ERROR = 0b1000000000, + } +} + // https://html.spec.whatwg.org/multipage/#validitystate #[dom_struct] pub struct ValidityState { diff --git a/tests/html/html_validation_test.html b/tests/html/html_validation_test.html new file mode 100644 index 00000000000..64b7ade0038 --- /dev/null +++ b/tests/html/html_validation_test.html @@ -0,0 +1,21 @@ + + + + +
+ First name:
+ +
+ Last name:
+ +

+ +
+ +

If you click the "Submit" button, the form-data will be sent to a page called "action_page.php".

+ + + + + +