зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #10169 - Implement initial pieces of form validation (from jdm:formvalidation); r=jdm
Rebase of #10108. Source-Repo: https://github.com/servo/servo Source-Revision: f56062b0698addf17d8077f11e3c12a7e3a3cb8b --HG-- rename : servo/resources/shaders/clear.fs.glsl => servo/components/script/dom/validation.rs
This commit is contained in:
Родитель
8fb2808cb9
Коммит
135f6ff4b2
|
@ -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>
|
Загрузка…
Ссылка в новой задаче