diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs
index 22fed30a2df6..aed274660e42 100644
--- a/components/script/dom/htmlbuttonelement.rs
+++ b/components/script/dom/htmlbuttonelement.rs
@@ -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{
+ None
+ }
+}
impl Activatable for HTMLButtonElement {
fn as_element(&self) -> &Element {
diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs
index b9800dcd1f1f..693629ef572c 100644
--- a/components/script/dom/htmlfieldsetelement.rs
+++ b/components/script/dom/htmlfieldsetelement.rs
@@ -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;
+ }
+
+}
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 0e8b6174ab50..a0260a1dee8c 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -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::().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> {
@@ -463,8 +484,53 @@ impl HTMLFormElement {
// 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
-
+ //if self.check_if_candidate_for_validation(_el) & !self.check_if_candidate_satisfies_constraints(_el) {
+ match _el.upcast::().type_id() {
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
+ let html_input_element = _el.downcast::().unwrap();
+ if html_input_element.candidate_for_validation(_el)
+ & !html_input_element.satisfies_constraints(_el) {
+ return Some(FormSubmittableElement::InputElement(
+ Root::from_ref(_el.downcast::().unwrap())))
+ }
+ }
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => {
+ let html_button_element = _el.downcast::().unwrap();
+ if html_button_element.candidate_for_validation(_el)
+ & !html_button_element.satisfies_constraints(_el) {
+ return Some(FormSubmittableElement::ButtonElement(
+ Root::from_ref(_el.downcast::().unwrap())))
+ }
+ }
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
+ let html_select_element = _el.downcast::().unwrap();
+ if html_select_element.candidate_for_validation(_el)
+ & !html_select_element.satisfies_constraints(_el) {
+ return Some(FormSubmittableElement::SelectElement(
+ Root::from_ref(_el.downcast::().unwrap())))
+ }
+ }
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
+ let html_textarea_element = _el.downcast::().unwrap();
+ if html_textarea_element.candidate_for_validation(_el)
+ & !html_textarea_element.satisfies_constraints(_el) {
+ return Some(FormSubmittableElement::TextAreaElement(
+ Root::from_ref(_el.downcast::().unwrap())))
+ }
+ }
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => {
+ let html_object_element = _el.downcast::().unwrap();
+ if html_object_element.candidate_for_validation(_el)
+ & !html_object_element.satisfies_constraints(_el) {
+ return Some(FormSubmittableElement::ObjectElement(
+ Root::from_ref(_el.downcast::().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::>();
// 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 + 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 {
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 0e675b35b27d..69ee4111e830 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -11,6 +11,7 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::HTMLInputElementBinding;
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
@@ -29,8 +30,11 @@ 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::ValidityState;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
+use regex::Regex;
+//use range::Range;
use script_runtime::CommonScriptMsg;
use script_runtime::ScriptThreadEventCategory::InputEvent;
use script_thread::Runnable;
@@ -86,7 +90,6 @@ pub struct HTMLInputElement {
activation_state: DOMRefCell,
// https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag
value_dirty: Cell,
-
// TODO: selected files for file input
}
@@ -936,9 +939,245 @@ impl VirtualMethods for HTMLInputElement {
}
}
-impl FormControl for HTMLInputElement {}
+impl FormControl for HTMLInputElement {
+ 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 {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("required"))
+ .map(|s| s.Value());
+ if attr_value_check.is_some() {
+ //let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ if input_value_check.is_some() {
+ return false;
+ }
+ else {
+ println!("Error - Value missing in html input element");
+ return true;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ fn TypeMismatch(&self) -> bool {
+ //let regex_email: Regex = Regex::new(r"/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-] \
+ // {0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/").unwrap();
+ let regex_email: Regex = Regex::new(r"").unwrap();
+ let regex_url: Regex = Regex::new(r"").unwrap();
+ let regex_number: Regex = Regex::new(r"").unwrap();
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("type"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ // let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ if (attr_value == "email") & (!regex_email.is_match(&*input_value)) {
+ println!("Type error in html text input [email]");
+ return true;
+ }
+ else if (attr_value == "url") & (!regex_url.is_match(&*input_value)) {
+ println!("Type error in html text input [url]");
+ return true;
+ }
+ else if (attr_value == "number") & (!regex_number.is_match(&*input_value)) {
+ println!("Type error in html text input [number]");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ //let data = element1.form_datum(Some(FormSubmitter::InputElement(element1)));
+ }
+ fn PatternMismatch(&self) -> bool {
+ return false;
+ }
+ fn TooLong(&self) -> bool {
+
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("maxlength"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let maxlength = attr_value.parse().unwrap();
+ //let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ if input_value.len() > maxlength {
+ println!("Error - TooLong html input element");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ }
+ fn TooShort(&self) -> bool {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("minlength"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let minlength = attr_value.parse().unwrap();
+ // let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ if input_value.len() < minlength {
+ println!("Error - TooShort html input element");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ }
+ fn RangeUnderflow(&self) -> bool {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("min"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let min: f32 = attr_value.parse().unwrap();
+ // let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ let text_value: f32 = input_value.parse().unwrap();
+ if text_value < min {
+ println!("Error - RangeUnderflow html input element");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ }
+ fn RangeOverflow(&self) -> bool {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("max"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let max: f32 = attr_value.parse().unwrap();
+ // let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ let text_value: f32 = input_value.parse().unwrap();
+ if text_value > max {
+ println!("Error - RangeOverflow html input element");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ }
+ fn StepMismatch(&self) -> bool {
+
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("step"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let step: f32 = attr_value.parse().unwrap();
+ // let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ let text_value: f32 = input_value.parse().unwrap();
+ if text_value % step == 0.0_f32 {
+ return false;
+ }
+ else {
+ println!("Error - StepMismatch html input element");
+ return true;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ }
+ fn BadInput(&self) -> bool {
+ return false;
+ }
+ fn CustomError(&self) -> bool {
+ return false;
+ }
-impl Validatable for HTMLInputElement {}
+}
+impl Validatable for HTMLInputElement {
+ fn get_value_for_validation(&self) -> Option{
+ if self.Value().is_empty() {
+ None
+ } else {
+ Some(self.Value())
+ }
+ }
+}
impl Activatable for HTMLInputElement {
fn as_element(&self) -> &Element {
diff --git a/components/script/dom/htmllabelelement.rs b/components/script/dom/htmllabelelement.rs
index 90d4a16b86e1..fb14a84b44d8 100644
--- a/components/script/dom/htmllabelelement.rs
+++ b/components/script/dom/htmllabelelement.rs
@@ -6,6 +6,7 @@ use dom::activation::{Activatable, ActivationSource, synthetic_click_activation}
use dom::attr::AttrValue;
use dom::bindings::codegen::Bindings::HTMLLabelElementBinding;
use dom::bindings::codegen::Bindings::HTMLLabelElementBinding::HTMLLabelElementMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
@@ -15,10 +16,14 @@ use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, HTMLFormElement};
use dom::node::{document_from_node, Node};
+use dom::node::{window_from_node};
+use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
use util::str::DOMString;
+
+
#[dom_struct]
pub struct HTMLLabelElement {
htmlelement: HTMLElement,
@@ -138,4 +143,48 @@ impl HTMLLabelElement {
}
}
-impl FormControl for HTMLLabelElement {}
+impl FormControl for HTMLLabelElement {
+ 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;
+ }
+}
diff --git a/components/script/dom/htmllegendelement.rs b/components/script/dom/htmllegendelement.rs
index d0b3487113a3..50e2567e5b3e 100644
--- a/components/script/dom/htmllegendelement.rs
+++ b/components/script/dom/htmllegendelement.rs
@@ -5,6 +5,7 @@
use dom::bindings::codegen::Bindings::HTMLLegendElementBinding;
use dom::bindings::codegen::Bindings::HTMLLegendElementBinding::HTMLLegendElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
@@ -12,7 +13,9 @@ use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::htmlfieldsetelement::HTMLFieldSetElement;
use dom::htmlformelement::{HTMLFormElement, FormControl};
+use dom::node::window_from_node;
use dom::node::{Node, UnbindContext};
+use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
use util::str::DOMString;
@@ -81,4 +84,48 @@ impl HTMLLegendElementMethods for HTMLLegendElement {
}
}
-impl FormControl for HTMLLegendElement {}
+impl FormControl for HTMLLegendElement {
+ 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;
+ }
+}
diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs
index 4d2b1cde7783..53f98b84e7b3 100644
--- a/components/script/dom/htmlobjectelement.rs
+++ b/components/script/dom/htmlobjectelement.rs
@@ -6,6 +6,7 @@ use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HTMLObjectElementBinding;
use dom::bindings::codegen::Bindings::HTMLObjectElementBinding::HTMLObjectElementMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
@@ -21,6 +22,7 @@ use std::sync::Arc;
use string_cache::Atom;
use util::str::DOMString;
+
#[dom_struct]
pub struct HTMLObjectElement {
htmlelement: HTMLElement,
@@ -92,8 +94,11 @@ impl HTMLObjectElementMethods for HTMLObjectElement {
}
}
-impl Validatable for HTMLObjectElement {}
-
+impl Validatable for HTMLObjectElement {
+ fn get_value_for_validation(&self) -> Option{
+ None
+ }
+}
impl VirtualMethods for HTMLObjectElement {
fn super_type(&self) -> Option<&VirtualMethods> {
Some(self.upcast::() as &VirtualMethods)
@@ -112,4 +117,48 @@ impl VirtualMethods for HTMLObjectElement {
}
}
-impl FormControl for HTMLObjectElement {}
+impl FormControl for HTMLObjectElement {
+ 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;
+ }
+}
diff --git a/components/script/dom/htmloutputelement.rs b/components/script/dom/htmloutputelement.rs
index b614684b863d..955e4f2062d9 100644
--- a/components/script/dom/htmloutputelement.rs
+++ b/components/script/dom/htmloutputelement.rs
@@ -4,9 +4,11 @@
use dom::bindings::codegen::Bindings::HTMLOutputElementBinding;
use dom::bindings::codegen::Bindings::HTMLOutputElementBinding::HTMLOutputElementMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
+use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, HTMLFormElement};
use dom::node::{Node, window_from_node};
@@ -15,6 +17,7 @@ use dom::validitystate::ValidityState;
use string_cache::Atom;
use util::str::DOMString;
+
#[dom_struct]
pub struct HTMLOutputElement {
htmlelement: HTMLElement
@@ -57,4 +60,48 @@ impl HTMLOutputElementMethods for HTMLOutputElement {
}
}
-impl FormControl for HTMLOutputElement {}
+impl FormControl for HTMLOutputElement {
+ 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;
+ }
+}
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index cfce718bcbe4..b99beec5acc8 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -3,20 +3,24 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::{Attr, AttrValue};
+use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
+use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods;
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::codegen::UnionTypes::HTMLElementOrLong;
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
use dom::element::{AttributeMutation, Element};
+use dom::event::Event;
use dom::htmlelement::HTMLElement;
use dom::htmlfieldsetelement::HTMLFieldSetElement;
use dom::htmlformelement::{FormDatumValue, FormControl, FormDatum, HTMLFormElement};
use dom::htmloptionelement::HTMLOptionElement;
-use dom::node::{Node, UnbindContext, window_from_node};
+use dom::node::{Node, UnbindContext, window_from_node, document_from_node};
use dom::nodelist::NodeList;
use dom::validation::Validatable;
use dom::validitystate::ValidityState;
@@ -25,6 +29,7 @@ use string_cache::Atom;
use style::element_state::*;
use util::str::DOMString;
+
#[dom_struct]
pub struct HTMLSelectElement {
htmlelement: HTMLElement
@@ -232,8 +237,92 @@ impl VirtualMethods for HTMLSelectElement {
_ => self.super_type().unwrap().parse_plain_attribute(local_name, value),
}
}
+ fn handle_event(&self, event: &Event) {
+ if let Some(s) = self.super_type() {
+ s.handle_event(event);
+ }
+ if event.type_() == atom!("click") && !event.DefaultPrevented() {
+ // TODO: Dispatch events for non activatable inputs
+ // https://html.spec.whatwg.org/multipage/#common-input-element-events
+ //TODO: set the editing position for text inputs
+ document_from_node(self).request_focus(self.upcast());
+ }
+ }
}
-impl FormControl for HTMLSelectElement {}
+impl FormControl for HTMLSelectElement {
+ fn candidate_for_validation(&self, element: &Element) -> bool {
+ if element.as_maybe_validatable().is_some() {
+ return true
+ }
+ else {
+ return false
+ }
+ }
-impl Validatable for HTMLSelectElement {}
+ fn satisfies_constraints(&self, element: &Element) -> bool {
+ let vs = ValidityState::new(window_from_node(self).r(), element);
+ return vs.Valid()
+ }
+ fn ValueMissing(&self) -> bool {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("required"))
+ .map(|s| s.Value());
+ if attr_value_check.is_some() {
+ // let html_select_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ if input_value_check.is_some() {
+ return false;
+ }
+ else {
+ println!("Error - Value missing in html select area element");
+ return true;
+ }
+ }
+ else {
+ 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 HTMLSelectElement {
+ fn get_value_for_validation(&self) -> Option{
+ /*let node = self.upcast::();
+ for opt in node.traverse_preorder().filter_map(Root::downcast::) {
+ let element = opt.upcast::();
+ if opt.Selected() && element.enabled_state() {
+ Some(self.Name())
+ }
+ }*/
+
+ None
+
+ }
+}
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 597c9a2bb60e..e045945752bd 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -4,10 +4,12 @@
use dom::attr::{Attr, AttrValue};
use dom::bindings::cell::DOMRefCell;
+use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding;
use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{LayoutJS, Root};
use dom::bindings::reflector::{Reflectable};
@@ -22,8 +24,10 @@ use dom::htmlinputelement::ChangeEventRunnable;
use dom::keyboardevent::KeyboardEvent;
use dom::node::{ChildrenMutation, Node, NodeDamage, UnbindContext};
use dom::node::{document_from_node};
+use dom::node::{window_from_node};
use dom::nodelist::NodeList;
use dom::validation::Validatable;
+use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
use script_traits::ScriptMsg as ConstellationMsg;
@@ -34,6 +38,8 @@ use style::element_state::*;
use textinput::{KeyReaction, Lines, TextInput, SelectionDirection};
use util::str::DOMString;
+
+
#[dom_struct]
pub struct HTMLTextAreaElement {
htmlelement: HTMLElement,
@@ -390,6 +396,123 @@ impl VirtualMethods for HTMLTextAreaElement {
}
}
-impl FormControl for HTMLTextAreaElement {}
+impl FormControl for HTMLTextAreaElement {
+ 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 {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("required"))
+ .map(|s| s.Value());
+ if attr_value_check.is_some() {
+ // let html_textarea_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ if input_value_check.is_some() {
+ return false;
+ }
+ else {
+ println!("Error - Value missing in html text area element");
+ return true;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ fn TypeMismatch(&self) -> bool {
+ return false;
+ }
+ fn PatternMismatch(&self) -> bool {
+ return false;
+ }
+ fn TooLong(&self) -> bool {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("maxlength"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let maxlength = attr_value.parse().unwrap();
+ //let html_textarea_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ if input_value.len() > maxlength {
+ println!("Error - TooLong in text area");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ }
+ fn TooShort(&self) -> bool {
+ let attr_value_check = self.upcast::().get_attribute_by_name(DOMString::from("minlength"))
+ .map(|s| s.Value());
+ match attr_value_check {
+ Some(attr_value) => {
+ let minlength = attr_value.parse().unwrap();
+ // let html_input_element = self.element.downcast::().unwrap();
+ let input_value_check = self.get_value_for_validation();
+ match input_value_check {
+ Some(input_value) => {
+ if input_value.len() < minlength {
+ println!("Error - TooShort html input element");
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+ None => {
+ return false;
+ }
+ }
+ },
+ None => {
+ 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 HTMLTextAreaElement {}
+impl Validatable for HTMLTextAreaElement {
+ fn get_value_for_validation(&self) -> Option{
+ if self.Value().is_empty() {
+ None
+ } else {
+ Some(self.Value())
+ }
+ }
+}
diff --git a/components/script/dom/validation.rs b/components/script/dom/validation.rs
index e9a6a1568482..687ca7675762 100644
--- a/components/script/dom/validation.rs
+++ b/components/script/dom/validation.rs
@@ -1,5 +1,8 @@
/* 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 util::str::DOMString;
-pub trait Validatable {}
+pub trait Validatable {
+ fn get_value_for_validation(&self) -> Option;
+}
diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs
index bd2cbb21aa7d..6a538865c38c 100644
--- a/components/script/dom/validitystate.rs
+++ b/components/script/dom/validitystate.rs
@@ -1,19 +1,25 @@
/* 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::bindings::codegen::Bindings::ValidityStateBinding;
use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::global::GlobalRef;
+use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::element::Element;
+use dom::htmlbuttonelement::HTMLButtonElement;
+use dom::htmlformelement::FormControl;
+use dom::htmlinputelement::HTMLInputElement;
+use dom::htmlobjectelement::HTMLObjectElement;
+use dom::htmlselectelement::HTMLSelectElement;
+use dom::htmltextareaelement::HTMLTextAreaElement;
+use dom::node::Node;
use dom::window::Window;
-// https://html.spec.whatwg.org/multipage/#validity-states
-#[derive_JSTraceable]
-#[derive_HeapSizeOf]
-pub enum ValidityStatus {
+/// https://html.spec.whatwg.org/multipage/#validity-states
+#[derive(JSTraceable, HeapSizeOf)]
+pub enum ValidityStates {
ValueMissing,
TypeMismatch,
PatternMismatch,
@@ -27,12 +33,12 @@ pub enum ValidityStatus {
Valid
}
-// https://html.spec.whatwg.org/multipage/#validitystate
+/// https://html.spec.whatwg.org/multipage/#validitystate
#[dom_struct]
pub struct ValidityState {
reflector_: Reflector,
element: JS,
- state: ValidityStatus
+ state: ValidityStates
}
@@ -41,7 +47,7 @@ impl ValidityState {
ValidityState {
reflector_: Reflector::new(),
element: JS::from_ref(element),
- state: ValidityStatus::Valid
+ state: ValidityStates::Valid
}
}
@@ -55,57 +61,134 @@ impl ValidityState {
impl ValidityStateMethods for ValidityState {
// https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing
- fn ValueMissing(&self) -> bool {
- false
- }
+ fn ValueMissing(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-typemismatch
- fn TypeMismatch(&self) -> bool {
- false
- }
+ fn TypeMismatch(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-patternmismatch
- fn PatternMismatch(&self) -> bool {
- false
- }
+ fn PatternMismatch(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-toolong
- fn TooLong(&self) -> bool {
- false
- }
+ fn TooLong(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-tooshort
- fn TooShort(&self) -> bool {
- false
- }
+ fn TooShort(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeunderflow
- fn RangeUnderflow(&self) -> bool {
- false
- }
+ fn RangeUnderflow(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeoverflow
- fn RangeOverflow(&self) -> bool {
- false
- }
+ fn RangeOverflow(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-stepmismatch
- fn StepMismatch(&self) -> bool {
- false
- }
+ fn StepMismatch(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-badinput
- fn BadInput(&self) -> bool {
- false
- }
+ fn BadInput(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-customerror
- fn CustomError(&self) -> bool {
- false
- }
+ fn CustomError(&self) -> bool { return false; }
+
// https://html.spec.whatwg.org/multipage/#dom-validitystate-valid
fn Valid(&self) -> bool {
- false
+ match self.element.upcast::().type_id() {
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
+ let html_input_element = self.element.downcast::().unwrap();
+ return !(
+ html_input_element.ValueMissing()|
+ html_input_element.TypeMismatch()|
+ html_input_element.PatternMismatch()|
+ html_input_element.TooLong()|
+ html_input_element.TooShort()|
+ html_input_element.RangeUnderflow()|
+ html_input_element.RangeOverflow()|
+ html_input_element.StepMismatch()|
+ html_input_element.BadInput()|
+ html_input_element.CustomError());
+
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => {
+ let html_button_element = self.element.downcast::().unwrap();
+ return !(
+ html_button_element.ValueMissing()|
+ html_button_element.TypeMismatch()|
+ html_button_element.PatternMismatch()|
+ html_button_element.TooLong()|
+ html_button_element.TooShort()|
+ html_button_element.RangeUnderflow()|
+ html_button_element.RangeOverflow()|
+ html_button_element.StepMismatch()|
+ html_button_element.BadInput()|
+ html_button_element.CustomError());
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => {
+ let html_object_element = self.element.downcast::().unwrap();
+ return !(
+ html_object_element.ValueMissing()|
+ html_object_element.TypeMismatch()|
+ html_object_element.PatternMismatch()|
+ html_object_element.TooLong()|
+ html_object_element.TooShort()|
+ html_object_element.RangeUnderflow()|
+ html_object_element.RangeOverflow()|
+ html_object_element.StepMismatch()|
+ html_object_element.BadInput()|
+ html_object_element.CustomError());
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
+ let html_select_element = self.element.downcast::().unwrap();
+ return !(
+ html_select_element.ValueMissing()|
+ html_select_element.TypeMismatch()|
+ html_select_element.PatternMismatch()|
+ html_select_element.TooLong()|
+ html_select_element.TooShort()|
+ html_select_element.RangeUnderflow()|
+ html_select_element.RangeOverflow()|
+ html_select_element.StepMismatch()|
+ html_select_element.BadInput()|
+ html_select_element.CustomError());
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
+ let html_textarea_element = self.element.downcast::().unwrap();
+ return !(
+ html_textarea_element.ValueMissing()|
+ html_textarea_element.TypeMismatch()|
+ html_textarea_element.PatternMismatch()|
+ html_textarea_element.TooLong()|
+ html_textarea_element.TooShort()|
+ html_textarea_element.RangeUnderflow()|
+ html_textarea_element.RangeOverflow()|
+ html_textarea_element.StepMismatch()|
+ html_textarea_element.BadInput()|
+ html_textarea_element.CustomError());
+ },
+ NodeTypeId::Element(_) => {
+ return false;
+ }
+ NodeTypeId::CharacterData(_) => {
+ return false;
+ }
+ NodeTypeId::Document(_) => {
+ return false;
+ }
+ NodeTypeId::DocumentFragment => {
+ return false;
+ }
+ NodeTypeId::DocumentType => {
+ return false;
+ }
+ };
}
}
diff --git a/components/script/dom/webidls/HTMLFormElement.webidl b/components/script/dom/webidls/HTMLFormElement.webidl
index a56b83235b66..f96596b34d95 100644
--- a/components/script/dom/webidls/HTMLFormElement.webidl
+++ b/components/script/dom/webidls/HTMLFormElement.webidl
@@ -22,8 +22,10 @@ interface HTMLFormElement : HTMLElement {
void submit();
void reset();
- //boolean checkValidity();
- //boolean reportValidity();
+ // https://html.spec.whatwg.org/multipage/#the-form-element:statically-validate-the-constraints
+ boolean check_validity();
+ // https://html.spec.whatwg.org/multipage/#the-form-element:interactively-validate-the-constraints
+ boolean report_validity();
//void requestAutocomplete();
};