mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 20:01:43 +00:00
SVG classes: split on ASCII whitespace only, keep class names that are not XML names
This commit is contained in:
@@ -637,7 +637,7 @@ impl Writer<'_> {
|
||||
.map_or(&[][..], |a| a.classes.as_slice())
|
||||
.iter()
|
||||
.map(String::as_str)
|
||||
.filter(|c| !c.is_empty() && c.chars().all(xml_name_char))
|
||||
.filter(|c| !c.is_empty() && !c.chars().any(|ch| ch.is_control() || matches!(ch, '\u{fffe}' | '\u{ffff}')))
|
||||
.collect();
|
||||
if !classes.is_empty() && !self.tiny() {
|
||||
out.push_str(&format!(" class=\"{}\"", xml_attr_escape(&classes.join(" "))));
|
||||
|
||||
@@ -718,11 +718,12 @@ type Extras = (Vec<(String, String)>, Vec<String>);
|
||||
const MAX_CLASSES: usize = 64;
|
||||
|
||||
/// The CSS classes of element `e`, in order and without repeats. Classes our own export
|
||||
/// generated (`cls-1`, with or without a prefix) aren't kept: export makes them again.
|
||||
/// generated (`cls-1`, with or without a prefix) aren't kept: export makes them again. A class list
|
||||
/// is split on SVG's five ASCII whitespace characters only, so a no-break space stays inside a name.
|
||||
fn user_classes(e: XNode) -> Vec<String> {
|
||||
let generated = |c: &str| c.rsplit_once("cls-").is_some_and(|(_, n)| !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()));
|
||||
let mut out: Vec<String> = Vec::new();
|
||||
for c in e.attribute("class").into_iter().flat_map(str::split_whitespace) {
|
||||
for c in e.attribute("class").into_iter().flat_map(|v| v.split(['\u{20}', '\t', '\n', '\u{c}', '\r']).filter(|c| !c.is_empty())) {
|
||||
if out.len() < MAX_CLASSES && !generated(c) && !out.iter().any(|k| k == c) {
|
||||
out.push(c.to_string());
|
||||
}
|
||||
|
||||
@@ -29,3 +29,10 @@ fn imported_classes_survive_every_styling_with_generated_ones() {
|
||||
assert_eq!(class_of(&again, "r"), Some(rect), "{styling:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn class_names_with_colons_slashes_and_no_break_spaces_are_kept() {
|
||||
let src = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\"><rect id=\"r\" class=\"hover:bg-blue w-1/2 a\u{a0}b\" width=\"5\" height=\"5\" fill=\"red\"/></svg>";
|
||||
let out = export(&import(src).unwrap(), &ExportOptions::default());
|
||||
assert_eq!(class_of(&out, "r").as_deref(), Some("hover:bg-blue w-1/2 a\u{a0}b"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user