mirror of
https://github.com/servo/servo.git
synced 2025-06-23 08:34:42 +01:00
Auto merge of #17209 - servo:derive-all-the-things, r=emilio
Introduce more generics and more deriving <!-- 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/17209) <!-- Reviewable:end -->
This commit is contained in:
commit
738483742c
20 changed files with 153 additions and 323 deletions
|
@ -3894,18 +3894,18 @@ fn static_assert() {
|
|||
}
|
||||
|
||||
pub fn set_initial_letter(&mut self, v: longhands::initial_letter::computed_value::T) {
|
||||
use properties::longhands::initial_letter::computed_value::T;
|
||||
use values::generics::text::InitialLetter;
|
||||
match v {
|
||||
T::Normal => {
|
||||
InitialLetter::Normal => {
|
||||
self.gecko.mInitialLetterSize = 0.;
|
||||
self.gecko.mInitialLetterSink = 0;
|
||||
},
|
||||
T::Specified(size, sink) => {
|
||||
self.gecko.mInitialLetterSize = size.get();
|
||||
InitialLetter::Specified(size, sink) => {
|
||||
self.gecko.mInitialLetterSize = size;
|
||||
if let Some(sink) = sink {
|
||||
self.gecko.mInitialLetterSink = sink.value();
|
||||
self.gecko.mInitialLetterSink = sink;
|
||||
} else {
|
||||
self.gecko.mInitialLetterSink = size.get().floor() as i32;
|
||||
self.gecko.mInitialLetterSink = size.floor() as i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -545,8 +545,6 @@ ${helpers.predefined_type("animation-timing-function",
|
|||
extra_prefixes="moz webkit"
|
||||
spec="https://drafts.csswg.org/css-animations/#propdef-animation-iteration-count",
|
||||
allowed_in_keyframe_block="False">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
|
||||
pub mod computed_value {
|
||||
|
@ -554,8 +552,8 @@ ${helpers.predefined_type("animation-timing-function",
|
|||
}
|
||||
|
||||
// https://drafts.csswg.org/css-animations/#animation-iteration-count
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Debug, Clone, PartialEq, ToCss)]
|
||||
pub enum SpecifiedValue {
|
||||
Number(f32),
|
||||
Infinite,
|
||||
|
@ -576,15 +574,6 @@ ${helpers.predefined_type("animation-timing-function",
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
SpecifiedValue::Number(n) => write!(dest, "{}", n),
|
||||
SpecifiedValue::Infinite => dest.write_str("infinite"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -1039,28 +1039,15 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
|
||||
pub mod computed_value {
|
||||
use properties::animated_properties::Animatable;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::CSSFloat;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, ToCss)]
|
||||
pub enum T {
|
||||
None,
|
||||
Number(CSSFloat),
|
||||
}
|
||||
|
||||
impl ToCss for T {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
T::None => dest.write_str("none"),
|
||||
T::Number(number) => number.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl T {
|
||||
pub fn from_gecko_adjust(gecko: f32) -> Self {
|
||||
if gecko == -1.0 {
|
||||
|
@ -2214,9 +2201,7 @@ ${helpers.single_keyword("-moz-math-variant",
|
|||
use app_units::Au;
|
||||
use cssparser::Parser;
|
||||
use properties::longhands;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use style_traits::ToCss;
|
||||
use values::computed::{ToComputedValue, Context};
|
||||
<%
|
||||
system_fonts = """caption icon menu message-box small-caption status-bar
|
||||
|
@ -2230,23 +2215,13 @@ ${helpers.single_keyword("-moz-math-variant",
|
|||
kw_cast = """font_style font_variant_caps font_stretch
|
||||
font_kerning font_variant_position""".split()
|
||||
%>
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ToCss)]
|
||||
pub enum SystemFont {
|
||||
% for font in system_fonts:
|
||||
${to_camel_case(font)},
|
||||
% endfor
|
||||
}
|
||||
|
||||
impl ToCss for SystemFont {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
dest.write_str(match *self {
|
||||
% for font in system_fonts:
|
||||
SystemFont::${to_camel_case(font)} => "${font}",
|
||||
% endfor
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ComputedValues are compared at times
|
||||
// so we need these impls. We don't want to
|
||||
// add Eq to Number (which contains a float)
|
||||
|
|
|
@ -287,72 +287,11 @@ ${helpers.predefined_type(
|
|||
ignored_when_colors_disabled=True,
|
||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color")}
|
||||
|
||||
<%helpers:longhand name="initial-letter"
|
||||
animation_value_type="none"
|
||||
products="gecko"
|
||||
spec="https://drafts.csswg.org/css-inline/#sizing-drop-initials">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
use values::specified::{Number, Integer};
|
||||
|
||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum SpecifiedValue {
|
||||
Normal,
|
||||
Specified(Number, Option<Integer>)
|
||||
}
|
||||
|
||||
pub mod computed_value {
|
||||
pub use super::SpecifiedValue as T;
|
||||
}
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
SpecifiedValue::Normal => try!(dest.write_str("normal")),
|
||||
SpecifiedValue::Specified(size, sink) => {
|
||||
try!(size.to_css(dest));
|
||||
if let Some(sink) = sink {
|
||||
try!(dest.write_str(" "));
|
||||
try!(sink.to_css(dest));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T::Normal
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
||||
SpecifiedValue::Normal
|
||||
}
|
||||
|
||||
/// normal | <number> <integer>?
|
||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||
return Ok(SpecifiedValue::Normal);
|
||||
}
|
||||
|
||||
let size = try!(Number::parse_at_least_one(context, input));
|
||||
|
||||
match input.try(|input| Integer::parse(context, input)) {
|
||||
Ok(number) => {
|
||||
if number.value() < 1 {
|
||||
return Err(());
|
||||
}
|
||||
Ok(SpecifiedValue::Specified(size, Some(number)))
|
||||
}
|
||||
Err(()) => Ok(SpecifiedValue::Specified(size, None)),
|
||||
}
|
||||
}
|
||||
</%helpers:longhand>
|
||||
${helpers.predefined_type(
|
||||
"initial-letter",
|
||||
"InitialLetter",
|
||||
"computed::InitialLetter::normal()",
|
||||
initial_specified_value="specified::InitialLetter::normal()",
|
||||
animation_value_type="none",
|
||||
products="gecko",
|
||||
spec="https://drafts.csswg.org/css-inline/#sizing-drop-initials")}
|
||||
|
|
|
@ -450,8 +450,8 @@ impl PropertyDeclarationIdSet {
|
|||
% endfor
|
||||
|
||||
/// An enum to represent a CSS Wide keyword.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, ToCss)]
|
||||
pub enum CSSWideKeyword {
|
||||
/// The `initial` keyword.
|
||||
Initial,
|
||||
|
@ -483,12 +483,6 @@ impl CSSWideKeyword {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for CSSWideKeyword {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
dest.write_str(self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for CSSWideKeyword {
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let ident = input.expect_ident()?;
|
||||
|
@ -628,8 +622,8 @@ impl LonghandId {
|
|||
}
|
||||
|
||||
/// An identifier for a given shorthand property.
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss)]
|
||||
pub enum ShorthandId {
|
||||
% for property in data.shorthands:
|
||||
/// ${property.name}
|
||||
|
@ -637,14 +631,6 @@ pub enum ShorthandId {
|
|||
% endfor
|
||||
}
|
||||
|
||||
impl ToCss for ShorthandId {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
dest.write_str(self.name())
|
||||
}
|
||||
}
|
||||
|
||||
impl ShorthandId {
|
||||
/// Get the name for this shorthand property.
|
||||
pub fn name(&self) -> &'static str {
|
||||
|
|
|
@ -42,7 +42,7 @@ pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrP
|
|||
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
||||
pub use self::length::{MaxLength, MozLength};
|
||||
pub use self::position::Position;
|
||||
pub use self::text::{LetterSpacing, LineHeight, WordSpacing};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
||||
pub use self::transform::{TimingFunction, TransformOrigin};
|
||||
|
||||
pub mod background;
|
||||
|
|
|
@ -6,9 +6,14 @@
|
|||
|
||||
use app_units::Au;
|
||||
use properties::animated_properties::Animatable;
|
||||
use values::CSSFloat;
|
||||
use values::{CSSInteger, CSSFloat};
|
||||
use values::computed::length::{Length, LengthOrPercentage};
|
||||
use values::generics::text::{LineHeight as GenericLineHeight, Spacing};
|
||||
use values::generics::text::InitialLetter as GenericInitialLetter;
|
||||
use values::generics::text::LineHeight as GenericLineHeight;
|
||||
use values::generics::text::Spacing;
|
||||
|
||||
/// A computed value for the `initial-letter` property.
|
||||
pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
|
||||
|
||||
/// A computed value for the `letter-spacing` property.
|
||||
pub type LetterSpacing = Spacing<Length>;
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
|
||||
//! Generic types for CSS values related to backgrounds.
|
||||
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
/// A generic value for the `background-size` property.
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum BackgroundSize<LengthOrPercentageOrAuto> {
|
||||
/// `<width> <height>`
|
||||
|
@ -32,21 +29,3 @@ impl<L> From<L> for BackgroundSize<L>
|
|||
BackgroundSize::Explicit { width: value.clone(), height: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> ToCss for BackgroundSize<L>
|
||||
where L: ToCss
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write
|
||||
{
|
||||
match *self {
|
||||
BackgroundSize::Explicit { ref width, ref height } => {
|
||||
width.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
height.to_css(dest)
|
||||
},
|
||||
BackgroundSize::Cover => dest.write_str("cover"),
|
||||
BackgroundSize::Contain => dest.write_str("contain"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub type ClippingShape<BasicShape> = ShapeSource<BasicShape, GeometryBox>;
|
|||
/// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
|
||||
pub enum GeometryBox {
|
||||
FillBox,
|
||||
StrokeBox,
|
||||
|
@ -142,17 +142,6 @@ impl<B: ToCss, T: ToCss> ToCss for ShapeSource<B, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for GeometryBox {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
GeometryBox::FillBox => dest.write_str("fill-box"),
|
||||
GeometryBox::StrokeBox => dest.write_str("stroke-box"),
|
||||
GeometryBox::ViewBox => dest.write_str("view-box"),
|
||||
GeometryBox::ShapeBox(s) => s.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L> ToCss for InsetRect<L>
|
||||
where L: ToCss + PartialEq
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ use values::generics::rect::Rect;
|
|||
|
||||
/// A generic value for a single side of a `border-image-width` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum BorderImageSideWidth<LengthOrPercentage, Number> {
|
||||
/// `<length-or-percentage>`
|
||||
Length(LengthOrPercentage),
|
||||
|
@ -52,20 +52,6 @@ pub struct BorderRadius<LengthOrPercentage> {
|
|||
/// A generic value for `border-*-radius` longhand properties.
|
||||
pub struct BorderCornerRadius<L>(pub Size2D<L>);
|
||||
|
||||
impl<L, N> ToCss for BorderImageSideWidth<L, N>
|
||||
where L: ToCss, N: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write
|
||||
{
|
||||
match *self {
|
||||
BorderImageSideWidth::Length(ref length) => length.to_css(dest),
|
||||
BorderImageSideWidth::Number(ref number) => number.to_css(dest),
|
||||
BorderImageSideWidth::Auto => dest.write_str("auto"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> From<N> for BorderImageSlice<N>
|
||||
where N: Clone,
|
||||
{
|
||||
|
|
|
@ -329,8 +329,8 @@ pub fn concat_serialize_idents<W>(prefix: &str, suffix: &str,
|
|||
/// The initial argument of the `repeat` function.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-grid/#typedef-track-repeat
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
|
||||
pub enum RepeatCount {
|
||||
/// A positive integer. This is allowed only for `<track-repeat>` and `<fixed-repeat>`
|
||||
Number(Integer),
|
||||
|
@ -340,16 +340,6 @@ pub enum RepeatCount {
|
|||
AutoFit,
|
||||
}
|
||||
|
||||
impl ToCss for RepeatCount {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
RepeatCount::Number(ref c) => c.to_css(dest),
|
||||
RepeatCount::AutoFill => dest.write_str("auto-fill"),
|
||||
RepeatCount::AutoFit => dest.write_str("auto-fit"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for RepeatCount {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
if let Ok(i) = input.try(|i| Integer::parse(context, i)) {
|
||||
|
|
|
@ -182,8 +182,8 @@ impl<T: Parse> Parse for FontSettingTag<T> {
|
|||
|
||||
|
||||
/// A font settings value for font-variation-settings or font-feature-settings
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, ToCss)]
|
||||
pub enum FontSettings<T> {
|
||||
/// No settings (default)
|
||||
Normal,
|
||||
|
@ -191,15 +191,6 @@ pub enum FontSettings<T> {
|
|||
Tag(Vec<FontSettingTag<T>>)
|
||||
}
|
||||
|
||||
impl<T: ToCss> ToCss for FontSettings<T> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
FontSettings::Normal => dest.write_str("normal"),
|
||||
FontSettings::Tag(ref ftvs) => ftvs.to_css(dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Parse> Parse for FontSettings<T> {
|
||||
/// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
|
@ -290,8 +281,8 @@ pub struct SVGPaint<ColorType> {
|
|||
/// Whereas the spec only allows PaintServer
|
||||
/// to have a fallback, Gecko lets the context
|
||||
/// properties have a fallback as well.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||
pub enum SVGPaintKind<ColorType> {
|
||||
/// `none`
|
||||
None,
|
||||
|
@ -378,18 +369,6 @@ impl<ColorType: Parse> Parse for SVGPaint<ColorType> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<ColorType: ToCss> ToCss for SVGPaintKind<ColorType> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
SVGPaintKind::None => dest.write_str("none"),
|
||||
SVGPaintKind::ContextStroke => dest.write_str("context-stroke"),
|
||||
SVGPaintKind::ContextFill => dest.write_str("context-fill"),
|
||||
SVGPaintKind::Color(ref color) => color.to_css(dest),
|
||||
SVGPaintKind::PaintServer(ref server) => server.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColorType: ToCss> ToCss for SVGPaint<ColorType> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
self.kind.to_css(dest)?;
|
||||
|
|
|
@ -11,9 +11,50 @@ use properties::animated_properties::Animatable;
|
|||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
/// A generic spacing value for the `letter-spacing` and `word-spacing` properties.alloc
|
||||
/// A generic value for the `initial-letter` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||
pub enum InitialLetter<Number, Integer> {
|
||||
/// `normal`
|
||||
Normal,
|
||||
/// `<number> <integer>?`
|
||||
Specified(Number, Option<Integer>),
|
||||
}
|
||||
|
||||
impl<N, I> InitialLetter<N, I> {
|
||||
/// Returns `normal`.
|
||||
#[inline]
|
||||
pub fn normal() -> Self {
|
||||
InitialLetter::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl<N, I> ToCss for InitialLetter<N, I>
|
||||
where
|
||||
N: ToCss,
|
||||
I: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
InitialLetter::Normal => dest.write_str("normal"),
|
||||
InitialLetter::Specified(ref size, ref sink) => {
|
||||
size.to_css(dest)?;
|
||||
if let Some(ref sink) = *sink {
|
||||
dest.write_str(" ")?;
|
||||
sink.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic spacing value for the `letter-spacing` and `word-spacing` properties.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum Spacing<Value> {
|
||||
/// `normal`
|
||||
Normal,
|
||||
|
@ -76,22 +117,9 @@ impl<Value> Animatable for Spacing<Value>
|
|||
}
|
||||
}
|
||||
|
||||
impl<Value> ToCss for Spacing<Value>
|
||||
where Value: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write
|
||||
{
|
||||
match *self {
|
||||
Spacing::Normal => dest.write_str("normal"),
|
||||
Spacing::Value(ref value) => value.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A generic value for the `line-height` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
pub enum LineHeight<Number, LengthOrPercentage> {
|
||||
/// `normal`
|
||||
Normal,
|
||||
|
@ -111,19 +139,3 @@ impl<N, L> LineHeight<N, L> {
|
|||
LineHeight::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl<N, L> ToCss for LineHeight<N, L>
|
||||
where N: ToCss, L: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
LineHeight::Normal => dest.write_str("normal"),
|
||||
#[cfg(feature = "gecko")]
|
||||
LineHeight::MozBlockHeight => dest.write_str("-moz-block-height"),
|
||||
LineHeight::Number(ref number) => number.to_css(dest),
|
||||
LineHeight::Length(ref value) => value.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
use app_units::Au;
|
||||
use cssparser::Parser;
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
|
||||
use values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth;
|
||||
|
@ -20,7 +18,7 @@ use values::specified::length::{Length, LengthOrPercentage};
|
|||
|
||||
/// A specified value for a single side of the `border-width` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
pub enum BorderSideWidth {
|
||||
/// `thin`
|
||||
Thin,
|
||||
|
@ -73,17 +71,6 @@ impl Parse for BorderSideWidth {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for BorderSideWidth {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
BorderSideWidth::Thin => dest.write_str("thin"),
|
||||
BorderSideWidth::Medium => dest.write_str("medium"),
|
||||
BorderSideWidth::Thick => dest.write_str("thick"),
|
||||
BorderSideWidth::Length(ref length) => length.to_css(dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for BorderSideWidth {
|
||||
type ComputedValue = Au;
|
||||
|
||||
|
|
|
@ -894,9 +894,9 @@ impl LengthOrPercentage {
|
|||
}
|
||||
|
||||
/// Either a `<length>`, a `<percentage>`, or the `auto` keyword.
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
pub enum LengthOrPercentageOrAuto {
|
||||
Length(NoCalcLength),
|
||||
Percentage(Percentage),
|
||||
|
@ -918,17 +918,6 @@ impl From<Percentage> for LengthOrPercentageOrAuto {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for LengthOrPercentageOrAuto {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
LengthOrPercentageOrAuto::Length(ref length) => length.to_css(dest),
|
||||
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest),
|
||||
LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
|
||||
LengthOrPercentageOrAuto::Calc(ref calc) => calc.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LengthOrPercentageOrAuto {
|
||||
fn parse_internal(context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
|
@ -1012,8 +1001,8 @@ impl LengthOrPercentageOrAuto {
|
|||
}
|
||||
|
||||
/// Either a `<length>`, a `<percentage>`, or the `none` keyword.
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum LengthOrPercentageOrNone {
|
||||
Length(NoCalcLength),
|
||||
|
@ -1022,16 +1011,6 @@ pub enum LengthOrPercentageOrNone {
|
|||
None,
|
||||
}
|
||||
|
||||
impl ToCss for LengthOrPercentageOrNone {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
LengthOrPercentageOrNone::Length(ref length) => length.to_css(dest),
|
||||
LengthOrPercentageOrNone::Percentage(ref percentage) => percentage.to_css(dest),
|
||||
LengthOrPercentageOrNone::Calc(ref calc) => calc.to_css(dest),
|
||||
LengthOrPercentageOrNone::None => dest.write_str("none"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LengthOrPercentageOrNone {
|
||||
fn parse_internal(context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
|
@ -1099,8 +1078,8 @@ pub type LengthOrAuto = Either<Length, Auto>;
|
|||
|
||||
/// Either a `<length>` or a `<percentage>` or the `auto` keyword or the
|
||||
/// `content` keyword.
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
pub enum LengthOrPercentageOrAutoOrContent {
|
||||
/// A `<length>`.
|
||||
Length(NoCalcLength),
|
||||
|
@ -1156,18 +1135,6 @@ impl LengthOrPercentageOrAutoOrContent {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for LengthOrPercentageOrAutoOrContent {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
LengthOrPercentageOrAutoOrContent::Length(ref len) => len.to_css(dest),
|
||||
LengthOrPercentageOrAutoOrContent::Percentage(perc) => perc.to_css(dest),
|
||||
LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
|
||||
LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content"),
|
||||
LengthOrPercentageOrAutoOrContent::Calc(ref calc) => calc.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Either a `<length>` or a `<number>`.
|
||||
pub type LengthOrNumber = Either<Length, Number>;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercent
|
|||
pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength};
|
||||
pub use self::length::{MaxLength, MozLength};
|
||||
pub use self::position::{Position, PositionComponent};
|
||||
pub use self::text::{LetterSpacing, LineHeight, WordSpacing};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
||||
pub use self::transform::{TimingFunction, TransformOrigin};
|
||||
pub use super::generics::grid::GridLine;
|
||||
|
||||
|
|
|
@ -9,10 +9,15 @@ use parser::{Parse, ParserContext};
|
|||
use std::ascii::AsciiExt;
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::computed::text::LineHeight as ComputedLineHeight;
|
||||
use values::generics::text::{LineHeight as GenericLineHeight, Spacing};
|
||||
use values::specified::{AllowQuirks, Number};
|
||||
use values::generics::text::InitialLetter as GenericInitialLetter;
|
||||
use values::generics::text::LineHeight as GenericLineHeight;
|
||||
use values::generics::text::Spacing;
|
||||
use values::specified::{AllowQuirks, Integer, Number};
|
||||
use values::specified::length::{FontRelativeLength, Length, LengthOrPercentage, NoCalcLength};
|
||||
|
||||
/// A specified type for the `initial-letter` property.
|
||||
pub type InitialLetter = GenericInitialLetter<Number, Integer>;
|
||||
|
||||
/// A specified value for the `letter-spacing` property.
|
||||
pub type LetterSpacing = Spacing<Length>;
|
||||
|
||||
|
@ -22,6 +27,17 @@ pub type WordSpacing = Spacing<LengthOrPercentage>;
|
|||
/// A specified value for the `line-height` property.
|
||||
pub type LineHeight = GenericLineHeight<Number, LengthOrPercentage>;
|
||||
|
||||
impl Parse for InitialLetter {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
||||
return Ok(GenericInitialLetter::Normal);
|
||||
}
|
||||
let size = Number::parse_at_least_one(context, input)?;
|
||||
let sink = input.try(|i| Integer::parse_positive(context, i)).ok();
|
||||
Ok(GenericInitialLetter::Specified(size, sink))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for LetterSpacing {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
Spacing::parse_with(context, input, |c, i| {
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
use cssparser::Parser;
|
||||
use euclid::Point2D;
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, Context, ToComputedValue};
|
||||
use values::computed::transform::TimingFunction as ComputedTimingFunction;
|
||||
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
|
||||
|
@ -22,7 +20,7 @@ pub type TransformOrigin = GenericTransformOrigin<OriginComponent<X>, OriginComp
|
|||
|
||||
/// The specified value of a component of a CSS `<transform-origin>`.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
pub enum OriginComponent<S> {
|
||||
/// `center`
|
||||
Center,
|
||||
|
@ -99,20 +97,6 @@ impl<S> Parse for OriginComponent<S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: ToCss> ToCss for OriginComponent<S>
|
||||
where S: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
OriginComponent::Center => dest.write_str("center"),
|
||||
OriginComponent::Length(ref lop) => lop.to_css(dest),
|
||||
OriginComponent::Side(ref keyword) => keyword.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> ToComputedValue for OriginComponent<S>
|
||||
where S: Side,
|
||||
{
|
||||
|
|
|
@ -15,9 +15,12 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
|
|||
}
|
||||
|
||||
let style = synstructure::BindStyle::Ref.into();
|
||||
let match_body = synstructure::each_variant(&input, &style, |bindings, _| {
|
||||
let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
|
||||
if bindings.is_empty() {
|
||||
panic!("unit variants are not yet supported");
|
||||
let identifier = to_css_identifier(variant.ident.as_ref());
|
||||
return Some(quote! {
|
||||
::std::fmt::Write::write_str(dest, #identifier)
|
||||
});
|
||||
}
|
||||
let (first, rest) = bindings.split_first().expect("unit variants are not yet supported");
|
||||
where_clause.predicates.push(where_predicate(first.field.ty.clone()));
|
||||
|
@ -28,7 +31,7 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
|
|||
where_clause.predicates.push(where_predicate(binding.field.ty.clone()));
|
||||
expr = quote! {
|
||||
#expr?;
|
||||
dest.write_str(" ")?;
|
||||
::std::fmt::Write::write_str(dest, " ")?;
|
||||
::style_traits::ToCss::to_css(#binding, dest)
|
||||
};
|
||||
}
|
||||
|
@ -68,3 +71,40 @@ fn where_predicate(ty: syn::Ty) -> syn::WherePredicate {
|
|||
)],
|
||||
})
|
||||
}
|
||||
|
||||
/// Transforms "FooBar" to "foo-bar".
|
||||
///
|
||||
/// If the first Camel segment is "Moz"" or "Webkit", the result string
|
||||
/// is prepended with "-".
|
||||
fn to_css_identifier(mut camel_case: &str) -> String {
|
||||
let mut first = true;
|
||||
let mut result = String::with_capacity(camel_case.len());
|
||||
while let Some(segment) = split_camel_segment(&mut camel_case) {
|
||||
if first {
|
||||
match segment {
|
||||
"Moz" | "Webkit" => first = false,
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
if !first {
|
||||
result.push_str("-");
|
||||
}
|
||||
first = false;
|
||||
result.push_str(&segment.to_lowercase());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Given "FooBar", returns "Foo" and sets `camel_case` to "Bar".
|
||||
fn split_camel_segment<'input>(camel_case: &mut &'input str) -> Option<&'input str> {
|
||||
let index = match camel_case.chars().next() {
|
||||
None => return None,
|
||||
Some(ch) => ch.len_utf8(),
|
||||
};
|
||||
let end_position = camel_case[index..]
|
||||
.find(char::is_uppercase)
|
||||
.map_or(camel_case.len(), |pos| index + pos);
|
||||
let result = &camel_case[..end_position];
|
||||
*camel_case = &camel_case[end_position..];
|
||||
Some(result)
|
||||
}
|
||||
|
|
|
@ -8,8 +8,15 @@ use app_units::Au;
|
|||
use cssparser::UnicodeRange;
|
||||
use std::fmt;
|
||||
|
||||
/// The real `ToCss` trait can't be implemented for types in crates that don't
|
||||
/// depend on each other.
|
||||
/// Serialises a value according to its CSS representation.
|
||||
///
|
||||
/// This trait is derivable with `#[derive(ToCss)]`, with the following behaviour:
|
||||
/// * unit variants get serialised as the `snake-case` representation
|
||||
/// of their name;
|
||||
/// * unit variants whose name starts with "Moz" or "Webkit" are prepended
|
||||
/// with a "-";
|
||||
/// * variants with fields get serialised as the space-separated serialisations
|
||||
/// of their fields.
|
||||
pub trait ToCss {
|
||||
/// Serialize `self` in CSS syntax, writing to `dest`.
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue