aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/str.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-12-04 15:44:58 -0600
committerGitHub <noreply@github.com>2017-12-04 15:44:58 -0600
commiteed3adc957fb3c52de24c560112533963572f525 (patch)
tree75c12b3c2bf9bfb9ad9ec467ef36ed10620a9ddc /components/script/dom/bindings/str.rs
parent221d72a81ed9300e260d33d2d2d6557b5a118fac (diff)
parenta999239f28672aed053c9c3db001a2e6a26efa7f (diff)
downloadservo-eed3adc957fb3c52de24c560112533963572f525.tar.gz
servo-eed3adc957fb3c52de24c560112533963572f525.zip
Auto merge of #19379 - SWW13:htmlinput_sanitize_time, r=KiChjang
Implemented sanitize_value for time input Implemented value sanitization for `<input type=time/>`. The value has the be valid time string (https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-time-string) or set to empty string. --- The following test results look expected to me, but I'm not sure: ``` ▶ Unexpected subtest result in /html/semantics/forms/the-input-element/type-change-state.html: │ FAIL [expected PASS] change state from time to text │ → assert_equals: input.value should be foobar after change of state expected " foobar " but got "" │ FAIL [expected PASS] change state from time to search │ → assert_equals: input.value should be foobar after change of state expected " foobar " but got "" │ FAIL [expected PASS] change state from time to tel │ → assert_equals: input.value should be foobar after change of state expected " foobar " but got "" │ FAIL [expected PASS] change state from time to url │ → assert_equals: input.value should be foobar after change of state expected "foobar" but got "" │ FAIL [expected PASS] change state from time to password │ → assert_equals: input.value should be foobar after change of state expected " foobar " but got "" │ │ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:53:15 │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1489:20 │ test@http://web-platform.test:8000/resources/testharness.js:511:9 └ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:37:9 ▶ Unexpected subtest result in /html/semantics/forms/the-input-element/type-change-state.html: │ FAIL [expected PASS] change state from color to time │ → assert_equals: input.value should be #000000 after change of state expected "#000000" but got "" │ │ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:55:15 │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1489:20 │ test@http://web-platform.test:8000/resources/testharness.js:511:9 └ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:37:9 ``` All other tests do now `PASS` instead of `FAIL`. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix *part of* #19172 - [x] There are tests for these changes - [x] All tests `PASS` <!-- 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/19379) <!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/bindings/str.rs')
-rw-r--r--components/script/dom/bindings/str.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs
index 3667dddf92d..6601d8e6856 100644
--- a/components/script/dom/bindings/str.rs
+++ b/components/script/dom/bindings/str.rs
@@ -208,6 +208,77 @@ impl DOMString {
self.0.truncate(last_non_whitespace);
let _ = self.0.splice(0..first_non_whitespace, "");
}
+
+ /// Validates this `DOMString` is a time string according to
+ /// <https://html.spec.whatwg.org/multipage/#valid-time-string>.
+ pub fn is_valid_time_string(&self) -> bool {
+ enum State {
+ HourHigh,
+ HourLow09,
+ HourLow03,
+ MinuteColon,
+ MinuteHigh,
+ MinuteLow,
+ SecondColon,
+ SecondHigh,
+ SecondLow,
+ MilliStop,
+ MilliHigh,
+ MilliMiddle,
+ MilliLow,
+ Done,
+ Error,
+ }
+ let next_state = |valid: bool, next: State| -> State { if valid { next } else { State::Error } };
+
+ let state = self.chars().fold(State::HourHigh, |state, c| {
+ match state {
+ // Step 1 "HH"
+ State::HourHigh => {
+ match c {
+ '0' | '1' => State::HourLow09,
+ '2' => State::HourLow03,
+ _ => State::Error,
+ }
+ },
+ State::HourLow09 => next_state(c.is_digit(10), State::MinuteColon),
+ State::HourLow03 => next_state(c.is_digit(4), State::MinuteColon),
+
+ // Step 2 ":"
+ State::MinuteColon => next_state(c == ':', State::MinuteHigh),
+
+ // Step 3 "mm"
+ State::MinuteHigh => next_state(c.is_digit(6), State::MinuteLow),
+ State::MinuteLow => next_state(c.is_digit(10), State::SecondColon),
+
+ // Step 4.1 ":"
+ State::SecondColon => next_state(c == ':', State::SecondHigh),
+ // Step 4.2 "ss"
+ State::SecondHigh => next_state(c.is_digit(6), State::SecondLow),
+ State::SecondLow => next_state(c.is_digit(10), State::MilliStop),
+
+ // Step 4.3.1 "."
+ State::MilliStop => next_state(c == '.', State::MilliHigh),
+ // Step 4.3.2 "SSS"
+ State::MilliHigh => next_state(c.is_digit(6), State::MilliMiddle),
+ State::MilliMiddle => next_state(c.is_digit(10), State::MilliLow),
+ State::MilliLow => next_state(c.is_digit(10), State::Done),
+
+ _ => State::Error,
+ }
+ });
+
+ match state {
+ State::Done |
+ // Step 4 (optional)
+ State::SecondColon |
+ // Step 4.3 (optional)
+ State::MilliStop |
+ // Step 4.3.2 (only 1 digit required)
+ State::MilliMiddle | State::MilliLow => true,
+ _ => false
+ }
+ }
}
impl Borrow<str> for DOMString {