aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmltextareaelement.rs
diff options
context:
space:
mode:
authorteapotd <teapot404@gmail.com>2020-04-01 11:08:02 +0200
committerteapotd <teapot404@gmail.com>2020-04-02 10:16:46 +0200
commit779552ee7ddbbde1055c7202e16b9a13c3961988 (patch)
treef3dac563783cfeaa5ca69851c426d7e7b4dff9c3 /components/script/dom/htmltextareaelement.rs
parente47e884cc738a5cb472416a4fbdd9d2a32a2385c (diff)
downloadservo-779552ee7ddbbde1055c7202e16b9a13c3961988.tar.gz
servo-779552ee7ddbbde1055c7202e16b9a13c3961988.zip
Form constraints validation
Diffstat (limited to 'components/script/dom/htmltextareaelement.rs')
-rwxr-xr-xcomponents/script/dom/htmltextareaelement.rs101
1 files changed, 99 insertions, 2 deletions
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 38fa642ca4c..b7d224db123 100755
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -29,7 +29,8 @@ use crate::dom::node::{
};
use crate::dom::nodelist::NodeList;
use crate::dom::textcontrol::{TextControlElement, TextControlSelection};
-use crate::dom::validation::Validatable;
+use crate::dom::validation::{is_barred_by_datalist_ancestor, Validatable};
+use crate::dom::validitystate::{ValidationFlags, ValidityState};
use crate::dom::virtualmethods::VirtualMethods;
use crate::textinput::{
Direction, KeyReaction, Lines, SelectionDirection, TextInput, UTF16CodeUnits, UTF8Bytes,
@@ -53,6 +54,7 @@ pub struct HTMLTextAreaElement {
value_dirty: Cell<bool>,
form_owner: MutNullableDom<HTMLFormElement>,
labels_node_list: MutNullableDom<NodeList>,
+ validity_state: MutNullableDom<ValidityState>,
}
pub trait LayoutHTMLTextAreaElementHelpers {
@@ -163,6 +165,7 @@ impl HTMLTextAreaElement {
value_dirty: Cell::new(false),
form_owner: Default::default(),
labels_node_list: Default::default(),
+ validity_state: Default::default(),
}
}
@@ -191,6 +194,13 @@ impl HTMLTextAreaElement {
let el = self.upcast::<Element>();
el.set_placeholder_shown_state(has_placeholder && !has_value);
}
+
+ // https://html.spec.whatwg.org/multipage/#concept-fe-mutable
+ fn is_mutable(&self) -> bool {
+ // https://html.spec.whatwg.org/multipage/#the-textarea-element%3Aconcept-fe-mutable
+ // https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
+ !(self.upcast::<Element>().disabled_state() || self.ReadOnly())
+ }
}
impl TextControlElement for HTMLTextAreaElement {
@@ -395,6 +405,36 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement {
self.selection()
.set_dom_range_text(replacement, Some(start), Some(end), selection_mode)
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate
+ fn WillValidate(&self) -> bool {
+ self.is_instance_validatable()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-validity
+ fn Validity(&self) -> DomRoot<ValidityState> {
+ self.validity_state()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-checkvalidity
+ fn CheckValidity(&self) -> bool {
+ self.check_validity()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-reportvalidity
+ fn ReportValidity(&self) -> bool {
+ self.report_validity()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-validationmessage
+ fn ValidationMessage(&self) -> DOMString {
+ self.validation_message()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-cva-setcustomvalidity
+ fn SetCustomValidity(&self, error: DOMString) {
+ self.validity_state().set_custom_error_message(error);
+ }
}
impl HTMLTextAreaElement {
@@ -643,4 +683,61 @@ impl FormControl for HTMLTextAreaElement {
}
}
-impl Validatable for HTMLTextAreaElement {}
+impl Validatable for HTMLTextAreaElement {
+ fn as_element(&self) -> &Element {
+ self.upcast()
+ }
+
+ fn validity_state(&self) -> DomRoot<ValidityState> {
+ self.validity_state
+ .or_init(|| ValidityState::new(&window_from_node(self), self.upcast()))
+ }
+
+ fn is_instance_validatable(&self) -> bool {
+ // https://html.spec.whatwg.org/multipage/#enabling-and-disabling-form-controls%3A-the-disabled-attribute%3Abarred-from-constraint-validation
+ // https://html.spec.whatwg.org/multipage/#the-textarea-element%3Abarred-from-constraint-validation
+ // https://html.spec.whatwg.org/multipage/#the-datalist-element%3Abarred-from-constraint-validation
+ !self.upcast::<Element>().disabled_state() &&
+ !self.ReadOnly() &&
+ !is_barred_by_datalist_ancestor(self.upcast())
+ }
+
+ fn perform_validation(&self, validate_flags: ValidationFlags) -> ValidationFlags {
+ let mut failed_flags = ValidationFlags::empty();
+
+ let textinput = self.textinput.borrow();
+ let UTF16CodeUnits(value_len) = textinput.utf16_len();
+ let last_edit_by_user = !textinput.was_last_change_by_set_content();
+ let value_dirty = self.value_dirty.get();
+
+ // https://html.spec.whatwg.org/multipage/#suffering-from-being-missing
+ // https://html.spec.whatwg.org/multipage/#the-textarea-element%3Asuffering-from-being-missing
+ if validate_flags.contains(ValidationFlags::VALUE_MISSING) {
+ if self.Required() && self.is_mutable() && value_len == 0 {
+ failed_flags.insert(ValidationFlags::VALUE_MISSING);
+ }
+ }
+
+ if value_dirty && last_edit_by_user && value_len > 0 {
+ // https://html.spec.whatwg.org/multipage/#suffering-from-being-too-long
+ // https://html.spec.whatwg.org/multipage/#limiting-user-input-length%3A-the-maxlength-attribute%3Asuffering-from-being-too-long
+ if validate_flags.contains(ValidationFlags::TOO_LONG) {
+ let max_length = self.MaxLength();
+ if max_length != DEFAULT_MAX_LENGTH && value_len > (max_length as usize) {
+ failed_flags.insert(ValidationFlags::TOO_LONG);
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#suffering-from-being-too-short
+ // https://html.spec.whatwg.org/multipage/#setting-minimum-input-length-requirements%3A-the-minlength-attribute%3Asuffering-from-being-too-short
+ if validate_flags.contains(ValidationFlags::TOO_SHORT) {
+ let min_length = self.MinLength();
+ if min_length != DEFAULT_MIN_LENGTH && value_len < (min_length as usize) {
+ failed_flags.insert(ValidationFlags::TOO_SHORT);
+ }
+ }
+ }
+
+ failed_flags
+ }
+}