layout: Implement a non-recursive version of CSS quotes (#34770)

* Squash and don't explicitly use noto-cjk in tests

Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>

* Mark quotes-034.html.ini failure

Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>

* Address review comments

Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>

---------

Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
This commit is contained in:
Xiaocheng Hu 2025-02-28 00:00:21 +08:00 committed by GitHub
parent 31de9c1c21
commit 11f54b9f23
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 536 additions and 229 deletions

View file

@ -15,10 +15,12 @@ use style::dom::{TElement, TShadowRoot};
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
use style::values::generics::counters::{Content, ContentItem};
use style::values::specified::Quotes;
use crate::context::LayoutContext;
use crate::dom::{BoxSlot, LayoutBox, NodeExt};
use crate::fragment_tree::{BaseFragmentInfo, FragmentFlags, Tag};
use crate::quotes::quotes_for_lang;
use crate::replaced::ReplacedContents;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside};
@ -394,6 +396,17 @@ where
})
}
fn get_quote_from_pair<I, S>(item: &ContentItem<I>, opening: &S, closing: &S) -> String
where
S: ToString + ?Sized,
{
match item {
ContentItem::OpenQuote => opening.to_string(),
ContentItem::CloseQuote => closing.to_string(),
_ => unreachable!("Got an unexpected ContentItem type when processing quotes."),
}
}
/// <https://www.w3.org/TR/CSS2/generate.html#propdef-content>
fn generate_pseudo_element_content<'dom, Node>(
pseudo_element_style: &ComputedValues,
@ -449,10 +462,30 @@ where
vec.push(PseudoElementContentItem::Replaced(replaced_content));
}
},
ContentItem::OpenQuote | ContentItem::CloseQuote => {
// TODO(xiaochengh): calculate quote depth
let maybe_quote = match &pseudo_element_style.get_list().quotes {
Quotes::QuoteList(quote_list) => {
quote_list.0.first().map(|quote_pair| {
get_quote_from_pair(
item,
&*quote_pair.opening,
&*quote_pair.closing,
)
})
},
Quotes::Auto => {
let lang = &pseudo_element_style.get_font()._x_lang;
let quotes = quotes_for_lang(lang.0.as_ref(), 0);
Some(get_quote_from_pair(item, &quotes.opening, &quotes.closing))
},
};
if let Some(quote) = maybe_quote {
vec.push(PseudoElementContentItem::Text(quote));
}
},
ContentItem::Counter(_, _) |
ContentItem::Counters(_, _, _) |
ContentItem::OpenQuote |
ContentItem::CloseQuote |
ContentItem::NoOpenQuote |
ContentItem::NoCloseQuote => {
// TODO: Add support for counters and quotes.