Auto merge of #17060 - upsuper:bug1363596, r=heycam

Support symbols() function and string value for list-style-type for stylo

This is the Servo side change of [bug 1363596](https://bugzilla.mozilla.org/show_bug.cgi?id=1363596).

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17060)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-05-27 07:09:30 -05:00 committed by GitHub
commit 6b1f039205
11 changed files with 2073 additions and 1666 deletions

View file

@ -337,7 +337,7 @@ impl ToCss for System {
} }
/// https://drafts.csswg.org/css-counter-styles/#typedef-symbol /// https://drafts.csswg.org/css-counter-styles/#typedef-symbol
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Symbol { pub enum Symbol {
/// <string> /// <string>
String(String), String(String),
@ -367,6 +367,17 @@ impl ToCss for Symbol {
} }
} }
impl Symbol {
/// Returns whether this symbol is allowed in symbols() function.
pub fn is_allowed_in_symbols(&self) -> bool {
match self {
// Identifier is not allowed.
&Symbol::Ident(_) => false,
_ => true,
}
}
}
/// https://drafts.csswg.org/css-counter-styles/#counter-style-negative /// https://drafts.csswg.org/css-counter-styles/#counter-style-negative
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Negative(pub Symbol, pub Option<Symbol>); pub struct Negative(pub Symbol, pub Option<Symbol>);
@ -495,7 +506,7 @@ impl ToCss for Fallback {
} }
/// https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols /// https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Symbols(pub Vec<Symbol>); pub struct Symbols(pub Vec<Symbol>);
impl Parse for Symbols { impl Parse for Symbols {

View file

@ -1874,6 +1874,10 @@ cfg_if! {
pub static nsGkAtoms_onsent: *mut nsIAtom; pub static nsGkAtoms_onsent: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms5onsetE"] #[link_name = "_ZN9nsGkAtoms5onsetE"]
pub static nsGkAtoms_onset: *mut nsIAtom; pub static nsGkAtoms_onset: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms23onshippingaddresschangeE"]
pub static nsGkAtoms_onshippingaddresschange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms22onshippingoptionchangeE"]
pub static nsGkAtoms_onshippingoptionchange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms6onshowE"] #[link_name = "_ZN9nsGkAtoms6onshowE"]
pub static nsGkAtoms_onshow: *mut nsIAtom; pub static nsGkAtoms_onshow: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms13onstatechangeE"] #[link_name = "_ZN9nsGkAtoms13onstatechangeE"]
@ -6893,6 +6897,10 @@ cfg_if! {
pub static nsGkAtoms_onsent: *mut nsIAtom; pub static nsGkAtoms_onsent: *mut nsIAtom;
#[link_name = "?onset@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onset@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onset: *mut nsIAtom; pub static nsGkAtoms_onset: *mut nsIAtom;
#[link_name = "?onshippingaddresschange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onshippingaddresschange: *mut nsIAtom;
#[link_name = "?onshippingoptionchange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onshippingoptionchange: *mut nsIAtom;
#[link_name = "?onshow@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onshow@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_onshow: *mut nsIAtom; pub static nsGkAtoms_onshow: *mut nsIAtom;
#[link_name = "?onstatechange@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?onstatechange@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -11912,6 +11920,10 @@ cfg_if! {
pub static nsGkAtoms_onsent: *mut nsIAtom; pub static nsGkAtoms_onsent: *mut nsIAtom;
#[link_name = "\x01?onset@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onset@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onset: *mut nsIAtom; pub static nsGkAtoms_onset: *mut nsIAtom;
#[link_name = "\x01?onshippingaddresschange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onshippingaddresschange: *mut nsIAtom;
#[link_name = "\x01?onshippingoptionchange@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onshippingoptionchange: *mut nsIAtom;
#[link_name = "\x01?onshow@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onshow@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_onshow: *mut nsIAtom; pub static nsGkAtoms_onshow: *mut nsIAtom;
#[link_name = "\x01?onstatechange@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?onstatechange@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -16934,6 +16946,10 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onsent as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onsent as *mut _) } };
("onset") => ("onset") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onset as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onset as *mut _) } };
("onshippingaddresschange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onshippingaddresschange as *mut _) } };
("onshippingoptionchange") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onshippingoptionchange as *mut _) } };
("onshow") => ("onshow") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onshow as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onshow as *mut _) } };
("onstatechange") => ("onstatechange") =>

View file

@ -32,6 +32,7 @@ use gecko_bindings::structs::CSSPseudoElementType;
use gecko_bindings::structs::TraversalRestyleBehavior; use gecko_bindings::structs::TraversalRestyleBehavior;
use gecko_bindings::structs::TraversalRootBehavior; use gecko_bindings::structs::TraversalRootBehavior;
use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag; use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag;
use gecko_bindings::structs::CounterStylePtr;
use gecko_bindings::structs::FontFamilyList; use gecko_bindings::structs::FontFamilyList;
use gecko_bindings::structs::FontFamilyType; use gecko_bindings::structs::FontFamilyType;
use gecko_bindings::structs::FontSizePrefs; use gecko_bindings::structs::FontSizePrefs;
@ -852,12 +853,22 @@ extern "C" {
aSrc: *const nsStyleVisibility); aSrc: *const nsStyleVisibility);
} }
extern "C" { extern "C" {
pub fn Gecko_SetListStyleType(style_struct: *mut nsStyleList, pub fn Gecko_SetCounterStyleToName(ptr: *mut CounterStylePtr,
name: *mut nsIAtom); name: *mut nsIAtom);
} }
extern "C" { extern "C" {
pub fn Gecko_CopyListStyleTypeFrom(dst: *mut nsStyleList, pub fn Gecko_SetCounterStyleToSymbols(ptr: *mut CounterStylePtr,
src: *const nsStyleList); symbols_type: u8,
symbols: *const *const nsACString,
symbols_count: u32);
}
extern "C" {
pub fn Gecko_SetCounterStyleToString(ptr: *mut CounterStylePtr,
symbol: *const nsACString);
}
extern "C" {
pub fn Gecko_CopyCounterStyle(dst: *mut CounterStylePtr,
src: *const CounterStylePtr);
} }
extern "C" { extern "C" {
pub fn Gecko_SetNullImageValue(image: *mut nsStyleImage); pub fn Gecko_SetNullImageValue(image: *mut nsStyleImage);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7,15 +7,19 @@
//! Different kind of helpers to interact with Gecko values. //! Different kind of helpers to interact with Gecko values.
use app_units::Au; use app_units::Au;
use counter_style::Symbol;
use cssparser::RGBA; use cssparser::RGBA;
use gecko_bindings::structs::{nsStyleCoord, StyleGridTrackBreadth, StyleShapeRadius}; use gecko_bindings::structs::{CounterStylePtr, nsStyleCoord};
use gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius};
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
use nsstring::{nsACString, nsCString};
use std::cmp::max; use std::cmp::max;
use values::{Auto, Either, ExtremumLength, None_, Normal}; use values::{Auto, Either, ExtremumLength, None_, Normal};
use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto}; use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto};
use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage};
use values::computed::{MaxLength, MozLength}; use values::computed::{MaxLength, MozLength};
use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
use values::generics::CounterStyleOrNone;
use values::generics::basic_shape::ShapeRadius; use values::generics::basic_shape::ShapeRadius;
use values::generics::grid::{TrackBreadth, TrackKeyword}; use values::generics::grid::{TrackBreadth, TrackKeyword};
use values::specified::Percentage; use values::specified::Percentage;
@ -390,3 +394,30 @@ pub fn round_border_to_device_pixels(width: Au, au_per_device_px: Au) -> Au {
max(au_per_device_px, Au(width.0 / au_per_device_px.0 * au_per_device_px.0)) max(au_per_device_px, Au(width.0 / au_per_device_px.0 * au_per_device_px.0))
} }
} }
impl CounterStyleOrNone {
/// Convert this counter style to a Gecko CounterStylePtr.
pub fn to_gecko_value(self, gecko_value: &mut CounterStylePtr) {
use gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name;
use gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols;
match self {
CounterStyleOrNone::None_ => unsafe {
set_name(gecko_value, atom!("none").into_addrefed());
},
CounterStyleOrNone::Name(name) => unsafe {
set_name(gecko_value, name.0.into_addrefed());
},
CounterStyleOrNone::Symbols(symbols_type, symbols) => {
let symbols: Vec<_> = symbols.0.iter().map(|symbol| match *symbol {
Symbol::String(ref s) => nsCString::from(s),
Symbol::Ident(_) => unreachable!("Should not have identifier in symbols()"),
}).collect();
let symbols: Vec<_> = symbols.iter()
.map(|symbol| symbol as &nsACString as *const _)
.collect();
unsafe { set_symbols(gecko_value, symbols_type.to_gecko_keyword(),
symbols.as_ptr(), symbols.len() as u32) };
}
}
}
}

View file

@ -21,11 +21,11 @@ use gecko_bindings::bindings::Gecko_CopyConstruct_${style_struct.gecko_ffi_name}
use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name}; use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
% endfor % endfor
use gecko_bindings::bindings::Gecko_Construct_nsStyleVariables; use gecko_bindings::bindings::Gecko_Construct_nsStyleVariables;
use gecko_bindings::bindings::Gecko_CopyCounterStyle;
use gecko_bindings::bindings::Gecko_CopyCursorArrayFrom; use gecko_bindings::bindings::Gecko_CopyCursorArrayFrom;
use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom; use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom;
use gecko_bindings::bindings::Gecko_CopyImageValueFrom; use gecko_bindings::bindings::Gecko_CopyImageValueFrom;
use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom; use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
use gecko_bindings::bindings::Gecko_CopyListStyleTypeFrom;
use gecko_bindings::bindings::Gecko_Destroy_nsStyleVariables; use gecko_bindings::bindings::Gecko_Destroy_nsStyleVariables;
use gecko_bindings::bindings::Gecko_EnsureImageLayersLength; use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
use gecko_bindings::bindings::Gecko_FontFamilyList_AppendGeneric; use gecko_bindings::bindings::Gecko_FontFamilyList_AppendGeneric;
@ -39,7 +39,6 @@ use gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
use gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom; use gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
use gecko_bindings::bindings::Gecko_SetListStyleImageNone; use gecko_bindings::bindings::Gecko_SetListStyleImageNone;
use gecko_bindings::bindings::Gecko_SetListStyleImageImageValue; use gecko_bindings::bindings::Gecko_SetListStyleImageImageValue;
use gecko_bindings::bindings::Gecko_SetListStyleType;
use gecko_bindings::bindings::Gecko_SetNullImageValue; use gecko_bindings::bindings::Gecko_SetNullImageValue;
use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom}; use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
@ -3157,18 +3156,21 @@ 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 values::generics::CounterStyleOrNone; use gecko_bindings::bindings::Gecko_SetCounterStyleToString;
let name = match v.0 { use nsstring::{nsACString, nsCString};
CounterStyleOrNone::None_ => atom!("none"), use self::longhands::list_style_type::computed_value::T;
CounterStyleOrNone::Name(name) => name.0, match v {
}; T::CounterStyle(s) => s.to_gecko_value(&mut self.gecko.mCounterStyle),
unsafe { Gecko_SetListStyleType(&mut self.gecko, name.as_ptr()); } T::String(s) => unsafe {
Gecko_SetCounterStyleToString(&mut self.gecko.mCounterStyle,
&nsCString::from(s) as &nsACString)
}
}
} }
pub fn copy_list_style_type_from(&mut self, other: &Self) { pub fn copy_list_style_type_from(&mut self, other: &Self) {
unsafe { unsafe {
Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko); Gecko_CopyCounterStyle(&mut self.gecko.mCounterStyle, &other.gecko.mCounterStyle);
} }
} }
@ -4264,7 +4266,6 @@ clip-path
use properties::longhands::content::computed_value::T; use properties::longhands::content::computed_value::T;
use properties::longhands::content::computed_value::ContentItem; use properties::longhands::content::computed_value::ContentItem;
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
use gecko_bindings::structs::nsIAtom;
use gecko_bindings::structs::nsStyleContentData; use gecko_bindings::structs::nsStyleContentData;
use gecko_bindings::structs::nsStyleContentType; use gecko_bindings::structs::nsStyleContentType;
use gecko_bindings::structs::nsStyleContentType::*; use gecko_bindings::structs::nsStyleContentType::*;
@ -4292,11 +4293,7 @@ clip-path
if content_type == eStyleContentType_Counters { if content_type == eStyleContentType_Counters {
counter_func.mSeparator.assign_utf8(sep); counter_func.mSeparator.assign_utf8(sep);
} }
let ptr = match style { style.to_gecko_value(&mut counter_func.mCounterStyle);
CounterStyleOrNone::None_ => atom!("none"),
CounterStyleOrNone::Name(name) => name.0,
}.into_addrefed();
unsafe { counter_func.mCounterStyleName.set_raw_from_addrefed::<nsIAtom>(ptr); }
} }
match v { match v {

View file

@ -31,8 +31,9 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
animation_value_type="none", animation_value_type="none",
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")} spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")}
% else: % else:
<%helpers:longhand name="list-style-type" animation_value_type="none" <%helpers:longhand name="list-style-type" animation_value_type="none" boxed="True"
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type"> spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type">
use cssparser;
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use values::CustomIdent; use values::CustomIdent;
@ -44,9 +45,12 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
pub mod computed_value { pub mod computed_value {
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
/// <counter-style> | none /// <counter-style> | <string> | none
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct T(pub CounterStyleOrNone); pub enum T {
CounterStyle(CounterStyleOrNone),
String(String),
}
} }
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
@ -54,7 +58,10 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
impl ToCss for SpecifiedValue { impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.0.to_css(dest) match *self {
SpecifiedValue::CounterStyle(ref s) => s.to_css(dest),
SpecifiedValue::String(ref s) => cssparser::serialize_string(s, dest)
}
} }
} }
@ -67,7 +74,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
/// attribute is considered here. /// attribute is considered here.
pub fn from_gecko_keyword(value: u32) -> Self { pub fn from_gecko_keyword(value: u32) -> Self {
use gecko_bindings::structs; use gecko_bindings::structs;
SpecifiedValue(if value == structs::NS_STYLE_LIST_STYLE_NONE { SpecifiedValue::CounterStyle(if value == structs::NS_STYLE_LIST_STYLE_NONE {
CounterStyleOrNone::None_ CounterStyleOrNone::None_
} else { } else {
<% <%
@ -86,16 +93,20 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
#[inline] #[inline]
pub fn get_initial_value() -> computed_value::T { pub fn get_initial_value() -> computed_value::T {
computed_value::T(CounterStyleOrNone::disc()) computed_value::T::CounterStyle(CounterStyleOrNone::disc())
} }
#[inline] #[inline]
pub fn get_initial_specified_value() -> SpecifiedValue { pub fn get_initial_specified_value() -> SpecifiedValue {
SpecifiedValue(CounterStyleOrNone::disc()) SpecifiedValue::CounterStyle(CounterStyleOrNone::disc())
} }
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
CounterStyleOrNone::parse(context, input).map(SpecifiedValue) Ok(if let Ok(style) = input.try(|i| CounterStyleOrNone::parse(context, i)) {
SpecifiedValue::CounterStyle(style)
} else {
SpecifiedValue::String(input.expect_string()?.into_owned())
})
} }
</%helpers:longhand> </%helpers:longhand>
% endif % endif

View file

@ -61,7 +61,7 @@
list_style_type::SpecifiedValue::none list_style_type::SpecifiedValue::none
% else: % else:
use values::generics::CounterStyleOrNone; use values::generics::CounterStyleOrNone;
list_style_type::SpecifiedValue(CounterStyleOrNone::None_) list_style_type::SpecifiedValue::CounterStyle(CounterStyleOrNone::None_)
% endif % endif
} }

View file

@ -5,7 +5,7 @@
//! Generic types that share their serialization implementations //! Generic types that share their serialization implementations
//! for both specified and computed values. //! for both specified and computed values.
use counter_style::parse_counter_style_name; use counter_style::{Symbols, parse_counter_style_name};
use cssparser::Parser; use cssparser::Parser;
use euclid::size::Size2D; use euclid::size::Size2D;
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
@ -64,16 +64,43 @@ impl<L: ToCss> ToCss for BorderRadiusSize<L> {
} }
} }
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
define_css_keyword_enum! { SymbolsType:
"cyclic" => Cyclic,
"numeric" => Numeric,
"alphabetic" => Alphabetic,
"symbolic" => Symbolic,
"fixed" => Fixed,
}
add_impls_for_keyword_enum!(SymbolsType);
#[cfg(feature = "gecko")]
impl SymbolsType {
/// Convert symbols type to their corresponding Gecko values.
pub fn to_gecko_keyword(self) -> u8 {
use gecko_bindings::structs;
match self {
SymbolsType::Cyclic => structs::NS_STYLE_COUNTER_SYSTEM_CYCLIC as u8,
SymbolsType::Numeric => structs::NS_STYLE_COUNTER_SYSTEM_NUMERIC as u8,
SymbolsType::Alphabetic => structs::NS_STYLE_COUNTER_SYSTEM_ALPHABETIC as u8,
SymbolsType::Symbolic => structs::NS_STYLE_COUNTER_SYSTEM_SYMBOLIC as u8,
SymbolsType::Fixed => structs::NS_STYLE_COUNTER_SYSTEM_FIXED as u8,
}
}
}
/// 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 /// Since wherever <counter-style> is used, 'none' is a valid value as
/// well, we combine them into one type to make code simpler. /// well, we combine them into one type to make code simpler.
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum CounterStyleOrNone { pub enum CounterStyleOrNone {
/// none /// none
None_, None_,
/// <counter-style-name> /// <counter-style-name>
Name(CustomIdent), Name(CustomIdent),
/// symbols()
Symbols(SymbolsType, Symbols),
} }
impl CounterStyleOrNone { impl CounterStyleOrNone {
@ -91,12 +118,32 @@ impl CounterStyleOrNone {
no_viewport_percentage!(CounterStyleOrNone); no_viewport_percentage!(CounterStyleOrNone);
impl Parse for CounterStyleOrNone { impl Parse for CounterStyleOrNone {
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
input.try(|input| { if let Ok(name) = input.try(|i| parse_counter_style_name(i)) {
parse_counter_style_name(input).map(CounterStyleOrNone::Name) return Ok(CounterStyleOrNone::Name(name));
}).or_else(|_| { }
input.expect_ident_matching("none").map(|_| CounterStyleOrNone::None_) if input.try(|i| i.expect_ident_matching("none")).is_ok() {
}) return Ok(CounterStyleOrNone::None_);
}
if input.try(|i| i.expect_function_matching("symbols")).is_ok() {
return input.parse_nested_block(|input| {
let symbols_type = input.try(|i| SymbolsType::parse(i))
.unwrap_or(SymbolsType::Symbolic);
let symbols = Symbols::parse(context, input)?;
// There must be at least two symbols for alphabetic or
// numeric system.
if (symbols_type == SymbolsType::Alphabetic ||
symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 {
return Err(());
}
// Identifier is not allowed in symbols() function.
if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) {
return Err(());
}
Ok(CounterStyleOrNone::Symbols(symbols_type, symbols))
});
}
Err(())
} }
} }
@ -106,6 +153,13 @@ impl ToCss for CounterStyleOrNone {
match self { match self {
&CounterStyleOrNone::None_ => dest.write_str("none"), &CounterStyleOrNone::None_ => dest.write_str("none"),
&CounterStyleOrNone::Name(ref name) => name.to_css(dest), &CounterStyleOrNone::Name(ref name) => name.to_css(dest),
&CounterStyleOrNone::Symbols(ref symbols_type, ref symbols) => {
dest.write_str("symbols(")?;
symbols_type.to_css(dest)?;
dest.write_str(" ")?;
symbols.to_css(dest)?;
dest.write_str(")")
}
} }
} }
} }

View file

@ -1844,7 +1844,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
}, },
FontStyle => longhands::font_style::computed_value::T::from_gecko_keyword(value).into(), FontStyle => longhands::font_style::computed_value::T::from_gecko_keyword(value).into(),
FontWeight => longhands::font_weight::SpecifiedValue::from_gecko_keyword(value), FontWeight => longhands::font_weight::SpecifiedValue::from_gecko_keyword(value),
ListStyleType => longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value), ListStyleType => Box::new(longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value)),
MozMathVariant => longhands::_moz_math_variant::SpecifiedValue::from_gecko_keyword(value), MozMathVariant => longhands::_moz_math_variant::SpecifiedValue::from_gecko_keyword(value),
WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value), WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value),
CaptionSide => longhands::caption_side::SpecifiedValue::from_gecko_keyword(value), CaptionSide => longhands::caption_side::SpecifiedValue::from_gecko_keyword(value),