aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaryn Hill <Phrohdoh@gmail.com>2016-09-18 22:22:47 -0500
committerTaryn Hill <Phrohdoh@gmail.com>2016-09-21 07:54:39 -0500
commit2cb5adf6c6bee44e6aac6b6e875a1cda7eb50c87 (patch)
tree7ef07e6d413aefced4f80029a9fc69adae5adc06
parent7c0dfd07ad5149406b389ca893d51f6fa442e98e (diff)
downloadservo-2cb5adf6c6bee44e6aac6b6e875a1cda7eb50c87.tar.gz
servo-2cb5adf6c6bee44e6aac6b6e875a1cda7eb50c87.zip
Implement minlength for text inputs
-rw-r--r--components/script/dom/htmlinputelement.rs31
-rw-r--r--components/script/dom/htmltextareaelement.rs2
-rw-r--r--components/script/dom/webidls/HTMLInputElement.webidl3
-rw-r--r--components/script/textinput.rs3
-rw-r--r--tests/unit/script/textinput.rs19
-rw-r--r--tests/wpt/metadata/MANIFEST.json6
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini72
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/forms/the-input-element/minlength.html55
8 files changed, 113 insertions, 78 deletions
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index aded18162ba..d9cda98b284 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -85,6 +85,7 @@ pub struct HTMLInputElement {
value_changed: Cell<bool>,
size: Cell<u32>,
maxlength: Cell<i32>,
+ minlength: Cell<i32>,
#[ignore_heap_size_of = "#7193"]
textinput: DOMRefCell<TextInput<IpcSender<ConstellationMsg>>>,
activation_state: DOMRefCell<InputActivationState>,
@@ -123,6 +124,7 @@ impl InputActivationState {
static DEFAULT_INPUT_SIZE: u32 = 20;
static DEFAULT_MAX_LENGTH: i32 = -1;
+static DEFAULT_MIN_LENGTH: i32 = -1;
impl HTMLInputElement {
fn new_inherited(local_name: Atom, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement {
@@ -136,8 +138,14 @@ impl HTMLInputElement {
checked_changed: Cell::new(false),
value_changed: Cell::new(false),
maxlength: Cell::new(DEFAULT_MAX_LENGTH),
+ minlength: Cell::new(DEFAULT_MIN_LENGTH),
size: Cell::new(DEFAULT_INPUT_SIZE),
- textinput: DOMRefCell::new(TextInput::new(Single, DOMString::new(), chan, None, SelectionDirection::None)),
+ textinput: DOMRefCell::new(TextInput::new(Single,
+ DOMString::new(),
+ chan,
+ None,
+ None,
+ SelectionDirection::None)),
activation_state: DOMRefCell::new(InputActivationState::new()),
value_dirty: Cell::new(false),
filelist: MutNullableHeap::new(None),
@@ -479,6 +487,12 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-maxlength
make_limited_int_setter!(SetMaxLength, "maxlength", DEFAULT_MAX_LENGTH);
+ // https://html.spec.whatwg.org/multipage/#dom-input-minlength
+ make_int_getter!(MinLength, "minlength", DEFAULT_MIN_LENGTH);
+
+ // https://html.spec.whatwg.org/multipage/#dom-input-minlength
+ make_limited_int_setter!(SetMinLength, "minlength", DEFAULT_MIN_LENGTH);
+
// https://html.spec.whatwg.org/multipage/#dom-input-min
make_getter!(Min, "min");
@@ -993,7 +1007,19 @@ impl VirtualMethods for HTMLInputElement {
},
_ => panic!("Expected an AttrValue::Int"),
}
- }
+ },
+ &atom!("minlength") => {
+ match *attr.value() {
+ AttrValue::Int(_, value) => {
+ if value < 0 {
+ self.textinput.borrow_mut().min_length = None
+ } else {
+ self.textinput.borrow_mut().min_length = Some(value as usize)
+ }
+ },
+ _ => panic!("Expected an AttrValue::Int"),
+ }
+ },
&atom!("placeholder") => {
{
let mut placeholder = self.placeholder.borrow_mut();
@@ -1027,6 +1053,7 @@ impl VirtualMethods for HTMLInputElement {
&atom!("size") => AttrValue::from_limited_u32(value.into(), DEFAULT_INPUT_SIZE),
&atom!("type") => AttrValue::from_atomic(value.into()),
&atom!("maxlength") => AttrValue::from_limited_i32(value.into(), DEFAULT_MAX_LENGTH),
+ &atom!("minlength") => AttrValue::from_limited_i32(value.into(), DEFAULT_MIN_LENGTH),
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
}
}
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index b43f4f75d5c..3a4418d713d 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -105,7 +105,7 @@ impl HTMLTextAreaElement {
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE,
local_name, prefix, document),
textinput: DOMRefCell::new(TextInput::new(
- Lines::Multiple, DOMString::new(), chan, None, SelectionDirection::None)),
+ Lines::Multiple, DOMString::new(), chan, None, None, SelectionDirection::None)),
value_changed: Cell::new(false),
}
}
diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl
index 1d6160b14cd..5c644894bbf 100644
--- a/components/script/dom/webidls/HTMLInputElement.webidl
+++ b/components/script/dom/webidls/HTMLInputElement.webidl
@@ -27,7 +27,8 @@ interface HTMLInputElement : HTMLElement {
[SetterThrows]
attribute long maxLength;
attribute DOMString min;
- // attribute long minLength;
+ [SetterThrows]
+ attribute long minLength;
attribute boolean multiple;
attribute DOMString name;
attribute DOMString pattern;
diff --git a/components/script/textinput.rs b/components/script/textinput.rs
index 5beee247f96..25243d739ab 100644
--- a/components/script/textinput.rs
+++ b/components/script/textinput.rs
@@ -73,6 +73,7 @@ pub struct TextInput<T: ClipboardProvider> {
///
/// https://html.spec.whatwg.org/multipage/#attr-fe-maxlength
pub max_length: Option<usize>,
+ pub min_length: Option<usize>,
pub selection_direction: SelectionDirection,
}
@@ -150,6 +151,7 @@ impl<T: ClipboardProvider> TextInput<T> {
/// Instantiate a new text input control
pub fn new(lines: Lines, initial: DOMString,
clipboard_provider: T, max_length: Option<usize>,
+ min_length: Option<usize>,
selection_direction: SelectionDirection) -> TextInput<T> {
let mut i = TextInput {
lines: vec!(),
@@ -158,6 +160,7 @@ impl<T: ClipboardProvider> TextInput<T> {
multiline: lines == Lines::Multiple,
clipboard_provider: clipboard_provider,
max_length: max_length,
+ min_length: min_length,
selection_direction: selection_direction,
};
i.set_content(initial);
diff --git a/tests/unit/script/textinput.rs b/tests/unit/script/textinput.rs
index b276b0da058..677132d393c 100644
--- a/tests/unit/script/textinput.rs
+++ b/tests/unit/script/textinput.rs
@@ -17,13 +17,18 @@ use script::dom::bindings::str::DOMString;
use script::textinput::{TextInput, TextPoint, Selection, Lines, Direction, SelectionDirection};
fn text_input(lines: Lines, s: &str) -> TextInput<DummyClipboardContext> {
- TextInput::new(lines, DOMString::from(s), DummyClipboardContext::new(""), None, SelectionDirection::None)
+ TextInput::new(lines,
+ DOMString::from(s),
+ DummyClipboardContext::new(""),
+ None,
+ None,
+ SelectionDirection::None)
}
#[test]
fn test_set_content_ignores_max_length() {
let mut textinput = TextInput::new(
- Lines::Single, DOMString::from(""), DummyClipboardContext::new(""), Some(1), SelectionDirection::None
+ Lines::Single, DOMString::from(""), DummyClipboardContext::new(""), Some(1), None, SelectionDirection::None
);
textinput.set_content(DOMString::from("mozilla rocks"));
@@ -37,6 +42,7 @@ fn test_textinput_when_inserting_multiple_lines_over_a_selection_respects_max_le
DOMString::from("hello\nworld"),
DummyClipboardContext::new(""),
Some(17),
+ None,
SelectionDirection::None,
);
@@ -61,6 +67,7 @@ fn test_textinput_when_inserting_multiple_lines_still_respects_max_length() {
DOMString::from("hello\nworld"),
DummyClipboardContext::new(""),
Some(17),
+ None,
SelectionDirection::None
);
@@ -78,6 +85,7 @@ fn test_textinput_when_content_is_already_longer_than_max_length_and_theres_no_s
DOMString::from("abc"),
DummyClipboardContext::new(""),
Some(1),
+ None,
SelectionDirection::None,
);
@@ -93,6 +101,7 @@ fn test_multi_line_textinput_with_maxlength_doesnt_allow_appending_characters_wh
DOMString::from("abc\nd"),
DummyClipboardContext::new(""),
Some(5),
+ None,
SelectionDirection::None,
);
@@ -108,6 +117,7 @@ fn test_single_line_textinput_with_max_length_doesnt_allow_appending_characters_
DOMString::from("abcde"),
DummyClipboardContext::new(""),
Some(5),
+ None,
SelectionDirection::None,
);
@@ -129,6 +139,7 @@ fn test_single_line_textinput_with_max_length_multibyte() {
DOMString::from(""),
DummyClipboardContext::new(""),
Some(2),
+ None,
SelectionDirection::None,
);
@@ -147,6 +158,7 @@ fn test_single_line_textinput_with_max_length_multi_code_unit() {
DOMString::from(""),
DummyClipboardContext::new(""),
Some(3),
+ None,
SelectionDirection::None,
);
@@ -167,6 +179,7 @@ fn test_single_line_textinput_with_max_length_inside_char() {
DOMString::from("\u{10437}"),
DummyClipboardContext::new(""),
Some(1),
+ None,
SelectionDirection::None,
);
@@ -181,6 +194,7 @@ fn test_single_line_textinput_with_max_length_doesnt_allow_appending_characters_
DOMString::from("a"),
DummyClipboardContext::new(""),
Some(1),
+ None,
SelectionDirection::None,
);
@@ -398,6 +412,7 @@ fn test_clipboard_paste() {
DOMString::from("defg"),
DummyClipboardContext::new("abc"),
None,
+ None,
SelectionDirection::None);
assert_eq!(textinput.get_content(), "defg");
assert_eq!(textinput.edit_point.index, 0);
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 4dd9d658d0a..ad6f50c06f5 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -37499,6 +37499,12 @@
"path": "dom/lists/DOMTokenList-Iterable.html",
"url": "/dom/lists/DOMTokenList-Iterable.html"
}
+ ],
+ "html/semantics/forms/the-input-element/minlength.html": [
+ {
+ "path": "html/semantics/forms/the-input-element/minlength.html",
+ "url": "/html/semantics/forms/the-input-element/minlength.html"
+ }
]
}
},
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index 7832b77a50a..240d96a350b 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -3555,9 +3555,6 @@
[HTMLInputElement interface: attribute list]
expected: FAIL
- [HTMLInputElement interface: attribute minLength]
- expected: FAIL
-
[HTMLInputElement interface: attribute valueAsDate]
expected: FAIL
@@ -3627,9 +3624,6 @@
[HTMLInputElement interface: document.createElement("input") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: document.createElement("input") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: document.createElement("input") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -6906,9 +6900,6 @@
[HTMLInputElement interface: createInput("text") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("text") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("text") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -6993,9 +6984,6 @@
[HTMLInputElement interface: createInput("hidden") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("hidden") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("hidden") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7080,9 +7068,6 @@
[HTMLInputElement interface: createInput("search") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("search") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("search") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7167,9 +7152,6 @@
[HTMLInputElement interface: createInput("tel") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("tel") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("tel") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7254,9 +7236,6 @@
[HTMLInputElement interface: createInput("url") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("url") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("url") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7341,9 +7320,6 @@
[HTMLInputElement interface: createInput("email") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("email") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("email") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7428,9 +7404,6 @@
[HTMLInputElement interface: createInput("password") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("password") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("password") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7515,9 +7488,6 @@
[HTMLInputElement interface: createInput("date") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("date") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("date") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7602,9 +7572,6 @@
[HTMLInputElement interface: createInput("month") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("month") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("month") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7689,9 +7656,6 @@
[HTMLInputElement interface: createInput("week") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("week") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("week") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7776,9 +7740,6 @@
[HTMLInputElement interface: createInput("time") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("time") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("time") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7863,9 +7824,6 @@
[HTMLInputElement interface: createInput("datetime-local") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("datetime-local") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("datetime-local") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -7950,9 +7908,6 @@
[HTMLInputElement interface: createInput("number") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("number") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("number") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8037,9 +7992,6 @@
[HTMLInputElement interface: createInput("range") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("range") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("range") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8124,9 +8076,6 @@
[HTMLInputElement interface: createInput("color") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("color") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("color") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8211,9 +8160,6 @@
[HTMLInputElement interface: createInput("checkbox") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("checkbox") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("checkbox") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8298,9 +8244,6 @@
[HTMLInputElement interface: createInput("radio") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("radio") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("radio") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8388,9 +8331,6 @@
[HTMLInputElement interface: createInput("file") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("file") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("file") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8475,9 +8415,6 @@
[HTMLInputElement interface: createInput("submit") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("submit") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("submit") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8562,9 +8499,6 @@
[HTMLInputElement interface: createInput("image") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("image") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("image") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8649,9 +8583,6 @@
[HTMLInputElement interface: createInput("reset") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("reset") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("reset") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
@@ -8736,9 +8667,6 @@
[HTMLInputElement interface: createInput("button") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: createInput("button") must inherit property "minLength" with the proper type (22)]
- expected: FAIL
-
[HTMLInputElement interface: createInput("button") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/the-input-element/minlength.html b/tests/wpt/web-platform-tests/html/semantics/forms/the-input-element/minlength.html
new file mode 100644
index 00000000000..7bfdf189a77
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/forms/the-input-element/minlength.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>input min length</title>
+ <link rel="author" title="Taryn Hill" href="mailto:Phrohdoh@gmail.com">
+ <link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#the-minlength-and-minlength-attributes">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <h1>Text input element</h1>
+
+ <div style="display: none">
+ <input id="none" />
+ <input id="negative" minlength=-5 />
+ <input id="non-numeric" minlength="not-a-number" />
+ <input id="assign-negative" />
+ <input id="assign-non-numeric" />
+ </div>
+
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(
+ function() {
+ assert_equals(document.getElementById("none").minLength, -1);
+ }, "Unset minlength is -1");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("negative").minLength, -1);
+ }, "Negative minlength is always -1");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("non-numeric").minLength, -1);
+ }, "Non-numeric minlength is -1");
+
+ test(
+ function() {
+ assert_throws("INDEX_SIZE_ERR", function() {
+ document.getElementById("assign-negative").minLength = -5;
+ });
+ }, "Assigning negative integer throws IndexSizeError");
+
+ test(
+ function() {
+ document.getElementById("assign-non-numeric").minLength = "not-a-number";
+ assert_equals(document.getElementById("assign-non-numeric").minLength, 0);
+ }, "Assigning non-numeric to minlength sets minlength to 0");
+ </script>
+ </body>
+</html>
+