diff --git a/moli-dom/src/native/element/mod.rs b/moli-dom/src/native/element/mod.rs index 443f518d93..be1955cf41 100644 --- a/moli-dom/src/native/element/mod.rs +++ b/moli-dom/src/native/element/mod.rs @@ -591,10 +591,7 @@ impl Element { } pub(crate) fn resanitize_input_value_after_parser_attributes(&mut self) -> bool { - if !self.is_html_input() - || self.input_type() != InputType::Range - || self.input_value_dirty() - { + if !self.is_html_input() || self.input_value_dirty() { return false; } let source = self.attribute("value").unwrap_or_default().to_owned(); diff --git a/moli-dom/src/native/element/tests.rs b/moli-dom/src/native/element/tests.rs index 18334fa9fd..f6b0e6ba0a 100644 --- a/moli-dom/src/native/element/tests.rs +++ b/moli-dom/src/native/element/tests.rs @@ -501,3 +501,17 @@ fn range_value_setters_use_element_bounds_and_step_authority() { input.set_input_value("180.25"); assert_eq!(input.input_value(), "180.25"); } + +#[test] +fn parser_input_finalization_preserves_dirty_values_and_skips_other_elements() { + let mut input = Element::new_html("input"); + input.set_attribute("type".into(), String::new(), None, "hidden".into()); + input.set_attribute("value".into(), String::new(), None, "default".into()); + input.set_input_value(" edited\nvalue "); + assert!(!input.resanitize_input_value_after_parser_attributes()); + assert_eq!(input.input_value(), " edited\nvalue "); + assert!(input.input_value_dirty()); + let mut div = Element::new_html("div"); + assert!(!div.resanitize_input_value_after_parser_attributes()); + assert!(!div.rare_data.is_materialized()); +} diff --git a/moli-dom/src/native/host/parser.rs b/moli-dom/src/native/host/parser.rs index 977fec179e..af9192c753 100644 --- a/moli-dom/src/native/host/parser.rs +++ b/moli-dom/src/native/host/parser.rs @@ -274,6 +274,41 @@ mod tests { assert_eq!(host.get_attribute(element, "id").as_deref(), Some("card")); } + #[test] + fn parser_input_default_values_do_not_depend_on_attribute_order() { + for kind in ["hidden", "button", "submit", "reset", "checkbox", "radio"] { + for value_first in [true, false] { + let mut host = test_host(); + let input = host.create_parser_element_without_attributes( + "input".to_owned(), + "http://www.w3.org/1999/xhtml".to_owned(), + None, + ); + let mut attrs = vec![ + Attribute::new( + "value".to_owned(), + String::new(), + None, + " first\nsecond ".to_owned(), + ), + Attribute::new("type".to_owned(), String::new(), None, kind.to_owned()), + ]; + if !value_first { + attrs.reverse(); + } + host.add_attrs_if_missing_for_parser(input, attrs); + let element = host.node(input).and_then(Node::as_element).unwrap(); + assert_eq!( + element.input_value(), + " first\nsecond ", + "{kind}, value_first={value_first}" + ); + assert!(!element.input_value_dirty()); + assert_eq!(element.attribute("value"), Some(" first\nsecond ")); + } + } + } + #[test] fn parser_input_value_sanitization_observes_the_complete_token_attribute_set() { let mut host = test_host();