mirror of
https://github.com/servo/servo.git
synced 2025-07-31 03:00:29 +01:00
Implement ToCss for types in style::properties::common_values::specified
This commit is contained in:
parent
4a9d5b1130
commit
45a08c94a4
3 changed files with 177 additions and 81 deletions
|
@ -50,3 +50,49 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||||
reg.register_lint_pass(box lints::InheritancePass as LintPassObject);
|
reg.register_lint_pass(box lints::InheritancePass as LintPassObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! define_css_keyword_enum {
|
||||||
|
($name: ident: $( $css: expr => $variant: ident ),+,) => {
|
||||||
|
define_css_keyword_enum!($name: $( $css => $variant ),+)
|
||||||
|
};
|
||||||
|
($name: ident: $( $css: expr => $variant: ident ),+) => {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[deriving(Clone, Eq, PartialEq, FromPrimitive)]
|
||||||
|
pub enum $name {
|
||||||
|
$( $variant ),+
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $name {
|
||||||
|
pub fn parse(component_value: &::cssparser::ast::ComponentValue) -> Result<$name, ()> {
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
|
match component_value {
|
||||||
|
&::cssparser::ast::Ident(ref value) => {
|
||||||
|
match value.to_ascii_lower().as_slice() {
|
||||||
|
$( concat!($css) => Ok($name::$variant), )+
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::fmt::Show for $name {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||||
|
use cssparser::ToCss;
|
||||||
|
self.fmt_to_css(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::cssparser::ToCss for $name {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> ::text_writer::Result
|
||||||
|
where W: ::text_writer::TextWriter {
|
||||||
|
match self {
|
||||||
|
$( &$name::$variant => dest.write_str($css) ),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ extern crate collections;
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
extern crate text_writer;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
|
@ -27,6 +28,9 @@ extern crate string_cache;
|
||||||
#[phase(plugin)]
|
#[phase(plugin)]
|
||||||
extern crate string_cache_macros;
|
extern crate string_cache_macros;
|
||||||
|
|
||||||
|
#[phase(plugin)]
|
||||||
|
extern crate plugins;
|
||||||
|
|
||||||
#[phase(plugin)]
|
#[phase(plugin)]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@ pub mod specified {
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Formatter, FormatError, Show};
|
use std::fmt::{Formatter, Show};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use cssparser;
|
use cssparser::{mod, ast, ToCss, CssStringWriter};
|
||||||
use cssparser::ast;
|
|
||||||
use cssparser::ast::*;
|
use cssparser::ast::*;
|
||||||
|
use text_writer::{mod, TextWriter};
|
||||||
use parsing_utils::{mod, BufferedIter, ParserIter};
|
use parsing_utils::{mod, BufferedIter, ParserIter};
|
||||||
use super::{Au, CSSFloat};
|
use super::{Au, CSSFloat};
|
||||||
|
|
||||||
|
@ -42,11 +42,16 @@ pub mod specified {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for CSSColor {
|
impl fmt::Show for CSSColor {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for CSSColor {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self.authored {
|
match self.authored {
|
||||||
Some(ref s) => write!(f, "{}", s),
|
Some(ref s) => dest.write_str(s.as_slice()),
|
||||||
None => write!(f, "{}", self.parsed),
|
None => self.parsed.to_css(dest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,22 +62,30 @@ pub mod specified {
|
||||||
pub authored: Option<String>,
|
pub authored: Option<String>,
|
||||||
}
|
}
|
||||||
impl fmt::Show for CSSRGBA {
|
impl fmt::Show for CSSRGBA {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for CSSRGBA {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self.authored {
|
match self.authored {
|
||||||
Some(ref s) => write!(f, "{}", s),
|
Some(ref s) => dest.write_str(s.as_slice()),
|
||||||
None => write!(f, "{}", self.parsed),
|
None => self.parsed.to_css(dest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub struct CSSImage(pub Option<Image>);
|
pub struct CSSImage(pub Option<Image>);
|
||||||
|
|
||||||
impl fmt::Show for CSSImage {
|
impl fmt::Show for CSSImage {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
let &CSSImage(ref url) = self;
|
}
|
||||||
match url {
|
|
||||||
&Some(ref image) => write!(f, "{}", image),
|
impl ToCss for CSSImage {
|
||||||
&None => write!(f, "none"),
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
match self {
|
||||||
|
&CSSImage(Some(ref image)) => image.to_css(dest),
|
||||||
|
&CSSImage(None) => dest.write_str("none"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,17 +110,24 @@ pub mod specified {
|
||||||
// Vmin(CSSFloat),
|
// Vmin(CSSFloat),
|
||||||
// Vmax(CSSFloat),
|
// Vmax(CSSFloat),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for Length {
|
impl fmt::Show for Length {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for Length {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&Length::Au(length) => write!(f, "{}", length),
|
&Length::Au(length) => write!(dest, "{}px", length.to_subpx()),
|
||||||
&Length::Em(length) => write!(f, "{}em", length),
|
&Length::Em(length) => write!(dest, "{}em", length),
|
||||||
&Length::Ex(length) => write!(f, "{}ex", length),
|
&Length::Ex(length) => write!(dest, "{}ex", length),
|
||||||
&Length::Rem(length) => write!(f, "{}rem", length),
|
&Length::Rem(length) => write!(dest, "{}rem", length),
|
||||||
&Length::ServoCharacterWidth(_) => panic!("internal CSS values should never be serialized"),
|
&Length::ServoCharacterWidth(_)
|
||||||
|
=> panic!("internal CSS values should never be serialized"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const AU_PER_PX: CSSFloat = 60.;
|
const AU_PER_PX: CSSFloat = 60.;
|
||||||
const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
|
const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
|
||||||
const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
|
const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
|
||||||
|
@ -156,11 +176,17 @@ pub mod specified {
|
||||||
Length(Length),
|
Length(Length),
|
||||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for LengthOrPercentage {
|
impl fmt::Show for LengthOrPercentage {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for LengthOrPercentage {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&LengthOrPercentage::Length(length) => write!(f, "{}", length),
|
&LengthOrPercentage::Length(length) => length.to_css(dest),
|
||||||
&LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
|
&LengthOrPercentage::Percentage(percentage)
|
||||||
|
=> write!(dest, "{}%", percentage * 100.),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,12 +221,18 @@ pub mod specified {
|
||||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||||
Auto,
|
Auto,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for LengthOrPercentageOrAuto {
|
impl fmt::Show for LengthOrPercentageOrAuto {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for LengthOrPercentageOrAuto {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length),
|
&LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
|
||||||
&LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
|
&LengthOrPercentageOrAuto::Percentage(percentage)
|
||||||
&LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
|
=> write!(dest, "{}%", percentage * 100.),
|
||||||
|
&LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,12 +267,18 @@ pub mod specified {
|
||||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for LengthOrPercentageOrNone {
|
impl fmt::Show for LengthOrPercentageOrNone {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for LengthOrPercentageOrNone {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length),
|
&LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
|
||||||
&LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
|
&LengthOrPercentageOrNone::Percentage(percentage)
|
||||||
&LengthOrPercentageOrNone::None => write!(f, "none"),
|
=> write!(dest, "{}%", percentage * 100.),
|
||||||
|
&LengthOrPercentageOrNone::None => dest.write_str("none"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,10 +350,14 @@ pub mod specified {
|
||||||
#[deriving(Clone, PartialEq, PartialOrd)]
|
#[deriving(Clone, PartialEq, PartialOrd)]
|
||||||
pub struct Angle(pub CSSFloat);
|
pub struct Angle(pub CSSFloat);
|
||||||
|
|
||||||
impl Show for Angle {
|
impl fmt::Show for Angle {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for Angle {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
let Angle(value) = *self;
|
let Angle(value) = *self;
|
||||||
write!(f, "{}", value)
|
write!(dest, "{}rad", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,11 +395,20 @@ pub mod specified {
|
||||||
LinearGradient(LinearGradient),
|
LinearGradient(LinearGradient),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Show for Image {
|
impl fmt::Show for Image {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for Image {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&Image::Url(ref url) => write!(f, "url(\"{}\")", url),
|
&Image::Url(ref url) => {
|
||||||
&Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad),
|
try!(dest.write_str("url(\""));
|
||||||
|
try!(write!(CssStringWriter::new(dest), "{}", url));
|
||||||
|
try!(dest.write_str("\")"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
&Image::LinearGradient(ref gradient) => gradient.to_css(dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,12 +456,19 @@ pub mod specified {
|
||||||
pub stops: Vec<ColorStop>,
|
pub stops: Vec<ColorStop>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Show for LinearGradient {
|
impl fmt::Show for LinearGradient {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
let _ = write!(f, "{}", self.angle_or_corner);
|
}
|
||||||
|
|
||||||
|
impl ToCss for LinearGradient {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
try!(dest.write_str("linear-gradient("));
|
||||||
|
try!(self.angle_or_corner.to_css(dest));
|
||||||
for stop in self.stops.iter() {
|
for stop in self.stops.iter() {
|
||||||
let _ = write!(f, ", {}", stop);
|
try!(dest.write_str(", "));
|
||||||
|
try!(stop.to_css(dest));
|
||||||
}
|
}
|
||||||
|
try!(dest.write_char(')'));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,11 +480,21 @@ pub mod specified {
|
||||||
Corner(HorizontalDirection, VerticalDirection),
|
Corner(HorizontalDirection, VerticalDirection),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Show for AngleOrCorner {
|
impl fmt::Show for AngleOrCorner {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for AngleOrCorner {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&AngleOrCorner::Angle(angle) => write!(f, "{}", angle),
|
&AngleOrCorner::Angle(angle) => angle.to_css(dest),
|
||||||
&AngleOrCorner::Corner(horiz, vert) => write!(f, "to {} {}", horiz, vert),
|
&AngleOrCorner::Corner(horizontal, vertical) => {
|
||||||
|
try!(dest.write_str("to "));
|
||||||
|
try!(horizontal.to_css(dest));
|
||||||
|
try!(dest.write_char(' '));
|
||||||
|
try!(vertical.to_css(dest));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,45 +510,23 @@ pub mod specified {
|
||||||
pub position: Option<LengthOrPercentage>,
|
pub position: Option<LengthOrPercentage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Show for ColorStop {
|
impl fmt::Show for ColorStop {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||||
let _ = write!(f, "{}", self.color);
|
}
|
||||||
self.position.map(|pos| {
|
|
||||||
let _ = write!(f, " {}", pos);
|
impl ToCss for ColorStop {
|
||||||
});
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
try!(self.color.to_css(dest));
|
||||||
|
if let Some(position) = self.position {
|
||||||
|
try!(dest.write_char(' '));
|
||||||
|
try!(position.to_css(dest));
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq)]
|
define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right)
|
||||||
pub enum HorizontalDirection {
|
define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom)
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Show for HorizontalDirection {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
|
||||||
match self {
|
|
||||||
&HorizontalDirection::Left => write!(f, "left"),
|
|
||||||
&HorizontalDirection::Right => write!(f, "right"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq)]
|
|
||||||
pub enum VerticalDirection {
|
|
||||||
Top,
|
|
||||||
Bottom,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Show for VerticalDirection {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
|
||||||
match self {
|
|
||||||
&VerticalDirection::Top => write!(f, "top"),
|
|
||||||
&VerticalDirection::Bottom => write!(f, "bottom"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_color_stop(source: ParserIter) -> Result<ColorStop,()> {
|
fn parse_color_stop(source: ParserIter) -> Result<ColorStop,()> {
|
||||||
let color = match source.next() {
|
let color = match source.next() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue