Make ContentItem use a CustomIdent for counter names

See https://github.com/w3c/csswg-drafts/pull/2377
This commit is contained in:
Anthony Ramine 2018-03-01 12:38:02 +01:00
parent 1df6c97948
commit a4d3a8d74a
6 changed files with 74 additions and 26 deletions

View file

@ -188,9 +188,9 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
counter_style)) => { counter_style)) => {
let temporary_counter = Counter::new(); let temporary_counter = Counter::new();
let counter = self.traversal let counter = self.traversal
.counters .counters
.get(&**counter_name) .get(&*counter_name.0)
.unwrap_or(&temporary_counter); .unwrap_or(&temporary_counter);
new_info = counter.render(self.traversal.layout_context, new_info = counter.render(self.traversal.layout_context,
fragment.node, fragment.node,
fragment.pseudo.clone(), fragment.pseudo.clone(),
@ -203,9 +203,9 @@ impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
counter_style)) => { counter_style)) => {
let temporary_counter = Counter::new(); let temporary_counter = Counter::new();
let counter = self.traversal let counter = self.traversal
.counters .counters
.get(&**counter_name) .get(&*counter_name.0)
.unwrap_or(&temporary_counter); .unwrap_or(&temporary_counter);
new_info = counter.render(self.traversal.layout_context, new_info = counter.render(self.traversal.layout_context,
fragment.node, fragment.node,
fragment.pseudo, fragment.pseudo,

View file

@ -5428,6 +5428,7 @@ clip-path
} }
pub fn set_content(&mut self, v: longhands::content::computed_value::T, device: &Device) { pub fn set_content(&mut self, v: longhands::content::computed_value::T, device: &Device) {
use values::CustomIdent;
use values::computed::counters::{Content, ContentItem}; use values::computed::counters::{Content, ContentItem};
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
use gecko_bindings::structs::nsStyleContentData; use gecko_bindings::structs::nsStyleContentData;
@ -5445,16 +5446,20 @@ clip-path
ptr ptr
} }
fn set_counter_function(data: &mut nsStyleContentData, fn set_counter_function(
content_type: nsStyleContentType, data: &mut nsStyleContentData,
name: &str, sep: &str, content_type: nsStyleContentType,
style: CounterStyleOrNone, device: &Device) { name: &CustomIdent,
sep: &str,
style: CounterStyleOrNone,
device: &Device,
) {
debug_assert!(content_type == eStyleContentType_Counter || debug_assert!(content_type == eStyleContentType_Counter ||
content_type == eStyleContentType_Counters); content_type == eStyleContentType_Counters);
let counter_func = unsafe { let counter_func = unsafe {
bindings::Gecko_SetCounterFunction(data, content_type).as_mut().unwrap() bindings::Gecko_SetCounterFunction(data, content_type).as_mut().unwrap()
}; };
counter_func.mIdent.assign_utf8(name); counter_func.mIdent.assign(name.0.as_slice());
if content_type == eStyleContentType_Counters { if content_type == eStyleContentType_Counters {
counter_func.mSeparator.assign_utf8(sep); counter_func.mSeparator.assign_utf8(sep);
} }
@ -5522,12 +5527,24 @@ clip-path
ContentItem::NoCloseQuote ContentItem::NoCloseQuote
=> self.gecko.mContents[i].mType = eStyleContentType_NoCloseQuote, => self.gecko.mContents[i].mType = eStyleContentType_NoCloseQuote,
ContentItem::Counter(ref name, ref style) => { ContentItem::Counter(ref name, ref style) => {
set_counter_function(&mut self.gecko.mContents[i], set_counter_function(
eStyleContentType_Counter, &name, "", style.clone(), device); &mut self.gecko.mContents[i],
eStyleContentType_Counter,
&name,
"",
style.clone(),
device,
);
} }
ContentItem::Counters(ref name, ref sep, ref style) => { ContentItem::Counters(ref name, ref sep, ref style) => {
set_counter_function(&mut self.gecko.mContents[i], set_counter_function(
eStyleContentType_Counters, &name, &sep, style.clone(), device); &mut self.gecko.mContents[i],
eStyleContentType_Counters,
&name,
&sep,
style.clone(),
device,
);
} }
ContentItem::Url(ref url) => { ContentItem::Url(ref url) => {
unsafe { unsafe {
@ -5553,10 +5570,11 @@ clip-path
} }
pub fn clone_content(&self) -> longhands::content::computed_value::T { pub fn clone_content(&self) -> longhands::content::computed_value::T {
use Atom;
use gecko::conversions::string_from_chars_pointer; use gecko::conversions::string_from_chars_pointer;
use gecko_bindings::structs::nsStyleContentType::*; use gecko_bindings::structs::nsStyleContentType::*;
use values::computed::counters::{Content, ContentItem}; use values::computed::counters::{Content, ContentItem};
use values::Either; use values::{CustomIdent, Either};
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
use values::specified::Attr; use values::specified::Attr;
@ -5601,7 +5619,7 @@ clip-path
eStyleContentType_Counter | eStyleContentType_Counters => { eStyleContentType_Counter | eStyleContentType_Counters => {
let gecko_function = let gecko_function =
unsafe { &**gecko_content.mContent.mCounters.as_ref() }; unsafe { &**gecko_content.mContent.mCounters.as_ref() };
let ident = gecko_function.mIdent.to_string(); let ident = CustomIdent(Atom::from(&*gecko_function.mIdent));
let style = let style =
CounterStyleOrNone::from_gecko_value(&gecko_function.mCounterStyle); CounterStyleOrNone::from_gecko_value(&gecko_function.mCounterStyle);
let style = match style { let style = match style {
@ -5610,10 +5628,10 @@ clip-path
unreachable!("counter function shouldn't have single string type"), unreachable!("counter function shouldn't have single string type"),
}; };
if gecko_content.mType == eStyleContentType_Counter { if gecko_content.mType == eStyleContentType_Counter {
ContentItem::Counter(ident.into_boxed_str(), style) ContentItem::Counter(ident, style)
} else { } else {
let separator = gecko_function.mSeparator.to_string(); let separator = gecko_function.mSeparator.to_string();
ContentItem::Counters(ident.into_boxed_str(), separator.into_boxed_str(), style) ContentItem::Counters(ident, separator.into_boxed_str(), style)
} }
}, },
eStyleContentType_Image => { eStyleContentType_Image => {

View file

@ -6,11 +6,12 @@
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
use computed_values::list_style_type::T as ListStyleType; use computed_values::list_style_type::T as ListStyleType;
use cssparser::{self, Parser, Token}; use cssparser::{Parser, Token};
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseErrorKind; use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use values::CustomIdent;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
use values::generics::counters::CounterIncrement as GenericCounterIncrement; use values::generics::counters::CounterIncrement as GenericCounterIncrement;
@ -93,7 +94,8 @@ impl Parse for Content {
Ok(Token::Function(ref name)) => { Ok(Token::Function(ref name)) => {
let result = match_ignore_ascii_case! { &name, let result = match_ignore_ascii_case! { &name,
"counter" => Some(input.parse_nested_block(|input| { "counter" => Some(input.parse_nested_block(|input| {
let name = input.expect_ident()?.as_ref().to_owned().into_boxed_str(); let location = input.current_source_location();
let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?;
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
let style = Content::parse_counter_style(input); let style = Content::parse_counter_style(input);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
@ -101,7 +103,8 @@ impl Parse for Content {
Ok(ContentItem::Counter(name, style)) Ok(ContentItem::Counter(name, style))
})), })),
"counters" => Some(input.parse_nested_block(|input| { "counters" => Some(input.parse_nested_block(|input| {
let name = input.expect_ident()?.as_ref().to_owned().into_boxed_str(); let location = input.current_source_location();
let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?;
input.expect_comma()?; input.expect_comma()?;
let separator = input.expect_string()?.as_ref().to_owned().into_boxed_str(); let separator = input.expect_string()?.as_ref().to_owned().into_boxed_str();
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
@ -154,14 +157,14 @@ impl ToCss for ContentItem {
ContentItem::String(ref s) => s.to_css(dest), ContentItem::String(ref s) => s.to_css(dest),
ContentItem::Counter(ref s, ref counter_style) => { ContentItem::Counter(ref s, ref counter_style) => {
dest.write_str("counter(")?; dest.write_str("counter(")?;
cssparser::serialize_identifier(&**s, dest)?; s.to_css(dest)?;
dest.write_str(", ")?; dest.write_str(", ")?;
counter_style.to_css(dest)?; counter_style.to_css(dest)?;
dest.write_str(")") dest.write_str(")")
} }
ContentItem::Counters(ref s, ref separator, ref counter_style) => { ContentItem::Counters(ref s, ref separator, ref counter_style) => {
dest.write_str("counters(")?; dest.write_str("counters(")?;
cssparser::serialize_identifier(&**s, dest)?; s.to_css(dest)?;
dest.write_str(", ")?; dest.write_str(", ")?;
separator.to_css(dest)?; separator.to_css(dest)?;
dest.write_str(", ")?; dest.write_str(", ")?;

View file

@ -102,9 +102,9 @@ pub enum ContentItem {
/// Literal string content. /// Literal string content.
String(Box<str>), String(Box<str>),
/// `counter(name, style)`. /// `counter(name, style)`.
Counter(Box<str>, CounterStyleType), Counter(CustomIdent, CounterStyleType),
/// `counters(name, separator, style)`. /// `counters(name, separator, style)`.
Counters(Box<str>, Box<str>, CounterStyleType), Counters(CustomIdent, Box<str>, CounterStyleType),
/// `open-quote`. /// `open-quote`.
OpenQuote, OpenQuote,
/// `close-quote`. /// `close-quote`.

View file

@ -117521,6 +117521,18 @@
{} {}
] ]
], ],
"css/css-lists/counter-invalid.htm": [
[
"/css/css-lists/counter-invalid.htm",
[
[
"/css/css-lists/counter-7-ref.html",
"=="
]
],
{}
]
],
"css/css-lists/counter-reset-increment-display-contents.html": [ "css/css-lists/counter-reset-increment-display-contents.html": [
[ [
"/css/css-lists/counter-reset-increment-display-contents.html", "/css/css-lists/counter-reset-increment-display-contents.html",
@ -499812,6 +499824,10 @@
"d137a61e9cdacdf9130412675f0365e78719e93e", "d137a61e9cdacdf9130412675f0365e78719e93e",
"reftest" "reftest"
], ],
"css/css-lists/counter-invalid.htm": [
"53bc436596adcb06a5612537f1a57b79629610b3",
"reftest"
],
"css/css-lists/counter-reset-increment-display-contents.html": [ "css/css-lists/counter-reset-increment-display-contents.html": [
"7e8737c7342ada38a67c25bebf7731ab906a6161", "7e8737c7342ada38a67c25bebf7731ab906a6161",
"reftest" "reftest"

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Lists: </title>
<link rel="author" title="Anthony Ramine" href="mailto:n.oxyde@gmail.com">
<link rel="help" href="https://drafts.csswg.org/css-lists/#counter-functions">
<link rel="match" href="counter-7-ref.html">
<style>
div::after { content: " is not " counter(inherit) }
</style>
<p>You should see the number 7 below.</p>
<div>7</div>