aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-11-09 18:35:07 -0600
committerGitHub <noreply@github.com>2017-11-09 18:35:07 -0600
commit338e2ae5206d5270a6feaf7adbb8279fe25040e2 (patch)
tree541f64241b2f7f25f50866e92fca650227437808 /components/script/dom
parenta1331169f6113440de37cade877ae799f72e4053 (diff)
parent8203605c043cc402e6264cf04e44758fcc7426a1 (diff)
downloadservo-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.rs23
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs36
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 {