зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #19385 - implement "Date type inputs", "Month type inputs" (from tigercosmos:b1); r=KiChjang
<!-- Please describe your changes on the following line: --> implement "Date type inputs", "Month type inputs" --- <!-- 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] `./mach test-unit` does not report any errors Source-Repo: https://github.com/servo/servo Source-Revision: 68cefb1b0031c05c7f2f4aa433eb1a21e7863f8f --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 1cadc19ec7e70ded4bb31329408a5d89311d9919
This commit is contained in:
Родитель
bdd3f2c5da
Коммит
b73dbbfaea
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -875,6 +875,18 @@ impl HTMLInputElement {
|
|||
content.strip_newlines();
|
||||
content.strip_leading_and_trailing_ascii_whitespace();
|
||||
}
|
||||
atom!("date") => {
|
||||
let mut textinput = self.textinput.borrow_mut();
|
||||
if !textinput.single_line_content().is_valid_date_string() {
|
||||
*textinput.single_line_content_mut() = "".into();
|
||||
}
|
||||
}
|
||||
atom!("month") => {
|
||||
let mut textinput = self.textinput.borrow_mut();
|
||||
if !textinput.single_line_content().is_valid_month_string() {
|
||||
*textinput.single_line_content_mut() = "".into();
|
||||
}
|
||||
}
|
||||
atom!("color") => {
|
||||
let mut textinput = self.textinput.borrow_mut();
|
||||
|
||||
|
@ -1042,6 +1054,7 @@ impl VirtualMethods for HTMLInputElement {
|
|||
let value = mutation.new_value(attr).map(|value| (**value).to_owned());
|
||||
self.textinput.borrow_mut().set_content(
|
||||
value.map_or(DOMString::new(), DOMString::from));
|
||||
self.sanitize_value();
|
||||
self.update_placeholder_shown_state();
|
||||
},
|
||||
&local_name!("name") if self.input_type.get() == InputType::InputRadio => {
|
||||
|
@ -1117,7 +1130,6 @@ impl VirtualMethods for HTMLInputElement {
|
|||
if let Some(ref s) = self.super_type() {
|
||||
s.bind_to_tree(tree_in_doc);
|
||||
}
|
||||
|
||||
self.upcast::<Element>().check_ancestors_disabled_state_for_form_control();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче