Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML5 Form Validation - Subsequent Steps #10843

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

HTML 5 Form validations

Fixed the compilation issues in h5fv. Still need to incorporate the other half of keith's recommended changes

Moved the code to include check and report validity to webidl file

Fixed focus issue in htmlformelement, removed warning code

Fixed tidy-test issues

moved the validation logic from validity state to individual form elements ike inputelement, selectelement
  • Loading branch information
tyagiarpit authored and vinay92 committed May 3, 2016
commit 3ed6e7f5382e7080edd3a1160686649d59db3828
@@ -6,6 +6,7 @@ use dom::activation::{Activatable, ActivationSource, synthetic_click_activation}
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
@@ -27,6 +28,7 @@ use string_cache::Atom;
use style::element_state::*;
use util::str::DOMString;


#[derive(JSTraceable, PartialEq, Copy, Clone)]
#[derive(HeapSizeOf)]
enum ButtonType {
@@ -202,9 +204,58 @@ impl VirtualMethods for HTMLButtonElement {
}
}

impl FormControl for HTMLButtonElement {}
impl FormControl for HTMLButtonElement {
fn candidate_for_validation(&self, element: &Element) -> bool {
if element.as_maybe_validatable().is_some() {
return true
}
else {
return false
}
}

fn satisfies_constraints(&self, element: &Element) -> bool {
let vs = ValidityState::new(window_from_node(self).r(), element);
return vs.Valid()
}
fn ValueMissing(&self) -> bool {
return false;
}
fn TypeMismatch(&self) -> bool {
return false;
}
fn PatternMismatch(&self) -> bool {
return false;
}
fn TooLong(&self) -> bool {
return false;
}
fn TooShort(&self) -> bool {
return false;
}
fn RangeUnderflow(&self) -> bool {
return false;
}
fn RangeOverflow(&self) -> bool {
return false;
}
fn StepMismatch(&self) -> bool {
return false;
}
fn BadInput(&self) -> bool {
return false;
}
fn CustomError(&self) -> bool {
return false;
}

}

impl Validatable for HTMLButtonElement {}
impl Validatable for HTMLButtonElement {
fn get_value_for_validation(&self) -> Option<DOMString>{
None
}
}

impl Activatable for HTMLButtonElement {
fn as_element(&self) -> &Element {
@@ -5,6 +5,7 @@
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding;
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods;
use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
@@ -20,6 +21,7 @@ use string_cache::Atom;
use style::element_state::*;
use util::str::DOMString;


#[dom_struct]
pub struct HTMLFieldSetElement {
htmlelement: HTMLElement
@@ -151,4 +153,49 @@ impl VirtualMethods for HTMLFieldSetElement {
}
}

impl FormControl for HTMLFieldSetElement {}
impl FormControl for HTMLFieldSetElement {
fn candidate_for_validation(&self, element: &Element) -> bool {
if element.as_maybe_validatable().is_some() {
return true
}
else {
return false
}
}

fn satisfies_constraints(&self, element: &Element) -> bool {
let vs = ValidityState::new(window_from_node(self).r(), element);
return vs.Valid()
}
fn ValueMissing(&self) -> bool {
return false;
}
fn TypeMismatch(&self) -> bool {
return false;
}
fn PatternMismatch(&self) -> bool {
return false;
}
fn TooLong(&self) -> bool {
return false;
}
fn TooShort(&self) -> bool {
return false;
}
fn RangeUnderflow(&self) -> bool {
return false;
}
fn RangeOverflow(&self) -> bool {
return false;
}
fn StepMismatch(&self) -> bool {
return false;
}
fn BadInput(&self) -> bool {
return false;
}
fn CustomError(&self) -> bool {
return false;
}

}
@@ -7,6 +7,7 @@ use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
use dom::bindings::codegen::Bindings::HTMLFormElementBinding;
use dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementMethods;
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
@@ -228,6 +229,24 @@ impl HTMLFormElementMethods for HTMLFormElement {
fn Length(&self) -> u32 {
self.Elements().Length() as u32
}
// https://html.spec.whatwg.org/multipage/#the-form-element:statically-validate-the-constraints
fn Check_validity(&self) -> bool {
let _unhandled_invalid_controls = match self.static_validation() {
Ok(()) => return true,
Err(err) => {
println!("Error in form fields in CheckValdity");
return false
}
};
}
// https://html.spec.whatwg.org/multipage/#the-form-element:interactively-validate-the-constraints
fn Report_validity(&self) -> bool {
if self.interactive_validation().is_err() {
return false;
} else {
return true;
}
}
}

#[derive(Copy, Clone, HeapSizeOf, PartialEq)]
@@ -446,14 +465,16 @@ impl HTMLFormElement {
// Step 1-3
let _unhandled_invalid_controls = match self.static_validation() {
Ok(()) => return Ok(()),
Err(err) => err
Err(err) => {
err[0].as_event_target().downcast::<HTMLElement>().unwrap().Focus();
err
}
};
// TODO: Report the problems with the constraints of at least one of
// the elements given in unhandled invalid controls to the user
// Step 4
Err(())
}

/// Statitically validate the constraints of form elements
/// https://html.spec.whatwg.org/multipage/#statically-validate-the-constraints
fn static_validation(&self) -> Result<(), Vec<FormSubmittableElement>> {
@@ -463,8 +484,53 @@ impl HTMLFormElement {
// Step 1-3
let invalid_controls = node.traverse_preorder().filter_map(|field| {
if let Some(_el) = field.downcast::<Element>() {
None // Remove this line if you decide to refactor

//if self.check_if_candidate_for_validation(_el) & !self.check_if_candidate_satisfies_constraints(_el) {
match _el.upcast::<Node>().type_id() {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
let html_input_element = _el.downcast::<HTMLInputElement>().unwrap();
if html_input_element.candidate_for_validation(_el)
& !html_input_element.satisfies_constraints(_el) {
return Some(FormSubmittableElement::InputElement(
Root::from_ref(_el.downcast::<HTMLInputElement>().unwrap())))
}
}
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => {
let html_button_element = _el.downcast::<HTMLButtonElement>().unwrap();
if html_button_element.candidate_for_validation(_el)
& !html_button_element.satisfies_constraints(_el) {
return Some(FormSubmittableElement::ButtonElement(
Root::from_ref(_el.downcast::<HTMLButtonElement>().unwrap())))
}
}
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
let html_select_element = _el.downcast::<HTMLSelectElement>().unwrap();
if html_select_element.candidate_for_validation(_el)
& !html_select_element.satisfies_constraints(_el) {
return Some(FormSubmittableElement::SelectElement(
Root::from_ref(_el.downcast::<HTMLSelectElement>().unwrap())))
}
}
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
let html_textarea_element = _el.downcast::<HTMLTextAreaElement>().unwrap();
if html_textarea_element.candidate_for_validation(_el)
& !html_textarea_element.satisfies_constraints(_el) {
return Some(FormSubmittableElement::TextAreaElement(
Root::from_ref(_el.downcast::<HTMLTextAreaElement>().unwrap())))
}
}
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => {
let html_object_element = _el.downcast::<HTMLObjectElement>().unwrap();
if html_object_element.candidate_for_validation(_el)
& !html_object_element.satisfies_constraints(_el) {
return Some(FormSubmittableElement::ObjectElement(
Root::from_ref(_el.downcast::<HTMLObjectElement>().unwrap())))
}
}
_ => { }
}
//}
// None // Remove this line if you decide to refactor
None
// XXXKiChjang: Form control elements should each have a candidate_for_validation
// and satisfies_constraints methods

@@ -473,7 +539,10 @@ impl HTMLFormElement {
}
}).collect::<Vec<FormSubmittableElement>>();
// Step 4
if invalid_controls.is_empty() { return Ok(()); }
if invalid_controls.is_empty() {
println!("Invalid Controls is Empty");
return Ok(());
}
// Step 5-6
let unhandled_invalid_controls = invalid_controls.into_iter().filter_map(|field| {
let event = field.as_event_target()
@@ -858,8 +927,20 @@ pub trait FormControl: DerivedFrom<Element> + Reflectable {
}

// XXXKiChjang: Implement these on inheritors
// fn candidate_for_validation(&self) -> bool;
// fn satisfies_constraints(&self) -> bool;
fn candidate_for_validation(&self, element: &Element) -> bool;
fn satisfies_constraints(&self, element: &Element) -> bool;
// Implement these on htmlinputelement, htmlselectelement, etc
fn ValueMissing(&self) -> bool;
fn TypeMismatch(&self) -> bool;
fn PatternMismatch(&self) -> bool;
fn TooLong(&self) -> bool;
fn TooShort(&self) -> bool;
fn RangeUnderflow(&self) -> bool;
fn RangeOverflow(&self) -> bool;
fn StepMismatch(&self) -> bool;
fn BadInput(&self) -> bool;
fn CustomError(&self) -> bool;

}

impl VirtualMethods for HTMLFormElement {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.