render: apply text transforms to UI word leaves

This commit is contained in:
SGavrl committed 2026-07-26 15:52:29 +00:00
1 parent 058e3e98a0
commit bc13488df9
1 file changed
+54
+54
View File
@@ -2727,16 +2727,45 @@ fn build_text_words(
let mut fsize = 16.0;
let mut is_bold = false;
let mut transform = crate::TextTransform::None;
if let Some(parent_id) = node.parent {
if let Some(p_style) = styles.get(&parent_id) {
fsize = p_style.font_size.unwrap_or(16.0);
is_bold = p_style.font_weight.as_deref() == Some("bold");
transform = p_style
.text_transform
.unwrap_or(crate::TextTransform::None);
}
}
display_text = transform_word_leaf_text(&display_text, transform);
build_word_leaves(id, &display_text, fsize, is_bold, taffy_tree, words)
}
fn transform_word_leaf_text(text: &str, transform: crate::TextTransform) -> String {
match transform {
crate::TextTransform::None => text.to_string(),
crate::TextTransform::Uppercase => text.chars().flat_map(char::to_uppercase).collect(),
crate::TextTransform::Lowercase => text.chars().flat_map(char::to_lowercase).collect(),
crate::TextTransform::Capitalize => {
let mut at_word_start = true;
let mut out = String::with_capacity(text.len());
for ch in text.chars() {
if ch.is_whitespace() {
at_word_start = true;
out.push(ch);
} else if at_word_start {
out.extend(ch.to_uppercase());
at_word_start = false;
} else {
out.push(ch);
}
}
out
}
}
}
/// Split `text` into one taffy leaf per word and register each against
/// `source_id` in `words`. Shared by `build_text_words` (a real DOM text
/// node) and `build_pseudo_content` (a `::before`/`::after` literal, which
@@ -4784,6 +4813,31 @@ mod tests {
assert_eq!(laid.rects.get(&b).unwrap().y, 50.0);
}
#[test]
fn text_transform_applies_to_word_leaves_in_flex_ui() {
let tree = parse_html(
r#"<div id="cta" style="display:flex;text-transform:uppercase">get started</div>"#,
);
let text = tree
.descendants(tree.document())
.into_iter()
.find(|id| tree.get_node(*id).is_some_and(|node| node.is_text()))
.unwrap();
let laid = layout_dom(&tree, (1280.0, 720.0));
let painted = laid
.text_runs
.get(&text)
.unwrap()
.iter()
.map(|(_, word)| word.as_str())
.collect::<String>();
assert_eq!(painted, "GET STARTED");
assert_eq!(
transform_word_leaf_text("hELLO wORLD", crate::TextTransform::Capitalize),
"HELLO WORLD"
);
}
#[test]
fn table_cell_content_box_width_includes_padding_and_border_in_track() {
let tree = parse_html(