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

html form validation initial steps with test html file #13969

Merged
merged 1 commit into from Nov 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions components/script/dom/htmlbuttonelement.rs 100644 → 100755
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
45 changes: 38 additions & 7 deletions components/script/dom/htmlformelement.rs 100644 → 100755
Expand Up @@ -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;
Expand Down Expand Up @@ -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::<Element>() {
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::<Element>() {
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
}
Expand Down Expand Up @@ -700,7 +711,7 @@ pub enum FormSubmittableElement {
// KeygenElement(&'a HTMLKeygenElement),
ObjectElement(Root<HTMLObjectElement>),
SelectElement(Root<HTMLSelectElement>),
TextAreaElement(Root<HTMLTextAreaElement>)
TextAreaElement(Root<HTMLTextAreaElement>),
}

impl FormSubmittableElement {
Expand All @@ -713,6 +724,26 @@ impl FormSubmittableElement {
FormSubmittableElement::TextAreaElement(ref textarea) => textarea.upcast()
}
}

fn from_element(element: &Element) -> FormSubmittableElement {
if let Some(input) = element.downcast::<HTMLInputElement>() {
FormSubmittableElement::InputElement(Root::from_ref(&input))
}
else if let Some(input) = element.downcast::<HTMLButtonElement>() {
FormSubmittableElement::ButtonElement(Root::from_ref(&input))
}
else if let Some(input) = element.downcast::<HTMLObjectElement>() {
FormSubmittableElement::ObjectElement(Root::from_ref(&input))
}
else if let Some(input) = element.downcast::<HTMLSelectElement>() {
FormSubmittableElement::SelectElement(Root::from_ref(&input))
}
else if let Some(input) = element.downcast::<HTMLTextAreaElement>() {
FormSubmittableElement::TextAreaElement(Root::from_ref(&input))
} else {
unreachable!()
}
}
}

#[derive(Copy, Clone, HeapSizeOf)]
Expand Down
12 changes: 11 additions & 1 deletion components/script/dom/htmlinputelement.rs 100644 → 100755
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method likely needs to implement the various cases where input elements are barred from constraint validation (click the bold text to see a list of places where the term is used).

// 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 {
Expand Down
13 changes: 11 additions & 2 deletions components/script/dom/htmlobjectelement.rs 100644 → 100755
Expand Up @@ -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;
Expand Down Expand Up @@ -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> {
Expand Down
13 changes: 11 additions & 2 deletions components/script/dom/htmlselectelement.rs 100644 → 100755
Expand Up @@ -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;
Expand Down Expand Up @@ -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
}
}
1 change: 1 addition & 0 deletions components/script/dom/htmltextareaelement.rs 100644 → 100755
Expand Up @@ -406,4 +406,5 @@ impl VirtualMethods for HTMLTextAreaElement {

impl FormControl for HTMLTextAreaElement {}


impl Validatable for HTMLTextAreaElement {}
6 changes: 5 additions & 1 deletion components/script/dom/validation.rs 100644 → 100755
@@ -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 }
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need a method added here that performs the appropriate validation checks, returns true if the element validates, and false otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello

As described in the initial steps for the project, we have some doubts. Is it possible for you to give your email id so that we can have a discussion there?

Regards
Bhavya

15 changes: 15 additions & 0 deletions components/script/dom/validitystate.rs 100644 → 100755
Expand Up @@ -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 {
Expand Down
21 changes: 21 additions & 0 deletions tests/html/html_validation_test.html
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<body>

<form>
First name:<br>
<input type="text" name="firstname" value="Mickey" required>
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse" required>
<br><br>
<input type="submit" value="Submit">
</form>

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

</body>
</html>