mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Auto merge of #20178 - servo:derive-all-the-things, r=emilio
Derive ToCss for some more stuff <!-- 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/20178) <!-- Reviewable:end -->
This commit is contained in:
commit
0c9be9f776
14 changed files with 133 additions and 233 deletions
|
@ -8,7 +8,7 @@
|
|||
|
||||
use Atom;
|
||||
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
|
||||
use cssparser::{Parser, Token, serialize_identifier, CowRcStr};
|
||||
use cssparser::{Parser, Token, CowRcStr};
|
||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||
#[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
|
||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::{ nsCSSCounterDesc, nsCSSValue };
|
||||
|
@ -391,12 +391,12 @@ impl ToCss for System {
|
|||
|
||||
/// <https://drafts.csswg.org/css-counter-styles/#typedef-symbol>
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum Symbol {
|
||||
/// <string>
|
||||
String(String),
|
||||
/// <ident>
|
||||
Ident(String),
|
||||
/// <custom-ident>
|
||||
Ident(CustomIdent),
|
||||
// Not implemented:
|
||||
// /// <image>
|
||||
// Image(Image),
|
||||
|
@ -407,24 +407,16 @@ impl Parse for Symbol {
|
|||
let location = input.current_source_location();
|
||||
match *input.next()? {
|
||||
Token::QuotedString(ref s) => Ok(Symbol::String(s.as_ref().to_owned())),
|
||||
Token::Ident(ref s) => Ok(Symbol::Ident(s.as_ref().to_owned())),
|
||||
Token::Ident(ref s) => {
|
||||
Ok(Symbol::Ident(
|
||||
CustomIdent::from_ident(location, s, &[])?,
|
||||
))
|
||||
}
|
||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for Symbol {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
match *self {
|
||||
Symbol::String(ref s) => s.to_css(dest),
|
||||
Symbol::Ident(ref s) => serialize_identifier(s, dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
/// Returns whether this symbol is allowed in symbols() function.
|
||||
pub fn is_allowed_in_symbols(&self) -> bool {
|
||||
|
@ -550,7 +542,8 @@ impl Parse for Fallback {
|
|||
|
||||
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols>
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue)]
|
||||
#[css(iterable)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss)]
|
||||
pub struct Symbols(pub Vec<Symbol>);
|
||||
|
||||
impl Parse for Symbols {
|
||||
|
@ -570,22 +563,6 @@ impl Parse for Symbols {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for Symbols {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
let mut iter = self.0.iter();
|
||||
let first = iter.next().expect("expected at least one symbol");
|
||||
first.to_css(dest)?;
|
||||
for item in iter {
|
||||
dest.write_char(' ')?;
|
||||
item.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-additive-symbols>
|
||||
#[derive(Clone, Debug, ToCss)]
|
||||
pub struct AdditiveSymbols(pub Vec<AdditiveTuple>);
|
||||
|
|
|
@ -313,7 +313,7 @@ impl ToNsCssValue for counter_style::Symbol {
|
|||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
match self {
|
||||
counter_style::Symbol::String(s) => nscssvalue.set_string(&s),
|
||||
counter_style::Symbol::Ident(s) => nscssvalue.set_ident(&s),
|
||||
counter_style::Symbol::Ident(s) => nscssvalue.set_ident_from_atom(&s.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4719,16 +4719,15 @@ fn static_assert() {
|
|||
|
||||
pub fn set_text_emphasis_style(&mut self, v: longhands::text_emphasis_style::computed_value::T) {
|
||||
use properties::longhands::text_emphasis_style::computed_value::T;
|
||||
use properties::longhands::text_emphasis_style::ShapeKeyword;
|
||||
use properties::longhands::text_emphasis_style::{FillMode, ShapeKeyword};
|
||||
|
||||
self.clear_text_emphasis_style_if_string();
|
||||
let (te, s) = match v {
|
||||
T::None => (structs::NS_STYLE_TEXT_EMPHASIS_STYLE_NONE, ""),
|
||||
T::Keyword(ref keyword) => {
|
||||
let fill = if keyword.fill {
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED
|
||||
} else {
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN
|
||||
let fill = match keyword.fill {
|
||||
FillMode::Filled => structs::NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED,
|
||||
FillMode::Open => structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN,
|
||||
};
|
||||
let shape = match keyword.shape {
|
||||
ShapeKeyword::Dot => structs::NS_STYLE_TEXT_EMPHASIS_STYLE_DOT,
|
||||
|
@ -4763,7 +4762,7 @@ fn static_assert() {
|
|||
|
||||
pub fn clone_text_emphasis_style(&self) -> longhands::text_emphasis_style::computed_value::T {
|
||||
use properties::longhands::text_emphasis_style::computed_value::{T, KeywordValue};
|
||||
use properties::longhands::text_emphasis_style::ShapeKeyword;
|
||||
use properties::longhands::text_emphasis_style::{FillMode, ShapeKeyword};
|
||||
|
||||
if self.gecko.mTextEmphasisStyle == structs::NS_STYLE_TEXT_EMPHASIS_STYLE_NONE as u8 {
|
||||
return T::None;
|
||||
|
@ -4771,7 +4770,11 @@ fn static_assert() {
|
|||
return T::String(self.gecko.mTextEmphasisStyleString.to_string());
|
||||
}
|
||||
|
||||
let fill = self.gecko.mTextEmphasisStyle & structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN as u8 == 0;
|
||||
let fill = match self.gecko.mTextEmphasisStyle as u32 {
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED => FillMode::Filled,
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN => FillMode::Open,
|
||||
_ => panic!("Unexpected value in style struct for text-emphasis-style property"),
|
||||
};
|
||||
let shape =
|
||||
match self.gecko.mTextEmphasisStyle as u32 & !structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN {
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_DOT => ShapeKeyword::Dot,
|
||||
|
|
|
@ -26,10 +26,9 @@ use properties::{LonghandId, ShorthandId};
|
|||
use servo_arc::Arc;
|
||||
use smallvec::SmallVec;
|
||||
use std::{cmp, ptr};
|
||||
use std::fmt::{self, Write};
|
||||
use std::mem::{self, ManuallyDrop};
|
||||
#[cfg(feature = "gecko")] use hash::FnvHashMap;
|
||||
use style_traits::{CssWriter, ParseError, ToCss};
|
||||
use style_traits::ParseError;
|
||||
use super::ComputedValues;
|
||||
use values::{CSSFloat, CustomIdent, Either};
|
||||
use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
||||
|
@ -79,7 +78,7 @@ pub fn nscsspropertyid_is_animatable(property: nsCSSPropertyID) -> bool {
|
|||
/// a shorthand with at least one transitionable longhand component, or an unsupported property.
|
||||
// NB: This needs to be here because it needs all the longhands generated
|
||||
// beforehand.
|
||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub enum TransitionProperty {
|
||||
/// A shorthand.
|
||||
Shorthand(ShorthandId),
|
||||
|
@ -90,19 +89,6 @@ pub enum TransitionProperty {
|
|||
Unsupported(CustomIdent),
|
||||
}
|
||||
|
||||
impl ToCss for TransitionProperty {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
match *self {
|
||||
TransitionProperty::Shorthand(ref id) => dest.write_str(id.name()),
|
||||
TransitionProperty::Longhand(ref id) => dest.write_str(id.name()),
|
||||
TransitionProperty::Unsupported(ref id) => id.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trivial_to_computed_value!(TransitionProperty);
|
||||
|
||||
impl TransitionProperty {
|
||||
|
|
|
@ -199,11 +199,8 @@ ${helpers.predefined_type(
|
|||
animation_value_type="discrete"
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-style">
|
||||
use computed_values::writing_mode::T as WritingMode;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
|
||||
pub mod computed_value {
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
#[cfg_attr(feature = "servo", derive(ToComputedValue))]
|
||||
|
@ -213,9 +210,9 @@ ${helpers.predefined_type(
|
|||
String(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub struct KeywordValue {
|
||||
pub fill: bool,
|
||||
pub fill: super::FillMode,
|
||||
pub shape: super::ShapeKeyword,
|
||||
}
|
||||
}
|
||||
|
@ -227,55 +224,22 @@ ${helpers.predefined_type(
|
|||
String(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub enum KeywordValue {
|
||||
Fill(bool),
|
||||
Fill(FillMode),
|
||||
Shape(ShapeKeyword),
|
||||
FillAndShape(bool, ShapeKeyword),
|
||||
}
|
||||
|
||||
impl ToCss for KeywordValue {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
if let Some(fill) = self.fill() {
|
||||
if fill {
|
||||
dest.write_str("filled")?;
|
||||
} else {
|
||||
dest.write_str("open")?;
|
||||
}
|
||||
}
|
||||
if let Some(shape) = self.shape() {
|
||||
if self.fill().is_some() {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
shape.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for computed_value::KeywordValue {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.fill {
|
||||
dest.write_str("filled")?;
|
||||
} else {
|
||||
dest.write_str("open")?;
|
||||
}
|
||||
dest.write_str(" ")?;
|
||||
self.shape.to_css(dest)
|
||||
}
|
||||
FillAndShape(FillMode, ShapeKeyword),
|
||||
}
|
||||
|
||||
impl KeywordValue {
|
||||
fn fill(&self) -> Option<bool> {
|
||||
fn fill(&self) -> Option<FillMode> {
|
||||
match *self {
|
||||
KeywordValue::Fill(fill) |
|
||||
KeywordValue::FillAndShape(fill,_) => Some(fill),
|
||||
KeywordValue::FillAndShape(fill, _) => Some(fill),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn shape(&self) -> Option<ShapeKeyword> {
|
||||
match *self {
|
||||
KeywordValue::Shape(shape) |
|
||||
|
@ -285,6 +249,12 @@ ${helpers.predefined_type(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, ToCss)]
|
||||
pub enum FillMode {
|
||||
Filled,
|
||||
Open,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss)]
|
||||
pub enum ShapeKeyword {
|
||||
Dot,
|
||||
|
@ -295,7 +265,8 @@ ${helpers.predefined_type(
|
|||
}
|
||||
|
||||
impl ShapeKeyword {
|
||||
pub fn char(&self, fill: bool) -> &str {
|
||||
pub fn char(&self, fill: FillMode) -> &str {
|
||||
let fill = fill == FillMode::Filled;
|
||||
match *self {
|
||||
ShapeKeyword::Dot => if fill { "\u{2022}" } else { "\u{25e6}" },
|
||||
ShapeKeyword::Circle => if fill { "\u{25cf}" } else { "\u{25cb}" },
|
||||
|
@ -330,7 +301,7 @@ ${helpers.predefined_type(
|
|||
ShapeKeyword::Sesame
|
||||
};
|
||||
computed_value::T::Keyword(computed_value::KeywordValue {
|
||||
fill: keyword.fill().unwrap_or(true),
|
||||
fill: keyword.fill().unwrap_or(FillMode::Filled),
|
||||
shape: keyword.shape().unwrap_or(default_shape),
|
||||
})
|
||||
},
|
||||
|
@ -354,8 +325,10 @@ ${helpers.predefined_type(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
||||
pub fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<SpecifiedValue, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(SpecifiedValue::None);
|
||||
}
|
||||
|
@ -366,21 +339,17 @@ ${helpers.predefined_type(
|
|||
}
|
||||
|
||||
// Handle a pair of keywords
|
||||
let mut shape = input.try(ShapeKeyword::parse);
|
||||
let fill = if input.try(|input| input.expect_ident_matching("filled")).is_ok() {
|
||||
Some(true)
|
||||
} else if input.try(|input| input.expect_ident_matching("open")).is_ok() {
|
||||
Some(false)
|
||||
} else { None };
|
||||
if shape.is_err() {
|
||||
shape = input.try(ShapeKeyword::parse);
|
||||
let mut shape = input.try(ShapeKeyword::parse).ok();
|
||||
let fill = input.try(FillMode::parse).ok();
|
||||
if shape.is_none() {
|
||||
shape = input.try(ShapeKeyword::parse).ok();
|
||||
}
|
||||
|
||||
// At least one of shape or fill must be handled
|
||||
let keyword_value = match (fill, shape) {
|
||||
(Some(fill), Ok(shape)) => KeywordValue::FillAndShape(fill,shape),
|
||||
(Some(fill), Err(_)) => KeywordValue::Fill(fill),
|
||||
(None, Ok(shape)) => KeywordValue::Shape(shape),
|
||||
(Some(fill), Some(shape)) => KeywordValue::FillAndShape(fill, shape),
|
||||
(Some(fill), None) => KeywordValue::Fill(fill),
|
||||
(None, Some(shape)) => KeywordValue::Shape(shape),
|
||||
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||
};
|
||||
Ok(SpecifiedValue::Keyword(keyword_value))
|
||||
|
|
|
@ -800,6 +800,16 @@ pub enum LonghandId {
|
|||
% endfor
|
||||
}
|
||||
|
||||
impl ToCss for LonghandId {
|
||||
#[inline]
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
dest.write_str(self.name())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for LonghandId {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(self.name())
|
||||
|
@ -1130,7 +1140,7 @@ where
|
|||
}
|
||||
|
||||
/// An identifier for a given shorthand property.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||
pub enum ShorthandId {
|
||||
% for property in data.shorthands:
|
||||
/// ${property.name}
|
||||
|
@ -1138,6 +1148,16 @@ pub enum ShorthandId {
|
|||
% endfor
|
||||
}
|
||||
|
||||
impl ToCss for ShorthandId {
|
||||
#[inline]
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
dest.write_str(self.name())
|
||||
}
|
||||
}
|
||||
|
||||
impl ShorthandId {
|
||||
/// Get the name for this shorthand property.
|
||||
pub fn name(&self) -> &'static str {
|
||||
|
|
|
@ -71,7 +71,7 @@ impl DeepCloneWithLock for DocumentRule {
|
|||
}
|
||||
|
||||
/// A URL matching function for a `@document` rule's condition.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, ToCss)]
|
||||
pub enum UrlMatchingFunction {
|
||||
/// Exact URL matching function. It evaluates to true whenever the
|
||||
/// URL of the document being styled is exactly the URL given.
|
||||
|
@ -81,6 +81,7 @@ pub enum UrlMatchingFunction {
|
|||
/// function as an initial substring (which is true when the two
|
||||
/// strings are equal). When the argument is the empty string,
|
||||
/// it evaluates to true for all documents.
|
||||
#[css(function)]
|
||||
UrlPrefix(String),
|
||||
/// Domain matching function. It evaluates to true whenever the URL
|
||||
/// of the document being styled has a host subcomponent and that
|
||||
|
@ -88,11 +89,13 @@ pub enum UrlMatchingFunction {
|
|||
/// function or a final substring of the host component is a
|
||||
/// period (U+002E) immediately followed by the argument to the
|
||||
/// ‘domain()’ function.
|
||||
#[css(function)]
|
||||
Domain(String),
|
||||
/// Regular expression matching function. It evaluates to true
|
||||
/// whenever the regular expression matches the entirety of the URL
|
||||
/// of the document being styled.
|
||||
RegExp(String),
|
||||
#[css(function)]
|
||||
Regexp(String),
|
||||
}
|
||||
|
||||
macro_rules! parse_quoted_or_unquoted_string {
|
||||
|
@ -125,7 +128,7 @@ impl UrlMatchingFunction {
|
|||
parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
|
||||
} else if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
|
||||
input.parse_nested_block(|input| {
|
||||
Ok(UrlMatchingFunction::RegExp(input.expect_string()?.as_ref().to_owned()))
|
||||
Ok(UrlMatchingFunction::Regexp(input.expect_string()?.as_ref().to_owned()))
|
||||
})
|
||||
} else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
|
||||
Ok(UrlMatchingFunction::Url(url))
|
||||
|
@ -145,14 +148,14 @@ impl UrlMatchingFunction {
|
|||
UrlMatchingFunction::Url(_) => GeckoUrlMatchingFunction::eURL,
|
||||
UrlMatchingFunction::UrlPrefix(_) => GeckoUrlMatchingFunction::eURLPrefix,
|
||||
UrlMatchingFunction::Domain(_) => GeckoUrlMatchingFunction::eDomain,
|
||||
UrlMatchingFunction::RegExp(_) => GeckoUrlMatchingFunction::eRegExp,
|
||||
UrlMatchingFunction::Regexp(_) => GeckoUrlMatchingFunction::eRegExp,
|
||||
};
|
||||
|
||||
let pattern = nsCStr::from(match *self {
|
||||
UrlMatchingFunction::Url(ref url) => url.as_str(),
|
||||
UrlMatchingFunction::UrlPrefix(ref pat) |
|
||||
UrlMatchingFunction::Domain(ref pat) |
|
||||
UrlMatchingFunction::RegExp(ref pat) => pat,
|
||||
UrlMatchingFunction::Regexp(ref pat) => pat,
|
||||
});
|
||||
unsafe {
|
||||
Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func)
|
||||
|
@ -166,34 +169,6 @@ impl UrlMatchingFunction {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for UrlMatchingFunction {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
match *self {
|
||||
UrlMatchingFunction::Url(ref url) => {
|
||||
url.to_css(dest)
|
||||
},
|
||||
UrlMatchingFunction::UrlPrefix(ref url_prefix) => {
|
||||
dest.write_str("url-prefix(")?;
|
||||
url_prefix.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
},
|
||||
UrlMatchingFunction::Domain(ref domain) => {
|
||||
dest.write_str("domain(")?;
|
||||
domain.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
},
|
||||
UrlMatchingFunction::RegExp(ref regex) => {
|
||||
dest.write_str("regexp(")?;
|
||||
regex.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A `@document` rule's condition.
|
||||
///
|
||||
/// <https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#at-document>
|
||||
|
@ -201,7 +176,8 @@ impl ToCss for UrlMatchingFunction {
|
|||
/// The `@document` rule's condition is written as a comma-separated list of
|
||||
/// URL matching functions, and the condition evaluates to true whenever any
|
||||
/// one of those functions evaluates to true.
|
||||
#[derive(Clone, Debug)]
|
||||
#[css(comma, iterable)]
|
||||
#[derive(Clone, Debug, ToCss)]
|
||||
pub struct DocumentCondition(Vec<UrlMatchingFunction>);
|
||||
|
||||
impl DocumentCondition {
|
||||
|
@ -219,20 +195,3 @@ impl DocumentCondition {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for DocumentCondition {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
let mut iter = self.0.iter();
|
||||
let first = iter.next()
|
||||
.expect("Empty DocumentCondition, should contain at least one URL matching function");
|
||||
first.to_css(dest)?;
|
||||
for url_matching_function in iter {
|
||||
dest.write_str(", ")?;
|
||||
url_matching_function.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ impl ToGeckoFontFeatureValues for SingleValue {
|
|||
}
|
||||
|
||||
/// A @font-feature-values block declaration value that keeps one or two values.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||
pub struct PairValues(pub u32, pub Option<u32>);
|
||||
|
||||
impl Parse for PairValues {
|
||||
|
@ -104,20 +104,6 @@ impl Parse for PairValues {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for PairValues {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
self.0.to_css(dest)?;
|
||||
if let Some(second) = self.1 {
|
||||
dest.write_char(' ')?;
|
||||
second.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for PairValues {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
|
@ -132,7 +118,8 @@ impl ToGeckoFontFeatureValues for PairValues {
|
|||
}
|
||||
|
||||
/// A @font-feature-values block declaration value that keeps a list of values.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[css(iterable)]
|
||||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||
pub struct VectorValues(pub Vec<u32>);
|
||||
|
||||
impl Parse for VectorValues {
|
||||
|
@ -159,24 +146,6 @@ impl Parse for VectorValues {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for VectorValues {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
let mut iter = self.0.iter();
|
||||
let first = iter.next();
|
||||
if let Some(first) = first {
|
||||
first.to_css(dest)?;
|
||||
for value in iter {
|
||||
dest.write_char(' ')?;
|
||||
value.to_css(dest)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for VectorValues {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
|
|
|
@ -145,24 +145,10 @@ impl KeyframePercentage {
|
|||
|
||||
/// A keyframes selector is a list of percentages or from/to symbols, which are
|
||||
/// converted at parse time to percentages.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[css(comma, iterable)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
|
||||
pub struct KeyframeSelector(Vec<KeyframePercentage>);
|
||||
|
||||
impl ToCss for KeyframeSelector {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
let mut iter = self.0.iter();
|
||||
iter.next().unwrap().to_css(dest)?;
|
||||
for percentage in iter {
|
||||
dest.write_str(", ")?;
|
||||
percentage.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyframeSelector {
|
||||
/// Return the list of percentages this selector contains.
|
||||
#[inline]
|
||||
|
|
|
@ -143,26 +143,14 @@ trait FromMeta: Sized {
|
|||
/// See:
|
||||
/// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc
|
||||
/// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||
pub enum ViewportLength {
|
||||
Specified(LengthOrPercentageOrAuto),
|
||||
ExtendToZoom
|
||||
}
|
||||
|
||||
impl ToCss for ViewportLength {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
match *self {
|
||||
ViewportLength::Specified(ref length) => length.to_css(dest),
|
||||
ViewportLength::ExtendToZoom => dest.write_str("extend-to-zoom"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromMeta for ViewportLength {
|
||||
fn from_meta(value: &str) -> Option<ViewportLength> {
|
||||
macro_rules! specified {
|
||||
|
|
|
@ -131,6 +131,8 @@ struct CssInputAttrs {
|
|||
derive_debug: bool,
|
||||
function: Option<Function>,
|
||||
comma: bool,
|
||||
// Here because structs variants are also their whole type definition.
|
||||
iterable: bool,
|
||||
}
|
||||
|
||||
#[darling(attributes(css), default)]
|
||||
|
|
|
@ -106113,6 +106113,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-counter-styles/broken-symbols.htm": [
|
||||
[
|
||||
"/css/css-counter-styles/broken-symbols.htm",
|
||||
[
|
||||
[
|
||||
"/css/css-counter-styles/broken-symbols-ref.htm",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-display/display-contents-alignment-001.html": [
|
||||
[
|
||||
"/css/css-display/display-contents-alignment-001.html",
|
||||
|
@ -237304,6 +237316,11 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-counter-styles/broken-symbols-ref.htm": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-display/OWNERS": [
|
||||
[
|
||||
{}
|
||||
|
@ -484992,6 +485009,14 @@
|
|||
"dbfaae0538c8cd1e759b59712f53cd17388e7c48",
|
||||
"manual"
|
||||
],
|
||||
"css/css-counter-styles/broken-symbols-ref.htm": [
|
||||
"c794c4b6846212f4ed27e618cdd32a28b8ce013c",
|
||||
"support"
|
||||
],
|
||||
"css/css-counter-styles/broken-symbols.htm": [
|
||||
"23cb132e8efcdd1020e12c89c9d30a333708b72e",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-counter-styles/cambodian/css3-counter-styles-158.html": [
|
||||
"a334bd087e7a808567daeeae419a80466a377ef3",
|
||||
"manual"
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="UTF-8">
|
||||
<ol><li>Should have "1." as bullet point.</ol>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="UTF-8">
|
||||
<title>CSS Test: invalid counter-style symbols</title>
|
||||
<link rel="author" title="Anthony Ramine" href="mailto:n.oxyde@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-counter-styles-3/#typedef-symbol">
|
||||
<link rel="match" href="broken-symbols-ref.htm">
|
||||
<style type="text/css">
|
||||
@counter-style a {
|
||||
system: alphabetic;
|
||||
symbols: ⓐ inherit;
|
||||
}
|
||||
</style>
|
||||
<ol style="list-style-type: a"><li>Should have "1." as bullet point.</ol>
|
Loading…
Add table
Add a link
Reference in a new issue