diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-11-09 18:35:07 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-09 18:35:07 -0600 |
commit | 338e2ae5206d5270a6feaf7adbb8279fe25040e2 (patch) | |
tree | 541f64241b2f7f25f50866e92fca650227437808 /components/script/dom | |
parent | a1331169f6113440de37cade877ae799f72e4053 (diff) | |
parent | 8203605c043cc402e6264cf04e44758fcc7426a1 (diff) | |
download | servo-338e2ae5206d5270a6feaf7adbb8279fe25040e2.tar.gz servo-338e2ae5206d5270a6feaf7adbb8279fe25040e2.zip |
Auto merge of #18262 - KiChjang:value-sanitization, r=nox
Implement value sanitization on HTMLInputElement
https://html.spec.whatwg.org/multipage/input.html#value-sanitization-algorithm
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18262)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/str.rs | 23 | ||||
-rwxr-xr-x | components/script/dom/htmlinputelement.rs | 36 |
2 files changed, 55 insertions, 4 deletions
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index 60b8d6183be..3667dddf92d 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -185,6 +185,29 @@ impl DOMString { pub fn bytes(&self) -> Bytes { self.0.bytes() } + + /// Removes newline characters according to <https://infra.spec.whatwg.org/#strip-newlines>. + pub fn strip_newlines(&mut self) { + self.0.retain(|c| c != '\r' && c != '\n'); + } + + /// Removes leading and trailing ASCII whitespaces according to + /// <https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace>. + pub fn strip_leading_and_trailing_ascii_whitespace(&mut self) { + if self.0.len() == 0 { return; } + + let last_non_whitespace = match self.0.rfind(|ref c| !char::is_ascii_whitespace(c)) { + Some(idx) => idx + 1, + None => { + self.0.clear(); + return; + } + }; + let first_non_whitespace = self.0.find(|ref c| !char::is_ascii_whitespace(c)).unwrap(); + + self.0.truncate(last_non_whitespace); + let _ = self.0.splice(0..first_non_whitespace, ""); + } } impl Borrow<str> for DOMString { diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 4fd99b289a1..48a6110f503 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -46,11 +46,12 @@ use script_traits::ScriptToConstellationChan; use servo_atoms::Atom; use std::borrow::ToOwned; use std::cell::Cell; +use std::mem; use std::ops::Range; use style::attr::AttrValue; use style::element_state::ElementState; use style::str::split_commas; -use textinput::{SelectionDirection, TextInput}; +use textinput::{Direction, Selection, SelectionDirection, TextInput}; use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction}; use textinput::Lines::Single; @@ -175,7 +176,7 @@ impl HTMLInputElement { .map_or_else(|| atom!(""), |a| a.value().as_atom().to_owned()) } - // https://html.spec.whatwg.org/multipage/#input-type-attr-summary + // https://html.spec.whatwg.org/multipage/#dom-input-value fn value_mode(&self) -> ValueMode { match self.input_type.get() { InputType::InputSubmit | @@ -409,8 +410,17 @@ impl HTMLInputElementMethods for HTMLInputElement { fn SetValue(&self, value: DOMString) -> ErrorResult { match self.value_mode() { ValueMode::Value => { - self.textinput.borrow_mut().set_content(value); + // Steps 1-2. + let old_value = mem::replace(self.textinput.borrow_mut().single_line_content_mut(), value); + // Step 3. self.value_dirty.set(true); + // Step 4. + self.sanitize_value(); + // Step 5. + if *self.textinput.borrow().single_line_content() != old_value { + self.textinput.borrow_mut() + .adjust_horizontal_to_limit(Direction::Forward, Selection::NotSelected); + } } ValueMode::Default | ValueMode::DefaultOn => { @@ -859,6 +869,23 @@ impl HTMLInputElement { target.fire_bubbling_event(atom!("change")); } } + + // https://html.spec.whatwg.org/multipage/#value-sanitization-algorithm + fn sanitize_value(&self) { + match self.type_() { + atom!("text") | atom!("search") | atom!("tel") | atom!("password") => { + self.textinput.borrow_mut().single_line_content_mut().strip_newlines(); + } + atom!("url") => { + let mut textinput = self.textinput.borrow_mut(); + let content = textinput.single_line_content_mut(); + content.strip_newlines(); + content.strip_leading_and_trailing_ascii_whitespace(); + } + // TODO: Implement more value sanitization algorithms for different types of inputs + _ => () + } + } } impl VirtualMethods for HTMLInputElement { @@ -972,7 +999,8 @@ impl VirtualMethods for HTMLInputElement { self.radio_group_name().as_ref()); } - // TODO: Step 6 - value sanitization + // Step 6 + self.sanitize_value(); }, AttributeMutation::Removed => { if self.input_type.get() == InputType::InputRadio { |