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

Implement initial pieces of form validation. #10169

Merged
merged 1 commit into from Mar 24, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -47,7 +47,9 @@ use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use dom::htmllabelelement::HTMLLabelElement;
use dom::htmllegendelement::HTMLLegendElement;
use dom::htmlobjectelement::HTMLObjectElement;
use dom::htmloptgroupelement::HTMLOptGroupElement;
use dom::htmlselectelement::HTMLSelectElement;
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementLayoutHelpers};
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementLayoutHelpers};
use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementLayoutHelpers};
@@ -60,6 +62,7 @@ use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE, UnbindContext};
use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList;
use dom::text::Text;
use dom::validation::Validatable;
use dom::virtualmethods::{VirtualMethods, vtable_for};
use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
@@ -1913,6 +1916,36 @@ impl Element {
})
}

// https://html.spec.whatwg.org/multipage/#category-submit
pub fn as_maybe_validatable(&self) -> Option<&Validatable> {
let element = match self.upcast::<Node>().type_id() {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
let element = self.downcast::<HTMLInputElement>().unwrap();
Some(element as &Validatable)
},
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => {
let element = self.downcast::<HTMLButtonElement>().unwrap();
Some(element as &Validatable)
},
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => {
let element = self.downcast::<HTMLObjectElement>().unwrap();
Some(element as &Validatable)
},
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
let element = self.downcast::<HTMLSelectElement>().unwrap();
Some(element as &Validatable)
},
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
let element = self.downcast::<HTMLTextAreaElement>().unwrap();
Some(element as &Validatable)
},
_ => {
None
}
};
element
}

pub fn click_in_progress(&self) -> bool {
self.upcast::<Node>().get_flag(CLICK_IN_PROGRESS)
}
@@ -18,6 +18,7 @@ use dom::htmlformelement::{FormControl, FormSubmitter, ResetFrom};
use dom::htmlformelement::{SubmittedFrom, 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::virtualmethods::VirtualMethods;
use std::ascii::AsciiExt;
@@ -66,7 +67,7 @@ impl HTMLButtonElementMethods for HTMLButtonElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
ValidityState::new(window.r(), self.upcast())
}

// https://html.spec.whatwg.org/multipage/#dom-fe-disabled
@@ -203,6 +204,8 @@ impl VirtualMethods for HTMLButtonElement {

impl FormControl for HTMLButtonElement {}

impl Validatable for HTMLButtonElement {}

impl Activatable for HTMLButtonElement {
fn as_element(&self) -> &Element {
self.upcast()
@@ -64,7 +64,7 @@ impl HTMLFieldSetElementMethods for HTMLFieldSetElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
ValidityState::new(window.r(), self.upcast())
}

// https://html.spec.whatwg.org/multipage/#dom-fieldset-disabled
@@ -28,6 +28,7 @@ use dom::keyboardevent::KeyboardEvent;
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::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
use script_thread::ScriptThreadEventCategory::InputEvent;
@@ -908,6 +909,8 @@ impl VirtualMethods for HTMLInputElement {

impl FormControl for HTMLInputElement {}

impl Validatable for HTMLInputElement {}

impl Activatable for HTMLInputElement {
fn as_element(&self) -> &Element {
self.upcast()
@@ -13,6 +13,7 @@ use dom::element::{AttributeMutation, Element};
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::virtualmethods::VirtualMethods;
use net_traits::image::base::Image;
@@ -76,7 +77,7 @@ impl HTMLObjectElementMethods for HTMLObjectElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
ValidityState::new(window.r(), self.upcast())
}

// https://html.spec.whatwg.org/multipage/#dom-object-type
@@ -91,6 +92,8 @@ impl HTMLObjectElementMethods for HTMLObjectElement {
}
}

impl Validatable for HTMLObjectElement {}

impl VirtualMethods for HTMLObjectElement {
fn super_type(&self) -> Option<&VirtualMethods> {
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
@@ -43,7 +43,7 @@ impl HTMLOutputElementMethods for HTMLOutputElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
ValidityState::new(window.r(), self.upcast())
}

// https://html.spec.whatwg.org/multipage/#dom-fae-form
@@ -18,6 +18,7 @@ use dom::htmlformelement::{FormControl, FormDatum, HTMLFormElement};
use dom::htmloptionelement::HTMLOptionElement;
use dom::node::{Node, UnbindContext, window_from_node};
use dom::nodelist::NodeList;
use dom::validation::Validatable;
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
@@ -130,7 +131,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
ValidityState::new(window.r(), self.upcast())
}

// Note: this function currently only exists for union.html.
@@ -234,3 +235,5 @@ impl VirtualMethods for HTMLSelectElement {
}

impl FormControl for HTMLSelectElement {}

impl Validatable for HTMLSelectElement {}
@@ -23,6 +23,7 @@ use dom::keyboardevent::KeyboardEvent;
use dom::node::{ChildrenMutation, Node, NodeDamage, UnbindContext};
use dom::node::{document_from_node};
use dom::nodelist::NodeList;
use dom::validation::Validatable;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
use script_traits::ScriptMsg as ConstellationMsg;
@@ -334,3 +335,5 @@ impl VirtualMethods for HTMLTextAreaElement {
}

impl FormControl for HTMLTextAreaElement {}

impl Validatable for HTMLTextAreaElement {}
@@ -373,6 +373,7 @@ pub mod url;
pub mod urlhelper;
pub mod urlsearchparams;
pub mod userscripts;
pub mod validation;
pub mod validitystate;
pub mod values;
pub mod virtualmethods;
@@ -0,0 +1,5 @@
/* 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/. */

pub trait Validatable {}
@@ -3,29 +3,109 @@
* 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::js::Root;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::element::Element;
use dom::window::Window;

// https://html.spec.whatwg.org/multipage/#validity-states
#[derive_JSTraceable]
#[derive_HeapSizeOf]
pub enum ValidityStatus {
ValueMissing,
TypeMismatch,
PatternMismatch,
TooLong,
TooShort,
RangeUnderflow,
RangeOverflow,
StepMismatch,
BadInput,
CustomError,
Valid
}

// https://html.spec.whatwg.org/multipage/#validitystate
#[dom_struct]
pub struct ValidityState {
reflector_: Reflector,
state: u8,
element: JS<Element>,
state: ValidityStatus
}


impl ValidityState {
fn new_inherited() -> ValidityState {
fn new_inherited(element: &Element) -> ValidityState {
ValidityState {
reflector_: Reflector::new(),
state: 0,
element: JS::from_ref(element),
state: ValidityStatus::Valid
}
}

pub fn new(window: &Window) -> Root<ValidityState> {
reflect_dom_object(box ValidityState::new_inherited(),
pub fn new(window: &Window, element: &Element) -> Root<ValidityState> {
reflect_dom_object(box ValidityState::new_inherited(element),
GlobalRef::Window(window),
ValidityStateBinding::Wrap)
}
}

impl ValidityStateMethods for ValidityState {

// https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing
fn ValueMissing(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-typemismatch
fn TypeMismatch(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-patternmismatch
fn PatternMismatch(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-toolong
fn TooLong(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-tooshort
fn TooShort(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeunderflow
fn RangeUnderflow(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeoverflow
fn RangeOverflow(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-stepmismatch
fn StepMismatch(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-badinput
fn BadInput(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-customerror
fn CustomError(&self) -> bool {
false
}

// https://html.spec.whatwg.org/multipage/#dom-validitystate-valid
fn Valid(&self) -> bool {
false
}
}
@@ -5,15 +5,15 @@

// https://html.spec.whatwg.org/multipage/#validitystate
interface ValidityState {
//readonly attribute boolean valueMissing;
//readonly attribute boolean typeMismatch;
//readonly attribute boolean patternMismatch;
//readonly attribute boolean tooLong;
//readonly attribute boolean tooShort;
//readonly attribute boolean rangeUnderflow;
//readonly attribute boolean rangeOverflow;
//readonly attribute boolean stepMismatch;
//readonly attribute boolean badInput;
//readonly attribute boolean customError;
//readonly attribute boolean valid;
readonly attribute boolean valueMissing;
readonly attribute boolean typeMismatch;
readonly attribute boolean patternMismatch;
readonly attribute boolean tooLong;
readonly attribute boolean tooShort;
readonly attribute boolean rangeUnderflow;
readonly attribute boolean rangeOverflow;
readonly attribute boolean stepMismatch;
readonly attribute boolean badInput;
readonly attribute boolean customError;
readonly attribute boolean valid;
};
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<body>
<form>
Required: <input type="text" name="name" required><br>
Email : <input type="email" name="email"><br>
URL : <input type="url" name="email"><br>
Number(18-99): <input type="number" size="6" name="age" min="18" max="99"><br>
Pattern(MM/DD/YYYY): <input type="text" pattern="\d{1,2}/\d{1,2}/\d{4}"><br>
Length(10-20): <input minlength="10" maxlength="20"><br>
Length(10-20): <textarea required minlength="10" maxlength="20"></textarea><br>
Step(3.11)<input type="number" min="0" step="3.11"><br>
Required Select: <select required>
<option></option>
<option value="0">A</option>
<option value="1">B</option>
<option value="2">C</option>
</select><br>
Required Radio: <input type="radio" name="group1" value="1" required>1
<input type="radio" name="group1" value="2">2
<input type="radio" name="group1" value="3">3<br>
Required Checkbox: <input type="checkbox" name="group2" value="1" required>1
<input type="checkbox" name="group2" value="2">2
<input type="checkbox" name="group2" value="3">3<br>
Required File: <input type="file" required><br>
<input type="submit">
</form>
</body>
</html>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.