From f60e9cdff5e9e7f78e3f3a022638d3e279909eba Mon Sep 17 00:00:00 2001 From: Euclid Ye Date: Mon, 16 Jun 2025 22:12:07 +0800 Subject: [PATCH] layout: capitalize string for `TextTransformCase::Capitalize` in `fn rendered_text_collection_steps` (#37486) Previously, `rendered_text_collection_steps` ignores `TextTransformCase::Capitalize` due to limitation of iterator. Now we handle the case outside. Testing: Added a new test as not covered by existing wpt-test, except for the indirectly related WebDriver test. `./mach test-wpt -r tests\wpt\tests\webdriver\tests\classic\get_element_text\get.py --product servodriver` Fixes: #37469 --------- Signed-off-by: Euclid Ye --- components/layout/flow/inline/construct.rs | 2 +- components/layout/query.rs | 19 ++++-- tests/wpt/meta/MANIFEST.json | 7 +++ .../text-transform-capitalize-036.html.ini | 3 + .../tests/classic/get_element_text/get.py.ini | 9 --- .../text-transform-capitalize-036.html | 63 +++++++++++++++++++ 6 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 tests/wpt/meta/css/css-text/text-transform/text-transform-capitalize-036.html.ini create mode 100644 tests/wpt/tests/css/css-text/text-transform/text-transform-capitalize-036.html diff --git a/components/layout/flow/inline/construct.rs b/components/layout/flow/inline/construct.rs index 07a2e914835..5acc10754fc 100644 --- a/components/layout/flow/inline/construct.rs +++ b/components/layout/flow/inline/construct.rs @@ -672,7 +672,7 @@ where /// Given a string and whether the start of the string represents a word boundary, create a copy of /// the string with letters after word boundaries capitalized. -fn capitalize_string(string: &str, allow_word_at_start: bool) -> String { +pub(crate) fn capitalize_string(string: &str, allow_word_at_start: bool) -> String { let mut output_string = String::new(); output_string.reserve(string.len()); diff --git a/components/layout/query.rs b/components/layout/query.rs index 137b6fc382d..21f43a34fd7 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -37,11 +37,12 @@ use style::values::generics::font::LineHeight; use style::values::generics::position::AspectRatio; use style::values::specified::GenericGridTemplateComponent; use style::values::specified::box_::DisplayInside; +use style::values::specified::text::TextTransformCase; use style_traits::{ParsingMode, ToCss}; use crate::ArcRefCell; use crate::dom::NodeExt; -use crate::flow::inline::construct::{TextTransformation, WhitespaceCollapse}; +use crate::flow::inline::construct::{TextTransformation, WhitespaceCollapse, capitalize_string}; use crate::fragment_tree::{ BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, }; @@ -777,11 +778,17 @@ fn rendered_text_collection_steps( // rules are slightly modified: collapsible spaces at the end of lines are always // collapsed, but they are only removed if the line is the last line of the block, // or it ends with a br element. Soft hyphens should be preserved. - let mut transformed_text: String = TextTransformation::new( - with_white_space_rules_applied, - style.clone_text_transform().case(), - ) - .collect(); + let text_transform = style.clone_text_transform().case(); + let mut transformed_text: String = + TextTransformation::new(with_white_space_rules_applied, text_transform) + .collect(); + + // Since iterator for capitalize not doing anything, we must handle it outside here + // FIXME: This assumes the element always start at a word boundary. But can fail: + // abc + if TextTransformCase::Capitalize == text_transform { + transformed_text = capitalize_string(&transformed_text, true); + } let is_preformatted_element = white_space_collapse == WhiteSpaceCollapseValue::Preserve; diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index f8c1e66bcbb..f715cdecbcb 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -612692,6 +612692,13 @@ ] ] }, + "text-transform-capitalize-036.html": [ + "a47dc35b949b56c734a0090c9c7a4932c745c4cf", + [ + null, + {} + ] + ], "text-transform-upperlower-107.html": [ "791edd14c0e144a945b4766a338725bca13da6bd", [ diff --git a/tests/wpt/meta/css/css-text/text-transform/text-transform-capitalize-036.html.ini b/tests/wpt/meta/css/css-text/text-transform/text-transform-capitalize-036.html.ini new file mode 100644 index 00000000000..72cc1d164fb --- /dev/null +++ b/tests/wpt/meta/css/css-text/text-transform/text-transform-capitalize-036.html.ini @@ -0,0 +1,3 @@ +[text-transform-capitalize-036.html] + [text-transform: capitalize test for not starting at word boundary] + expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini index b4016ed5298..a67074542e0 100644 --- a/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini @@ -5,15 +5,6 @@ [test_no_such_element_with_shadow_root] expected: FAIL - [test_transform_capitalize[space\]] - expected: FAIL - - [test_transform_capitalize[dash\]] - expected: FAIL - - [test_transform_capitalize[underscore\]] - expected: FAIL - [test_shadow_root_slot[custom outside\]] expected: FAIL diff --git a/tests/wpt/tests/css/css-text/text-transform/text-transform-capitalize-036.html b/tests/wpt/tests/css/css-text/text-transform/text-transform-capitalize-036.html new file mode 100644 index 00000000000..a47dc35b949 --- /dev/null +++ b/tests/wpt/tests/css/css-text/text-transform/text-transform-capitalize-036.html @@ -0,0 +1,63 @@ + + + + + text-transform: capitalize innerText WPT tests + + + + + + +
hello world
+
foo-bar
+
john's apple
+ +
+ hello world +
+
foo_bar
+ + abc + + + + \ No newline at end of file