diff --git a/crates/formats/src/odt/forms.rs b/crates/formats/src/odt/forms.rs index 794d32ebb5..b04fe6fc46 100644 --- a/crates/formats/src/odt/forms.rs +++ b/crates/formats/src/odt/forms.rs @@ -21,9 +21,23 @@ const MAX_VALUE: usize = 10_000; pub(in crate::odt) const RADIO_ON: char = '\u{25C9}'; pub(in crate::odt) const RADIO_OFF: char = '\u{25CB}'; -/// Form controls WordCraft has no kind for, kept verbatim (see [`ContentControl::form_xml`]). -const KEPT: [&str; 8] = - ["form:button", "form:image", "form:fixed-text", "form:file", "form:value-range", "form:frame", "form:image-frame", "form:generic-control"]; +/// Form controls WordCraft has no kind for, kept verbatim (see [`ContentControl::form_xml`]): +/// every control of ODF 1.3 §13.5 but those it reads (text fields and areas, check boxes, option +/// buttons, list and combo boxes, date fields) and hidden ones (kept apart). +const KEPT: [&str; 12] = [ + "form:button", + "form:image", + "form:fixed-text", + "form:file", + "form:value-range", + "form:frame", + "form:image-frame", + "form:generic-control", + "form:password", + "form:number", + "form:time", + "form:grid", +]; /// Most bytes of a kept control's XML. const MAX_KEPT: usize = 64 * 1024; /// The namespace prefixes a kept control may use: those the content WordCraft writes declares. diff --git a/crates/formats/src/odt/tests_more/forms.rs b/crates/formats/src/odt/tests_more/forms.rs index 39170f56d1..5639332a8c 100644 --- a/crates/formats/src/odt/tests_more/forms.rs +++ b/crates/formats/src/odt/tests_more/forms.rs @@ -221,3 +221,28 @@ fn controls_keep_their_place_on_the_line_and_a_text_area_its_lines() { let plain = entry(&export(&import(&package(&doc_xml(), None)).unwrap()).unwrap(), "content.xml"); assert!(plain.contains(r#"style:vertical-pos="top" style:vertical-rel="baseline""#), "{plain}"); } + +#[test] +fn password_number_time_and_grid_controls_are_kept() { + // ODF 1.3 §13.5 controls WordCraft has no kind for: kept as read, each in its place. + let controls = r#""#; + let anchor = |id: &str| format!(r#""#); + let content = format!( + r#"{controls}Fill {} {} {} {}"#, + anchor("p1"), + anchor("n1"), + anchor("t1"), + anchor("g1") + ); + let saved = export(&import(&package(&content, None)).unwrap()).unwrap(); + let c = entry(&saved, "content.xml"); + for el in [r#"