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 Atom;
|
||||||
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
|
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
|
||||||
use cssparser::{Parser, Token, serialize_identifier, CowRcStr};
|
use cssparser::{Parser, Token, CowRcStr};
|
||||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||||
#[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
|
#[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::{ nsCSSCounterDesc, nsCSSValue };
|
#[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>
|
/// <https://drafts.csswg.org/css-counter-styles/#typedef-symbol>
|
||||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue)]
|
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss)]
|
||||||
pub enum Symbol {
|
pub enum Symbol {
|
||||||
/// <string>
|
/// <string>
|
||||||
String(String),
|
String(String),
|
||||||
/// <ident>
|
/// <custom-ident>
|
||||||
Ident(String),
|
Ident(CustomIdent),
|
||||||
// Not implemented:
|
// Not implemented:
|
||||||
// /// <image>
|
// /// <image>
|
||||||
// Image(Image),
|
// Image(Image),
|
||||||
|
@ -407,24 +407,16 @@ impl Parse for Symbol {
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
match *input.next()? {
|
match *input.next()? {
|
||||||
Token::QuotedString(ref s) => Ok(Symbol::String(s.as_ref().to_owned())),
|
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())),
|
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 {
|
impl Symbol {
|
||||||
/// Returns whether this symbol is allowed in symbols() function.
|
/// Returns whether this symbol is allowed in symbols() function.
|
||||||
pub fn is_allowed_in_symbols(&self) -> bool {
|
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>
|
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols>
|
||||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
#[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>);
|
pub struct Symbols(pub Vec<Symbol>);
|
||||||
|
|
||||||
impl Parse for Symbols {
|
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>
|
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-additive-symbols>
|
||||||
#[derive(Clone, Debug, ToCss)]
|
#[derive(Clone, Debug, ToCss)]
|
||||||
pub struct AdditiveSymbols(pub Vec<AdditiveTuple>);
|
pub struct AdditiveSymbols(pub Vec<AdditiveTuple>);
|
||||||
|
|
|
@ -313,7 +313,7 @@ impl ToNsCssValue for counter_style::Symbol {
|
||||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||||
match self {
|
match self {
|
||||||
counter_style::Symbol::String(s) => nscssvalue.set_string(&s),
|
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) {
|
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::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();
|
self.clear_text_emphasis_style_if_string();
|
||||||
let (te, s) = match v {
|
let (te, s) = match v {
|
||||||
T::None => (structs::NS_STYLE_TEXT_EMPHASIS_STYLE_NONE, ""),
|
T::None => (structs::NS_STYLE_TEXT_EMPHASIS_STYLE_NONE, ""),
|
||||||
T::Keyword(ref keyword) => {
|
T::Keyword(ref keyword) => {
|
||||||
let fill = if keyword.fill {
|
let fill = match keyword.fill {
|
||||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED
|
FillMode::Filled => structs::NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED,
|
||||||
} else {
|
FillMode::Open => structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN,
|
||||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN
|
|
||||||
};
|
};
|
||||||
let shape = match keyword.shape {
|
let shape = match keyword.shape {
|
||||||
ShapeKeyword::Dot => structs::NS_STYLE_TEXT_EMPHASIS_STYLE_DOT,
|
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 {
|
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::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 {
|
if self.gecko.mTextEmphasisStyle == structs::NS_STYLE_TEXT_EMPHASIS_STYLE_NONE as u8 {
|
||||||
return T::None;
|
return T::None;
|
||||||
|
@ -4771,7 +4770,11 @@ fn static_assert() {
|
||||||
return T::String(self.gecko.mTextEmphasisStyleString.to_string());
|
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 =
|
let shape =
|
||||||
match self.gecko.mTextEmphasisStyle as u32 & !structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN {
|
match self.gecko.mTextEmphasisStyle as u32 & !structs::NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN {
|
||||||
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_DOT => ShapeKeyword::Dot,
|
structs::NS_STYLE_TEXT_EMPHASIS_STYLE_DOT => ShapeKeyword::Dot,
|
||||||
|
|
|
@ -26,10 +26,9 @@ use properties::{LonghandId, ShorthandId};
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{cmp, ptr};
|
use std::{cmp, ptr};
|
||||||
use std::fmt::{self, Write};
|
|
||||||
use std::mem::{self, ManuallyDrop};
|
use std::mem::{self, ManuallyDrop};
|
||||||
#[cfg(feature = "gecko")] use hash::FnvHashMap;
|
#[cfg(feature = "gecko")] use hash::FnvHashMap;
|
||||||
use style_traits::{CssWriter, ParseError, ToCss};
|
use style_traits::ParseError;
|
||||||
use super::ComputedValues;
|
use super::ComputedValues;
|
||||||
use values::{CSSFloat, CustomIdent, Either};
|
use values::{CSSFloat, CustomIdent, Either};
|
||||||
use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
|
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.
|
/// 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
|
// NB: This needs to be here because it needs all the longhands generated
|
||||||
// beforehand.
|
// beforehand.
|
||||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)]
|
||||||
pub enum TransitionProperty {
|
pub enum TransitionProperty {
|
||||||
/// A shorthand.
|
/// A shorthand.
|
||||||
Shorthand(ShorthandId),
|
Shorthand(ShorthandId),
|
||||||
|
@ -90,19 +89,6 @@ pub enum TransitionProperty {
|
||||||
Unsupported(CustomIdent),
|
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);
|
trivial_to_computed_value!(TransitionProperty);
|
||||||
|
|
||||||
impl TransitionProperty {
|
impl TransitionProperty {
|
||||||
|
|
|
@ -199,11 +199,8 @@ ${helpers.predefined_type(
|
||||||
animation_value_type="discrete"
|
animation_value_type="discrete"
|
||||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-style">
|
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-style">
|
||||||
use computed_values::writing_mode::T as WritingMode;
|
use computed_values::writing_mode::T as WritingMode;
|
||||||
use std::fmt::{self, Write};
|
|
||||||
use style_traits::{CssWriter, ToCss};
|
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||||
#[cfg_attr(feature = "servo", derive(ToComputedValue))]
|
#[cfg_attr(feature = "servo", derive(ToComputedValue))]
|
||||||
|
@ -213,9 +210,9 @@ ${helpers.predefined_type(
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||||
pub struct KeywordValue {
|
pub struct KeywordValue {
|
||||||
pub fill: bool,
|
pub fill: super::FillMode,
|
||||||
pub shape: super::ShapeKeyword,
|
pub shape: super::ShapeKeyword,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,55 +224,22 @@ ${helpers.predefined_type(
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||||
pub enum KeywordValue {
|
pub enum KeywordValue {
|
||||||
Fill(bool),
|
Fill(FillMode),
|
||||||
Shape(ShapeKeyword),
|
Shape(ShapeKeyword),
|
||||||
FillAndShape(bool, ShapeKeyword),
|
FillAndShape(FillMode, 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeywordValue {
|
impl KeywordValue {
|
||||||
fn fill(&self) -> Option<bool> {
|
fn fill(&self) -> Option<FillMode> {
|
||||||
match *self {
|
match *self {
|
||||||
KeywordValue::Fill(fill) |
|
KeywordValue::Fill(fill) |
|
||||||
KeywordValue::FillAndShape(fill,_) => Some(fill),
|
KeywordValue::FillAndShape(fill, _) => Some(fill),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape(&self) -> Option<ShapeKeyword> {
|
fn shape(&self) -> Option<ShapeKeyword> {
|
||||||
match *self {
|
match *self {
|
||||||
KeywordValue::Shape(shape) |
|
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)]
|
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss)]
|
||||||
pub enum ShapeKeyword {
|
pub enum ShapeKeyword {
|
||||||
Dot,
|
Dot,
|
||||||
|
@ -295,7 +265,8 @@ ${helpers.predefined_type(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShapeKeyword {
|
impl ShapeKeyword {
|
||||||
pub fn char(&self, fill: bool) -> &str {
|
pub fn char(&self, fill: FillMode) -> &str {
|
||||||
|
let fill = fill == FillMode::Filled;
|
||||||
match *self {
|
match *self {
|
||||||
ShapeKeyword::Dot => if fill { "\u{2022}" } else { "\u{25e6}" },
|
ShapeKeyword::Dot => if fill { "\u{2022}" } else { "\u{25e6}" },
|
||||||
ShapeKeyword::Circle => if fill { "\u{25cf}" } else { "\u{25cb}" },
|
ShapeKeyword::Circle => if fill { "\u{25cf}" } else { "\u{25cb}" },
|
||||||
|
@ -330,7 +301,7 @@ ${helpers.predefined_type(
|
||||||
ShapeKeyword::Sesame
|
ShapeKeyword::Sesame
|
||||||
};
|
};
|
||||||
computed_value::T::Keyword(computed_value::KeywordValue {
|
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),
|
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>)
|
pub fn parse<'i, 't>(
|
||||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
_context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<SpecifiedValue, ParseError<'i>> {
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(SpecifiedValue::None);
|
return Ok(SpecifiedValue::None);
|
||||||
}
|
}
|
||||||
|
@ -366,21 +339,17 @@ ${helpers.predefined_type(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a pair of keywords
|
// Handle a pair of keywords
|
||||||
let mut shape = input.try(ShapeKeyword::parse);
|
let mut shape = input.try(ShapeKeyword::parse).ok();
|
||||||
let fill = if input.try(|input| input.expect_ident_matching("filled")).is_ok() {
|
let fill = input.try(FillMode::parse).ok();
|
||||||
Some(true)
|
if shape.is_none() {
|
||||||
} else if input.try(|input| input.expect_ident_matching("open")).is_ok() {
|
shape = input.try(ShapeKeyword::parse).ok();
|
||||||
Some(false)
|
|
||||||
} else { None };
|
|
||||||
if shape.is_err() {
|
|
||||||
shape = input.try(ShapeKeyword::parse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// At least one of shape or fill must be handled
|
// At least one of shape or fill must be handled
|
||||||
let keyword_value = match (fill, shape) {
|
let keyword_value = match (fill, shape) {
|
||||||
(Some(fill), Ok(shape)) => KeywordValue::FillAndShape(fill,shape),
|
(Some(fill), Some(shape)) => KeywordValue::FillAndShape(fill, shape),
|
||||||
(Some(fill), Err(_)) => KeywordValue::Fill(fill),
|
(Some(fill), None) => KeywordValue::Fill(fill),
|
||||||
(None, Ok(shape)) => KeywordValue::Shape(shape),
|
(None, Some(shape)) => KeywordValue::Shape(shape),
|
||||||
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
};
|
};
|
||||||
Ok(SpecifiedValue::Keyword(keyword_value))
|
Ok(SpecifiedValue::Keyword(keyword_value))
|
||||||
|
|
|
@ -800,6 +800,16 @@ pub enum LonghandId {
|
||||||
% endfor
|
% 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 {
|
impl fmt::Debug for LonghandId {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter.write_str(self.name())
|
formatter.write_str(self.name())
|
||||||
|
@ -1130,7 +1140,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identifier for a given shorthand property.
|
/// 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 {
|
pub enum ShorthandId {
|
||||||
% for property in data.shorthands:
|
% for property in data.shorthands:
|
||||||
/// ${property.name}
|
/// ${property.name}
|
||||||
|
@ -1138,6 +1148,16 @@ pub enum ShorthandId {
|
||||||
% endfor
|
% 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 {
|
impl ShorthandId {
|
||||||
/// Get the name for this shorthand property.
|
/// Get the name for this shorthand property.
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl DeepCloneWithLock for DocumentRule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A URL matching function for a `@document` rule's condition.
|
/// A URL matching function for a `@document` rule's condition.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, ToCss)]
|
||||||
pub enum UrlMatchingFunction {
|
pub enum UrlMatchingFunction {
|
||||||
/// Exact URL matching function. It evaluates to true whenever the
|
/// Exact URL matching function. It evaluates to true whenever the
|
||||||
/// URL of the document being styled is exactly the URL given.
|
/// 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
|
/// function as an initial substring (which is true when the two
|
||||||
/// strings are equal). When the argument is the empty string,
|
/// strings are equal). When the argument is the empty string,
|
||||||
/// it evaluates to true for all documents.
|
/// it evaluates to true for all documents.
|
||||||
|
#[css(function)]
|
||||||
UrlPrefix(String),
|
UrlPrefix(String),
|
||||||
/// Domain matching function. It evaluates to true whenever the URL
|
/// Domain matching function. It evaluates to true whenever the URL
|
||||||
/// of the document being styled has a host subcomponent and that
|
/// 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
|
/// function or a final substring of the host component is a
|
||||||
/// period (U+002E) immediately followed by the argument to the
|
/// period (U+002E) immediately followed by the argument to the
|
||||||
/// ‘domain()’ function.
|
/// ‘domain()’ function.
|
||||||
|
#[css(function)]
|
||||||
Domain(String),
|
Domain(String),
|
||||||
/// Regular expression matching function. It evaluates to true
|
/// Regular expression matching function. It evaluates to true
|
||||||
/// whenever the regular expression matches the entirety of the URL
|
/// whenever the regular expression matches the entirety of the URL
|
||||||
/// of the document being styled.
|
/// of the document being styled.
|
||||||
RegExp(String),
|
#[css(function)]
|
||||||
|
Regexp(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! parse_quoted_or_unquoted_string {
|
macro_rules! parse_quoted_or_unquoted_string {
|
||||||
|
@ -125,7 +128,7 @@ impl UrlMatchingFunction {
|
||||||
parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
|
parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
|
||||||
} else if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
|
} else if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
|
||||||
input.parse_nested_block(|input| {
|
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)) {
|
} else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
|
||||||
Ok(UrlMatchingFunction::Url(url))
|
Ok(UrlMatchingFunction::Url(url))
|
||||||
|
@ -145,14 +148,14 @@ impl UrlMatchingFunction {
|
||||||
UrlMatchingFunction::Url(_) => GeckoUrlMatchingFunction::eURL,
|
UrlMatchingFunction::Url(_) => GeckoUrlMatchingFunction::eURL,
|
||||||
UrlMatchingFunction::UrlPrefix(_) => GeckoUrlMatchingFunction::eURLPrefix,
|
UrlMatchingFunction::UrlPrefix(_) => GeckoUrlMatchingFunction::eURLPrefix,
|
||||||
UrlMatchingFunction::Domain(_) => GeckoUrlMatchingFunction::eDomain,
|
UrlMatchingFunction::Domain(_) => GeckoUrlMatchingFunction::eDomain,
|
||||||
UrlMatchingFunction::RegExp(_) => GeckoUrlMatchingFunction::eRegExp,
|
UrlMatchingFunction::Regexp(_) => GeckoUrlMatchingFunction::eRegExp,
|
||||||
};
|
};
|
||||||
|
|
||||||
let pattern = nsCStr::from(match *self {
|
let pattern = nsCStr::from(match *self {
|
||||||
UrlMatchingFunction::Url(ref url) => url.as_str(),
|
UrlMatchingFunction::Url(ref url) => url.as_str(),
|
||||||
UrlMatchingFunction::UrlPrefix(ref pat) |
|
UrlMatchingFunction::UrlPrefix(ref pat) |
|
||||||
UrlMatchingFunction::Domain(ref pat) |
|
UrlMatchingFunction::Domain(ref pat) |
|
||||||
UrlMatchingFunction::RegExp(ref pat) => pat,
|
UrlMatchingFunction::Regexp(ref pat) => pat,
|
||||||
});
|
});
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func)
|
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.
|
/// A `@document` rule's condition.
|
||||||
///
|
///
|
||||||
/// <https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#at-document>
|
/// <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
|
/// The `@document` rule's condition is written as a comma-separated list of
|
||||||
/// URL matching functions, and the condition evaluates to true whenever any
|
/// URL matching functions, and the condition evaluates to true whenever any
|
||||||
/// one of those functions evaluates to true.
|
/// one of those functions evaluates to true.
|
||||||
#[derive(Clone, Debug)]
|
#[css(comma, iterable)]
|
||||||
|
#[derive(Clone, Debug, ToCss)]
|
||||||
pub struct DocumentCondition(Vec<UrlMatchingFunction>);
|
pub struct DocumentCondition(Vec<UrlMatchingFunction>);
|
||||||
|
|
||||||
impl DocumentCondition {
|
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.
|
/// 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>);
|
pub struct PairValues(pub u32, pub Option<u32>);
|
||||||
|
|
||||||
impl Parse for PairValues {
|
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")]
|
#[cfg(feature = "gecko")]
|
||||||
impl ToGeckoFontFeatureValues for PairValues {
|
impl ToGeckoFontFeatureValues for PairValues {
|
||||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
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.
|
/// 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>);
|
pub struct VectorValues(pub Vec<u32>);
|
||||||
|
|
||||||
impl Parse for VectorValues {
|
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")]
|
#[cfg(feature = "gecko")]
|
||||||
impl ToGeckoFontFeatureValues for VectorValues {
|
impl ToGeckoFontFeatureValues for VectorValues {
|
||||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
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
|
/// A keyframes selector is a list of percentages or from/to symbols, which are
|
||||||
/// converted at parse time to percentages.
|
/// 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>);
|
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 {
|
impl KeyframeSelector {
|
||||||
/// Return the list of percentages this selector contains.
|
/// Return the list of percentages this selector contains.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -143,26 +143,14 @@ trait FromMeta: Sized {
|
||||||
/// See:
|
/// See:
|
||||||
/// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc
|
/// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc
|
||||||
/// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom
|
/// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||||
|
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||||
pub enum ViewportLength {
|
pub enum ViewportLength {
|
||||||
Specified(LengthOrPercentageOrAuto),
|
Specified(LengthOrPercentageOrAuto),
|
||||||
ExtendToZoom
|
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 {
|
impl FromMeta for ViewportLength {
|
||||||
fn from_meta(value: &str) -> Option<ViewportLength> {
|
fn from_meta(value: &str) -> Option<ViewportLength> {
|
||||||
macro_rules! specified {
|
macro_rules! specified {
|
||||||
|
|
|
@ -131,6 +131,8 @@ struct CssInputAttrs {
|
||||||
derive_debug: bool,
|
derive_debug: bool,
|
||||||
function: Option<Function>,
|
function: Option<Function>,
|
||||||
comma: bool,
|
comma: bool,
|
||||||
|
// Here because structs variants are also their whole type definition.
|
||||||
|
iterable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[darling(attributes(css), default)]
|
#[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": [
|
||||||
[
|
[
|
||||||
"/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": [
|
"css/css-display/OWNERS": [
|
||||||
[
|
[
|
||||||
{}
|
{}
|
||||||
|
@ -484992,6 +485009,14 @@
|
||||||
"dbfaae0538c8cd1e759b59712f53cd17388e7c48",
|
"dbfaae0538c8cd1e759b59712f53cd17388e7c48",
|
||||||
"manual"
|
"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": [
|
"css/css-counter-styles/cambodian/css3-counter-styles-158.html": [
|
||||||
"a334bd087e7a808567daeeae419a80466a377ef3",
|
"a334bd087e7a808567daeeae419a80466a377ef3",
|
||||||
"manual"
|
"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