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 <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye 2025-06-16 22:12:07 +08:00 committed by GitHub
parent 910cc0b687
commit f60e9cdff5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 87 additions and 16 deletions

View file

@ -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());

View file

@ -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:
// a<span style="text-transform: capitalize">b</span>c
if TextTransformCase::Capitalize == text_transform {
transformed_text = capitalize_string(&transformed_text, true);
}
let is_preformatted_element =
white_space_collapse == WhiteSpaceCollapseValue::Preserve;