diff options
author | Taryn Hill <Phrohdoh@gmail.com> | 2016-09-18 22:22:47 -0500 |
---|---|---|
committer | Taryn Hill <Phrohdoh@gmail.com> | 2016-09-21 07:54:39 -0500 |
commit | 2cb5adf6c6bee44e6aac6b6e875a1cda7eb50c87 (patch) | |
tree | 7ef07e6d413aefced4f80029a9fc69adae5adc06 | |
parent | 7c0dfd07ad5149406b389ca893d51f6fa442e98e (diff) | |
download | servo-2cb5adf6c6bee44e6aac6b6e875a1cda7eb50c87.tar.gz servo-2cb5adf6c6bee44e6aac6b6e875a1cda7eb50c87.zip |
Implement minlength for text inputs
-rw-r--r-- | components/script/dom/htmlinputelement.rs | 31 | ||||
-rw-r--r-- | components/script/dom/htmltextareaelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLInputElement.webidl | 3 | ||||
-rw-r--r-- | components/script/textinput.rs | 3 | ||||
-rw-r--r-- | tests/unit/script/textinput.rs | 19 | ||||
-rw-r--r-- | tests/wpt/metadata/MANIFEST.json | 6 | ||||
-rw-r--r-- | tests/wpt/metadata/html/dom/interfaces.html.ini | 72 | ||||
-rw-r--r-- | tests/wpt/web-platform-tests/html/semantics/forms/the-input-element/minlength.html | 55 |
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> + |