Bug 1576821 - [css-lists-3] Make 'none' invalid as a <counter-style> in counter()/counters(). r=emilio

CSSWG resolution:
https://github.com/w3c/csswg-drafts/issues/4163#issuecomment-521331100

Spec:
https://drafts.csswg.org/css-lists-3/#counter-functions

Differential Revision: https://phabricator.services.mozilla.com/D43893

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mats Palmgren 2019-08-30 00:15:37 +00:00
Родитель 03fd07af55
Коммит e45d08541b
14 изменённых файлов: 108 добавлений и 191 удалений

Просмотреть файл

@ -1,6 +1,5 @@
== counter-name-case-sensitive.html counter-name-case-sensitive-ref.html == counter-name-case-sensitive.html counter-name-case-sensitive-ref.html
== t1202-counter-00-b-test.html t1202-counter-00-b-reference.html == t1202-counter-00-b-test.html t1202-counter-00-b-reference.html
== t1202-counter-01-b-test.html t1202-counter-01-b-reference.html
== t1202-counter-02-b-test.html t1202-counter-02-b-reference.html == t1202-counter-02-b-test.html t1202-counter-02-b-reference.html
== t1202-counter-03-b-test.html t1202-counter-03-b-reference.html == t1202-counter-03-b-test.html t1202-counter-03-b-reference.html
== t1202-counter-04-b-test.html t1202-counter-04-b-reference.html == t1202-counter-04-b-test.html t1202-counter-04-b-reference.html
@ -17,7 +16,7 @@ random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == t1202-counter-10-b-test.
== t1202-counter-15-b-test.html t1202-counter-15-b-reference.html == t1202-counter-15-b-test.html t1202-counter-15-b-reference.html
== t1202-counter-16-f-test.html t1202-counter-16-f-reference.html == t1202-counter-16-f-test.html t1202-counter-16-f-reference.html
== t1202-counters-00-b-test.html t1202-counters-00-b-reference.html == t1202-counters-00-b-test.html t1202-counters-00-b-reference.html
== t1202-counters-01-b-test.html t1202-counters-01-b-reference.html == t1202-counters-01-b-test.html about:blank
== t1202-counters-02-b-test.html t1202-counters-02-b-reference.html == t1202-counters-02-b-test.html t1202-counters-02-b-reference.html
== t1202-counters-03-b-test.html t1202-counters-03-b-reference.html == t1202-counters-03-b-test.html t1202-counters-03-b-reference.html
== t1202-counters-04-b-test.html t1202-counters-04-b-reference.html == t1202-counters-04-b-test.html t1202-counters-04-b-reference.html

Просмотреть файл

@ -1,34 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS 2.1 Test Suite: content: counter(c, none)</title>
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-content"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/syndata.html#counter"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counter-styles"/>
<style type="text/css">
#test { counter-reset: c; }
#test span { counter-increment: c; }
#test span:before { content: counter(c, none) "z"; }
</style>
</head>
<body>
<div id="test">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>

Просмотреть файл

@ -1,29 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS 2.1 Test Suite: content: counters(c, ".", none)</title>
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-content"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/syndata.html#counter"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counter-styles"/>
</head>
<body>
<p></p>
<div>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
<span>.z</span>
</div>
</body>
</html>

Просмотреть файл

@ -5287,8 +5287,6 @@ var gCSSProperties = {
"no-open-quote", "no-open-quote",
"no-close-quote", "no-close-quote",
"close-quote attr(title) counters(foo, '.', upper-alpha)", "close-quote attr(title) counters(foo, '.', upper-alpha)",
"counter(foo, none)",
"counters(bar, '.', none)",
"attr(\\32)", "attr(\\32)",
"attr(\\2)", "attr(\\2)",
"attr(-\\2)", "attr(-\\2)",
@ -5307,6 +5305,8 @@ var gCSSProperties = {
"counters(foo, '.', symbols(numeric '0' '1'))", "counters(foo, '.', symbols(numeric '0' '1'))",
], ],
invalid_values: [ invalid_values: [
"counter(foo, none)",
"counters(bar, '.', none)",
"counters(foo)", "counters(foo)",
'counter(foo, ".")', 'counter(foo, ".")',
'attr("title")', 'attr("title")',

Просмотреть файл

@ -8,7 +8,7 @@
use crate::counter_style::{Symbol, Symbols}; use crate::counter_style::{Symbol, Symbols};
use crate::gecko_bindings::structs::CounterStylePtr; use crate::gecko_bindings::structs::CounterStylePtr;
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
use crate::values::Either; use crate::values::Either;
use crate::Atom; use crate::Atom;
use app_units::Au; use app_units::Au;
@ -49,19 +49,17 @@ pub fn round_border_to_device_pixels(width: Au, au_per_device_px: Au) -> Au {
} }
} }
impl CounterStyleOrNone { impl CounterStyle {
/// Convert this counter style to a Gecko CounterStylePtr. /// Convert this counter style to a Gecko CounterStylePtr.
pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr) { pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr) {
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name; use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name;
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols; use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols;
match self { match self {
CounterStyleOrNone::None => unsafe { CounterStyle::Name(name) => unsafe {
set_name(gecko_value, atom!("none").into_addrefed()); debug_assert_ne!(name.0, atom!("none"));
},
CounterStyleOrNone::Name(name) => unsafe {
set_name(gecko_value, name.0.into_addrefed()); set_name(gecko_value, name.0.into_addrefed());
}, },
CounterStyleOrNone::Symbols(symbols_type, symbols) => { CounterStyle::Symbols(symbols_type, symbols) => {
let symbols: Vec<_> = symbols let symbols: Vec<_> = symbols
.0 .0
.iter() .iter()
@ -86,7 +84,7 @@ impl CounterStyleOrNone {
} }
} }
/// Convert Gecko CounterStylePtr to CounterStyleOrNone or String. /// Convert Gecko CounterStylePtr to CounterStyle or String.
pub fn from_gecko_value(gecko_value: &CounterStylePtr) -> Either<Self, String> { pub fn from_gecko_value(gecko_value: &CounterStylePtr) -> Either<Self, String> {
use crate::gecko_bindings::bindings; use crate::gecko_bindings::bindings;
use crate::values::generics::SymbolsType; use crate::values::generics::SymbolsType;
@ -95,11 +93,8 @@ impl CounterStyleOrNone {
let name = unsafe { bindings::Gecko_CounterStyle_GetName(gecko_value) }; let name = unsafe { bindings::Gecko_CounterStyle_GetName(gecko_value) };
if !name.is_null() { if !name.is_null() {
let name = unsafe { Atom::from_raw(name) }; let name = unsafe { Atom::from_raw(name) };
if name == atom!("none") { debug_assert_ne!(name, atom!("none"));
Either::First(CounterStyleOrNone::None) Either::First(CounterStyle::Name(CustomIdent(name)))
} else {
Either::First(CounterStyleOrNone::Name(CustomIdent(name)))
}
} else { } else {
let anonymous = let anonymous =
unsafe { bindings::Gecko_CounterStyle_GetAnonymous(gecko_value).as_ref() }.unwrap(); unsafe { bindings::Gecko_CounterStyle_GetAnonymous(gecko_value).as_ref() }.unwrap();
@ -113,7 +108,7 @@ impl CounterStyleOrNone {
.iter() .iter()
.map(|gecko_symbol| Symbol::String(gecko_symbol.to_string().into())) .map(|gecko_symbol| Symbol::String(gecko_symbol.to_string().into()))
.collect(); .collect();
Either::First(CounterStyleOrNone::Symbols(symbol_type, Symbols(symbols))) Either::First(CounterStyle::Symbols(symbol_type, Symbols(symbols)))
} }
} }
} }

Просмотреть файл

@ -2199,10 +2199,15 @@ fn static_assert() {
} }
pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T) { pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T) {
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToName;
use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToString; use crate::gecko_bindings::bindings::Gecko_SetCounterStyleToString;
use nsstring::{nsACString, nsCStr}; use nsstring::{nsACString, nsCStr};
use self::longhands::list_style_type::computed_value::T; use self::longhands::list_style_type::computed_value::T;
match v { match v {
T::None => unsafe {
Gecko_SetCounterStyleToName(&mut self.gecko.mCounterStyle,
atom!("none").into_addrefed());
}
T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle), T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle),
T::String(s) => unsafe { T::String(s) => unsafe {
Gecko_SetCounterStyleToString(&mut self.gecko.mCounterStyle, Gecko_SetCounterStyleToString(&mut self.gecko.mCounterStyle,
@ -2224,9 +2229,19 @@ fn static_assert() {
pub fn clone_list_style_type(&self) -> longhands::list_style_type::computed_value::T { pub fn clone_list_style_type(&self) -> longhands::list_style_type::computed_value::T {
use self::longhands::list_style_type::computed_value::T; use self::longhands::list_style_type::computed_value::T;
use crate::values::Either; use crate::values::Either;
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
use crate::gecko_bindings::bindings;
let result = CounterStyleOrNone::from_gecko_value(&self.gecko.mCounterStyle); let name = unsafe {
bindings::Gecko_CounterStyle_GetName(&self.gecko.mCounterStyle)
};
if !name.is_null() {
let name = unsafe { Atom::from_raw(name) };
if name == atom!("none") {
return T::None;
}
}
let result = CounterStyle::from_gecko_value(&self.gecko.mCounterStyle);
match result { match result {
Either::First(counter_style) => T::CounterStyle(counter_style), Either::First(counter_style) => T::CounterStyle(counter_style),
Either::Second(string) => T::String(string), Either::Second(string) => T::String(string),
@ -2573,7 +2588,7 @@ clip-path
pub fn set_content(&mut self, v: longhands::content::computed_value::T) { pub fn set_content(&mut self, v: longhands::content::computed_value::T) {
use crate::values::CustomIdent; use crate::values::CustomIdent;
use crate::values::generics::counters::{Content, ContentItem}; use crate::values::generics::counters::{Content, ContentItem};
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
use crate::gecko_bindings::structs::nsStyleContentData; use crate::gecko_bindings::structs::nsStyleContentData;
use crate::gecko_bindings::structs::nsStyleContentAttr; use crate::gecko_bindings::structs::nsStyleContentAttr;
use crate::gecko_bindings::structs::StyleContentType; use crate::gecko_bindings::structs::StyleContentType;
@ -2594,7 +2609,7 @@ clip-path
content_type: StyleContentType, content_type: StyleContentType,
name: CustomIdent, name: CustomIdent,
sep: &str, sep: &str,
style: CounterStyleOrNone, style: CounterStyle,
) { ) {
debug_assert!(content_type == StyleContentType::Counter || debug_assert!(content_type == StyleContentType::Counter ||
content_type == StyleContentType::Counters); content_type == StyleContentType::Counters);
@ -2724,7 +2739,7 @@ clip-path
use crate::gecko_bindings::structs::StyleContentType; use crate::gecko_bindings::structs::StyleContentType;
use crate::values::generics::counters::{Content, ContentItem}; use crate::values::generics::counters::{Content, ContentItem};
use crate::values::{CustomIdent, Either}; use crate::values::{CustomIdent, Either};
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
use crate::values::specified::Attr; use crate::values::specified::Attr;
if self.gecko.mContents.is_empty() { if self.gecko.mContents.is_empty() {
@ -2769,7 +2784,7 @@ clip-path
Atom::from_raw(gecko_function.mIdent.mRawPtr) Atom::from_raw(gecko_function.mIdent.mRawPtr)
}); });
let style = let style =
CounterStyleOrNone::from_gecko_value(&gecko_function.mCounterStyle); CounterStyle::from_gecko_value(&gecko_function.mCounterStyle);
let style = match style { let style = match style {
Either::First(counter_style) => counter_style, Either::First(counter_style) => counter_style,
Either::Second(_) => Either::Second(_) =>

Просмотреть файл

@ -61,31 +61,23 @@
let position = unwrap_or_initial!(list_style_position, position); let position = unwrap_or_initial!(list_style_position, position);
fn list_style_type_none() -> list_style_type::SpecifiedValue {
% if engine == "gecko":
use crate::values::generics::CounterStyleOrNone;
list_style_type::SpecifiedValue::CounterStyle(CounterStyleOrNone::None)
% else:
list_style_type::SpecifiedValue::None
% endif
}
// If there are two `none`s, then we can't have a type or image; if there is one `none`, // If there are two `none`s, then we can't have a type or image; if there is one `none`,
// then we can't have both a type *and* an image; if there is no `none` then we're fine as // then we can't have both a type *and* an image; if there is no `none` then we're fine as
// long as we parsed something. // long as we parsed something.
use self::list_style_type::SpecifiedValue as ListStyleType;
match (any, nones, list_style_type, image) { match (any, nones, list_style_type, image) {
(true, 2, None, None) => { (true, 2, None, None) => {
Ok(expanded! { Ok(expanded! {
list_style_position: position, list_style_position: position,
list_style_image: ImageUrlOrNone::none(), list_style_image: ImageUrlOrNone::none(),
list_style_type: list_style_type_none(), list_style_type: ListStyleType::None,
}) })
} }
(true, 1, None, Some(image)) => { (true, 1, None, Some(image)) => {
Ok(expanded! { Ok(expanded! {
list_style_position: position, list_style_position: position,
list_style_image: image, list_style_image: image,
list_style_type: list_style_type_none(), list_style_type: ListStyleType::None,
}) })
} }
(true, 1, Some(list_style_type), None) => { (true, 1, Some(list_style_type), None) => {
@ -99,7 +91,7 @@
Ok(expanded! { Ok(expanded! {
list_style_position: position, list_style_position: position,
list_style_image: ImageUrlOrNone::none(), list_style_image: ImageUrlOrNone::none(),
list_style_type: list_style_type_none(), list_style_type: ListStyleType::None,
}) })
} }
(true, 0, list_style_type, image) => { (true, 0, list_style_type, image) => {

Просмотреть файл

@ -7,7 +7,7 @@
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
use crate::computed_values::list_style_type::T as ListStyleType; use crate::computed_values::list_style_type::T as ListStyleType;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::specified::Attr; use crate::values::specified::Attr;
use crate::values::CustomIdent; use crate::values::CustomIdent;
@ -127,7 +127,7 @@ impl<I> Counters<I> {
type CounterStyleType = ListStyleType; type CounterStyleType = ListStyleType;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
type CounterStyleType = CounterStyleOrNone; type CounterStyleType = CounterStyle;
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
#[inline] #[inline]
@ -138,7 +138,7 @@ fn is_decimal(counter_type: &CounterStyleType) -> bool {
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
#[inline] #[inline]
fn is_decimal(counter_type: &CounterStyleType) -> bool { fn is_decimal(counter_type: &CounterStyleType) -> bool {
*counter_type == CounterStyleOrNone::decimal() *counter_type == CounterStyle::decimal()
} }
/// The specified value for the `content` property. /// The specified value for the `content` property.

Просмотреть файл

@ -92,13 +92,10 @@ impl SymbolsType {
/// <https://drafts.csswg.org/css-counter-styles/#typedef-counter-style> /// <https://drafts.csswg.org/css-counter-styles/#typedef-counter-style>
/// ///
/// Since wherever <counter-style> is used, 'none' is a valid value as /// Note that 'none' is not a valid name.
/// well, we combine them into one type to make code simpler.
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))] #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)] #[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
pub enum CounterStyleOrNone { pub enum CounterStyle {
/// `none`
None,
/// `<counter-style-name>` /// `<counter-style-name>`
Name(CustomIdent), Name(CustomIdent),
/// `symbols()` /// `symbols()`
@ -111,28 +108,25 @@ fn is_symbolic(symbols_type: &SymbolsType) -> bool {
*symbols_type == SymbolsType::Symbolic *symbols_type == SymbolsType::Symbolic
} }
impl CounterStyleOrNone { impl CounterStyle {
/// disc value /// disc value
pub fn disc() -> Self { pub fn disc() -> Self {
CounterStyleOrNone::Name(CustomIdent(atom!("disc"))) CounterStyle::Name(CustomIdent(atom!("disc")))
} }
/// decimal value /// decimal value
pub fn decimal() -> Self { pub fn decimal() -> Self {
CounterStyleOrNone::Name(CustomIdent(atom!("decimal"))) CounterStyle::Name(CustomIdent(atom!("decimal")))
} }
} }
impl Parse for CounterStyleOrNone { impl Parse for CounterStyle {
fn parse<'i, 't>( fn parse<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
if let Ok(name) = input.try(|i| parse_counter_style_name(i)) { if let Ok(name) = input.try(|i| parse_counter_style_name(i)) {
return Ok(CounterStyleOrNone::Name(name)); return Ok(CounterStyle::Name(name));
}
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(CounterStyleOrNone::None);
} }
input.expect_function_matching("symbols")?; input.expect_function_matching("symbols")?;
input.parse_nested_block(|input| { input.parse_nested_block(|input| {
@ -151,12 +145,12 @@ impl Parse for CounterStyleOrNone {
if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) { if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} }
Ok(CounterStyleOrNone::Symbols(symbols_type, symbols)) Ok(CounterStyle::Symbols(symbols_type, symbols))
}) })
} }
} }
impl SpecifiedValueInfo for CounterStyleOrNone { impl SpecifiedValueInfo for CounterStyle {
fn collect_completion_keywords(f: KeywordsCollectFn) { fn collect_completion_keywords(f: KeywordsCollectFn) {
// XXX The best approach for implementing this is probably // XXX The best approach for implementing this is probably
// having a CounterStyleName type wrapping CustomIdent, and // having a CounterStyleName type wrapping CustomIdent, and
@ -165,7 +159,7 @@ impl SpecifiedValueInfo for CounterStyleOrNone {
// approach here. // approach here.
macro_rules! predefined { macro_rules! predefined {
($($name:expr,)+) => { ($($name:expr,)+) => {
f(&["none", "symbols", $($name,)+]); f(&["symbols", $($name,)+]);
} }
} }
include!("../../counter_style/predefined.rs"); include!("../../counter_style/predefined.rs");

Просмотреть файл

@ -12,7 +12,7 @@ use crate::values::generics::counters::CounterIncrement as GenericCounterIncreme
use crate::values::generics::counters::CounterPair; use crate::values::generics::counters::CounterPair;
use crate::values::generics::counters::CounterSetOrReset as GenericCounterSetOrReset; use crate::values::generics::counters::CounterSetOrReset as GenericCounterSetOrReset;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
use crate::values::specified::url::SpecifiedImageUrl; use crate::values::specified::url::SpecifiedImageUrl;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::specified::Attr; use crate::values::specified::Attr;
@ -98,13 +98,13 @@ impl Content {
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyleOrNone { fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyle {
input input
.try(|input| { .try(|input| {
input.expect_comma()?; input.expect_comma()?;
CounterStyleOrNone::parse(context, input) CounterStyle::parse(context, input)
}) })
.unwrap_or(CounterStyleOrNone::decimal()) .unwrap_or(CounterStyle::decimal())
} }
} }

Просмотреть файл

@ -6,7 +6,7 @@
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::generics::CounterStyleOrNone; use crate::values::generics::CounterStyle;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::values::CustomIdent; use crate::values::CustomIdent;
use cssparser::{Parser, Token}; use cssparser::{Parser, Token};
@ -27,8 +27,10 @@ use style_traits::{ParseError, StyleParseErrorKind};
ToShmem, ToShmem,
)] )]
pub enum ListStyleType { pub enum ListStyleType {
/// <counter-style> | none /// `none`
CounterStyle(CounterStyleOrNone), None,
/// <counter-style>
CounterStyle(CounterStyle),
/// <string> /// <string>
String(String), String(String),
} }
@ -38,7 +40,7 @@ impl ListStyleType {
/// Initial specified value for `list-style-type`. /// Initial specified value for `list-style-type`.
#[inline] #[inline]
pub fn disc() -> Self { pub fn disc() -> Self {
ListStyleType::CounterStyle(CounterStyleOrNone::disc()) ListStyleType::CounterStyle(CounterStyle::disc())
} }
/// Convert from gecko keyword to list-style-type. /// Convert from gecko keyword to list-style-type.
@ -50,10 +52,10 @@ impl ListStyleType {
use crate::gecko_bindings::structs; use crate::gecko_bindings::structs;
if value == structs::NS_STYLE_LIST_STYLE_NONE { if value == structs::NS_STYLE_LIST_STYLE_NONE {
return ListStyleType::CounterStyle(CounterStyleOrNone::None); return ListStyleType::None;
} }
ListStyleType::CounterStyle(CounterStyleOrNone::Name(CustomIdent(match value { ListStyleType::CounterStyle(CounterStyle::Name(CustomIdent(match value {
structs::NS_STYLE_LIST_STYLE_DISC => atom!("disc"), structs::NS_STYLE_LIST_STYLE_DISC => atom!("disc"),
structs::NS_STYLE_LIST_STYLE_CIRCLE => atom!("circle"), structs::NS_STYLE_LIST_STYLE_CIRCLE => atom!("circle"),
structs::NS_STYLE_LIST_STYLE_SQUARE => atom!("square"), structs::NS_STYLE_LIST_STYLE_SQUARE => atom!("square"),
@ -73,10 +75,12 @@ impl Parse for ListStyleType {
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
if let Ok(style) = input.try(|i| CounterStyleOrNone::parse(context, i)) { if let Ok(style) = input.try(|i| CounterStyle::parse(context, i)) {
return Ok(ListStyleType::CounterStyle(style)); return Ok(ListStyleType::CounterStyle(style));
} }
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(ListStyleType::None);
}
Ok(ListStyleType::String( Ok(ListStyleType::String(
input.expect_string()?.as_ref().to_owned(), input.expect_string()?.as_ref().to_owned(),
)) ))

Просмотреть файл

@ -1,43 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com"/>
<style type="text/css">
body {
white-space: nowrap;
}
</style>
</head>
<body>
<p>The following two lines should look the same:</p>
<div>
z
z
z
z
z
z
z
z
z
z
z
z
</div>
<div>
z
z
z
z
z
z
z
z
z
z
z
z
</div>
</body>
</html>

Просмотреть файл

@ -6,7 +6,7 @@
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-content"/> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#propdef-content"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/syndata.html#counter"/> <link rel="help" href="http://www.w3.org/TR/CSS21/syndata.html#counter"/>
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counter-styles"/> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counter-styles"/>
<link rel="match" href="content-counter-001-ref.xht"/> <link rel="match" href="about:blank"/>
<style type="text/css"> <style type="text/css">
body { white-space: nowrap; } body { white-space: nowrap; }
@ -20,8 +20,6 @@
</head> </head>
<body> <body>
<p>The following two lines should look the same:</p>
<div id="test"> <div id="test">
<span></span> <span></span>
<span></span> <span></span>
@ -37,20 +35,5 @@
<span></span> <span></span>
</div> </div>
<div>
z
z
z
z
z
z
z
z
z
z
z
z
</div>
</body> </body>
</html> </html>

Просмотреть файл

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Lists: parsing counter()/counters() values for the 'content' property</title>
<link rel="help" href="https://drafts.csswg.org/css-lists-3/#counter-functions">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value('content', 'counter(foo, none)');
test_invalid_value('content', 'counters(foo, "", none)');
test_invalid_value('content', 'counter(foo, unset)');
test_invalid_value('content', 'counters(foo, "", unset)');
test_invalid_value('content', 'counter(foo, initial)');
test_invalid_value('content', 'counters(foo, "", initial)');
test_invalid_value('content', 'counter(foo, inherit)');
test_invalid_value('content', 'counters(foo, "", inherit)');
test_invalid_value('content', '"z" counter(foo, none)');
test_invalid_value('content', '"z" counters(foo, "", none)');
test_invalid_value('content', '"z" counter(foo, unset)');
test_invalid_value('content', '"z" counters(foo, "", unset)');
test_invalid_value('content', '"z" counter(foo, initial)');
test_invalid_value('content', '"z" counters(foo, "", initial)');
test_invalid_value('content', '"z" counter(foo, inherit)');
test_invalid_value('content', '"z" counters(foo, "", inherit)');
test_invalid_value('content', 'counter(foo, none) "z"');
test_invalid_value('content', 'counters(foo, "", none) "z"');
test_invalid_value('content', 'counter(foo, unset) "z"');
test_invalid_value('content', 'counters(foo, "", unset) "z"');
test_invalid_value('content', 'counter(foo, initial) "z"');
test_invalid_value('content', 'counters(foo, "", initial) "z"');
test_invalid_value('content', 'counter(foo, inherit) "z"');
test_invalid_value('content', 'counters(foo, "", inherit) "z"');
</script>
</body>
</html>