mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #19559 - tigercosmos:t1, r=KiChjang
implement valid week string <!-- Please describe your changes on the following line: --> implement valid week string part of #19172 r? @KiChjang --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [x] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- 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/19559) <!-- Reviewable:end -->
This commit is contained in:
commit
8798e49889
11 changed files with 103 additions and 128 deletions
|
@ -39,6 +39,7 @@ byteorder = "1.0"
|
|||
canvas_traits = {path = "../canvas_traits"}
|
||||
caseless = "0.1.0"
|
||||
cookie = "0.10"
|
||||
chrono = "0.4"
|
||||
cssparser = "0.23.0"
|
||||
deny_public_fields = {path = "../deny_public_fields"}
|
||||
devtools_traits = {path = "../devtools_traits"}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
//! The `ByteString` struct.
|
||||
|
||||
use chrono::{Datelike, TimeZone};
|
||||
use chrono::prelude::{Weekday, Utc};
|
||||
use cssparser::CowRcStr;
|
||||
use html5ever::{LocalName, Namespace};
|
||||
use servo_atoms::Atom;
|
||||
|
@ -293,6 +295,13 @@ impl DOMString {
|
|||
pub fn is_valid_month_string(&self) -> bool {
|
||||
parse_month_string(&*self.0).is_ok()
|
||||
}
|
||||
|
||||
/// A valid week string should be like {YYYY}-W{WW}, such as "2017-W52"
|
||||
/// YYYY must be four or more digits, WW both must be two digits
|
||||
/// https://html.spec.whatwg.org/multipage/#valid-week-string
|
||||
pub fn is_valid_week_string(&self) -> bool {
|
||||
parse_week_string(&*self.0).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for DOMString {
|
||||
|
@ -445,6 +454,48 @@ fn parse_date_string(value: &str) -> Result<(u32, u32, u32), ()> {
|
|||
Ok((year_int, month_int, day_int))
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#parse-a-week-string
|
||||
fn parse_week_string(value: &str) -> Result<(u32, u32), ()> {
|
||||
// Step 1, 2, 3
|
||||
let mut iterator = value.split('-');
|
||||
let year = iterator.next().ok_or(())?;
|
||||
|
||||
// Step 4
|
||||
let year_int = year.parse::<u32>().map_err(|_| ())?;
|
||||
if year.len() < 4 || year_int == 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Step 5, 6
|
||||
let week = iterator.next().ok_or(())?;
|
||||
let (week_first, week_last) = week.split_at(1);
|
||||
if week_first != "W" {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Step 7
|
||||
let week_int = week_last.parse::<u32>().map_err(|_| ())?;
|
||||
if week_last.len() != 2 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Step 8
|
||||
let max_week = max_week_in_year(year_int);
|
||||
|
||||
// Step 9
|
||||
if week_int < 1 || week_int > max_week {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Step 10
|
||||
if iterator.next().is_some() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Step 11
|
||||
Ok((year_int, week_int))
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#parse-a-month-component
|
||||
fn parse_month_component(value: &str) -> Result<(u32, u32), ()> {
|
||||
// Step 3
|
||||
|
@ -495,7 +546,7 @@ fn max_day_in_month(year_num: u32, month_num: u32) -> Result<u32, ()> {
|
|||
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) {
|
||||
if is_leap_year(year_num) {
|
||||
Ok(29)
|
||||
} else {
|
||||
Ok(28)
|
||||
|
@ -504,3 +555,17 @@ fn max_day_in_month(year_num: u32, month_num: u32) -> Result<u32, ()> {
|
|||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#week-number-of-the-last-day
|
||||
fn max_week_in_year(year: u32) -> u32 {
|
||||
match Utc.ymd(year as i32, 1, 1).weekday() {
|
||||
Weekday::Thu => 53,
|
||||
Weekday::Wed if is_leap_year(year) => 53,
|
||||
_ => 52
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_leap_year(year: u32) -> bool {
|
||||
year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
|
||||
}
|
||||
|
|
|
@ -1005,6 +1005,12 @@ impl HTMLInputElement {
|
|||
*textinput.single_line_content_mut() = "".into();
|
||||
}
|
||||
}
|
||||
InputType::Week => {
|
||||
let mut textinput = self.textinput.borrow_mut();
|
||||
if !textinput.single_line_content().is_valid_week_string() {
|
||||
*textinput.single_line_content_mut() = "".into();
|
||||
}
|
||||
}
|
||||
InputType::Color => {
|
||||
let mut textinput = self.textinput.borrow_mut();
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ extern crate bluetooth_traits;
|
|||
extern crate byteorder;
|
||||
extern crate canvas_traits;
|
||||
extern crate caseless;
|
||||
extern crate chrono;
|
||||
extern crate cookie as cookie_rs;
|
||||
#[macro_use] extern crate cssparser;
|
||||
#[macro_use] extern crate deny_public_fields;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue