diff options
author | tigercosmos <phy.tiger@gmail.com> | 2017-11-25 22:57:50 +0800 |
---|---|---|
committer | tigercosmos <phy.tiger@gmail.com> | 2017-12-05 09:44:51 +0800 |
commit | 927fd1d0444d519f514a58407395ea8d5df295a3 (patch) | |
tree | b1afa66bb699679e3cf344ff8fe893b13f833546 /components/script/dom/bindings/str.rs | |
parent | eed3adc957fb3c52de24c560112533963572f525 (diff) | |
download | servo-927fd1d0444d519f514a58407395ea8d5df295a3.tar.gz servo-927fd1d0444d519f514a58407395ea8d5df295a3.zip |
implement "Date type inputs", "Month type inputs"
Diffstat (limited to 'components/script/dom/bindings/str.rs')
-rw-r--r-- | components/script/dom/bindings/str.rs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index 6601d8e6856..596b2db14b2 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -279,6 +279,20 @@ impl DOMString { _ => false } } + + /// A valid date string should be "YYYY-MM-DD" + /// YYYY must be four or more digits, MM and DD both must be two digits + /// https://html.spec.whatwg.org/multipage/#valid-date-string + pub fn is_valid_date_string(&self) -> bool { + parse_date_string(&*self.0).is_ok() + } + + /// A valid month string should be "YYYY-MM" + /// YYYY must be four or more digits, MM both must be two digits + /// https://html.spec.whatwg.org/multipage/#valid-month-string + pub fn is_valid_month_string(&self) -> bool { + parse_month_string(&*self.0).is_ok() + } } impl Borrow<str> for DOMString { @@ -403,3 +417,90 @@ impl Extend<char> for DOMString { self.0.extend(iterable) } } + +/// https://html.spec.whatwg.org/multipage/#parse-a-month-string +fn parse_month_string(value: &str) -> Result<(u32, u32), ()> { + // Step 1, 2, 3 + let (year_int, month_int) = parse_month_component(value)?; + + // Step 4 + if value.split("-").nth(2).is_some() { + return Err(()); + } + // Step 5 + Ok((year_int, month_int)) +} + +/// https://html.spec.whatwg.org/multipage/#parse-a-date-string +fn parse_date_string(value: &str) -> Result<(u32, u32, u32), ()> { + // Step 1, 2, 3 + let (year_int, month_int, day_int) = parse_date_component(value)?; + + // Step 4 + if value.split('-').nth(3).is_some() { + return Err(()); + } + + // Step 5, 6 + Ok((year_int, month_int, day_int)) +} + +/// https://html.spec.whatwg.org/multipage/#parse-a-month-component +fn parse_month_component(value: &str) -> Result<(u32, u32), ()> { + // Step 3 + let mut iterator = value.split('-'); + let year = iterator.next().ok_or(())?; + let month = iterator.next().ok_or(())?; + + // Step 1, 2 + let year_int = year.parse::<u32>().map_err(|_| ())?; + if year.len() < 4 || year_int == 0 { + return Err(()); + } + + // Step 4, 5 + let month_int = month.parse::<u32>().map_err(|_| ())?; + if month.len() != 2 || month_int > 12 || month_int < 1 { + return Err(()); + } + + // Step 6 + Ok((year_int, month_int)) +} + +/// https://html.spec.whatwg.org/multipage/#parse-a-date-component +fn parse_date_component(value: &str) -> Result<(u32, u32, u32), ()> { + // Step 1 + let (year_int, month_int) = parse_month_component(value)?; + + // Step 3, 4 + let day = value.split('-').nth(2).ok_or(())?; + let day_int = day.parse::<u32>().map_err(|_| ())?; + if day.len() != 2 { + return Err(()); + } + + // Step 2, 5 + let max_day = max_day_in_month(year_int, month_int)?; + if day_int == 0 || day_int > max_day { + return Err(()); + } + + // Step 6 + Ok((year_int, month_int, day_int)) +} + +fn max_day_in_month(year_num: u32, month_num: u32) -> Result<u32, ()> { + match month_num { + 1|3|5|7|8|10|12 => Ok(31), + 4|6|9|11 => Ok(30), + 2 => { + if year_num % 400 == 0 || (year_num % 4 == 0 && year_num % 100 != 0) { + Ok(29) + } else { + Ok(28) + } + }, + _ => Err(()) + } +} |