use style::counter_style::{CounterStyle, Symbol, SymbolsType};
use style::properties::longhands::list_style_type::computed_value::T as ListStyleType;
use style::values::computed::Image;
use style::values::generics::counters::Content;
use stylo_atoms::atom;
use crate::context::LayoutContext;
use crate::dom_traversal::{
NodeAndStyleInfo, PseudoElementContentItem, generate_pseudo_element_content,
};
use crate::replaced::ReplacedContents;
pub(crate) fn make_marker<'dom>(
context: &LayoutContext,
info: &NodeAndStyleInfo<'dom>,
) -> Option<(NodeAndStyleInfo<'dom>, Vec<PseudoElementContentItem>)> {
let marker_info =
info.with_pseudo_element(context, style::selector_parser::PseudoElement::Marker)?;
let style = &marker_info.style;
let list_style = style.get_list();
let marker_image = || match &list_style.list_style_image {
Image::Url(url) => Some(vec![
PseudoElementContentItem::Replaced(ReplacedContents::from_image_url(
marker_info.node,
context,
url,
)?),
PseudoElementContentItem::Text(" ".into()),
]),
Image::ImageSet(..) |
Image::Gradient(..) |
Image::CrossFade(..) |
Image::PaintWorklet(..) |
Image::None => None,
Image::LightDark(..) => unreachable!("light-dark() should be disabled"),
};
let content = match &marker_info.style.get_counters().content {
Content::Items(_) => generate_pseudo_element_content(&marker_info, context),
Content::None => return None,
Content::Normal => marker_image().or_else(|| {
Some(vec![PseudoElementContentItem::Text(marker_string(
&list_style.list_style_type,
)?)])
})?,
};
Some((marker_info, content))
}
fn symbol_to_string(symbol: &Symbol) -> &str {
match symbol {
Symbol::String(string) => string,
Symbol::Ident(ident) => &ident.0,
}
}
pub(crate) fn generate_counter_representation(counter_style: &CounterStyle) -> &str {
match counter_style {
CounterStyle::None | CounterStyle::String(_) => unreachable!("Invalid counter style"),
CounterStyle::Name(name) => match name.0 {
atom!("disc") => "\u{2022}",
atom!("circle") => "\u{25E6}",
atom!("square") => "\u{25AA}",
atom!("disclosure-open") => "\u{25BE}",
atom!("disclosure-closed") => "\u{25B8}",
atom!("decimal-leading-zero") => "00",
atom!("arabic-indic") => "\u{660}",
atom!("bengali") => "\u{9E6}",
atom!("cambodian") | atom!("khmer") => "\u{17E0}",
atom!("devanagari") => "\u{966}",
atom!("gujarati") => "\u{AE6}",
atom!("gurmukhi") => "\u{A66}",
atom!("kannada") => "\u{CE6}",
atom!("lao") => "\u{ED0}",
atom!("malayalam") => "\u{D66}",
atom!("mongolian") => "\u{1810}",
atom!("myanmar") => "\u{1040}",
atom!("oriya") => "\u{B66}",
atom!("persian") => "\u{6F0}",
atom!("tamil") => "\u{BE6}",
atom!("telugu") => "\u{C66}",
atom!("thai") => "\u{E50}",
atom!("tibetan") => "\u{F20}",
atom!("cjk-decimal") |
atom!("cjk-earthly-branch") |
atom!("cjk-heavenly-stem") |
atom!("japanese-informal") => "\u{3007}",
atom!("korean-hangul-formal") => "\u{C601}",
atom!("korean-hanja-informal") |
atom!("korean-hanja-formal") |
atom!("japanese-formal") |
atom!("simp-chinese-informal") |
atom!("simp-chinese-formal") |
atom!("trad-chinese-informal") |
atom!("trad-chinese-formal") |
atom!("cjk-ideographic") => "\u{96F6}",
_ => "0",
},
CounterStyle::Symbols { ty, symbols } => match ty {
SymbolsType::Numeric => {
symbol_to_string(symbols.0.first().expect("symbols() should have symbols"))
},
SymbolsType::Cyclic => {
symbol_to_string(symbols.0.last().expect("symbols() should have symbols"))
},
SymbolsType::Alphabetic | SymbolsType::Symbolic | SymbolsType::Fixed => "0",
},
}
}
pub(crate) fn marker_string(list_style_type: &ListStyleType) -> Option<String> {
let suffix = match &list_style_type.0 {
CounterStyle::None => return None,
CounterStyle::String(string) => return Some(string.to_string()),
CounterStyle::Name(name) => match name.0 {
atom!("disc") |
atom!("circle") |
atom!("square") |
atom!("disclosure-open") |
atom!("disclosure-closed") => " ",
atom!("hiragana") |
atom!("hiragana-iroha") |
atom!("katakana") |
atom!("katakana-iroha") |
atom!("cjk-decimal") |
atom!("cjk-earthly-branch") |
atom!("cjk-heavenly-stem") |
atom!("japanese-informal") |
atom!("japanese-formal") |
atom!("simp-chinese-informal") |
atom!("simp-chinese-formal") |
atom!("trad-chinese-informal") |
atom!("trad-chinese-formal") |
atom!("cjk-ideographic") => "\u{3001}",
atom!("korean-hangul-formal") |
atom!("korean-hanja-informal") |
atom!("korean-hanja-formal") => ", ",
atom!("ethiopic-numeric") => "/ ",
_ => ". ",
},
CounterStyle::Symbols { .. } => " ",
};
Some(generate_counter_representation(&list_style_type.0).to_string() + suffix)
}