mirror of
https://github.com/servo/servo.git
synced 2025-06-13 02:44:29 +00: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);
|
||||
}
|
||||
|
||||
|
||||
#[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 serialize;
|
||||
extern crate sync;
|
||||
extern crate text_writer;
|
||||
extern crate url;
|
||||
|
||||
extern crate cssparser;
|
||||
|
@ -27,6 +28,9 @@ extern crate string_cache;
|
|||
#[phase(plugin)]
|
||||
extern crate string_cache_macros;
|
||||
|
||||
#[phase(plugin)]
|
||||
extern crate plugins;
|
||||
|
||||
#[phase(plugin)]
|
||||
extern crate lazy_static;
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ pub mod specified {
|
|||
use std::ascii::AsciiExt;
|
||||
use std::f64::consts::PI;
|
||||
use std::fmt;
|
||||
use std::fmt::{Formatter, FormatError, Show};
|
||||
use std::fmt::{Formatter, Show};
|
||||
use url::Url;
|
||||
use cssparser;
|
||||
use cssparser::ast;
|
||||
use cssparser::{mod, ast, ToCss, CssStringWriter};
|
||||
use cssparser::ast::*;
|
||||
use text_writer::{mod, TextWriter};
|
||||
use parsing_utils::{mod, BufferedIter, ParserIter};
|
||||
use super::{Au, CSSFloat};
|
||||
|
||||
|
@ -42,11 +42,16 @@ pub mod specified {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
Some(ref s) => write!(f, "{}", s),
|
||||
None => write!(f, "{}", self.parsed),
|
||||
Some(ref s) => dest.write_str(s.as_slice()),
|
||||
None => self.parsed.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,22 +62,30 @@ pub mod specified {
|
|||
pub authored: Option<String>,
|
||||
}
|
||||
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 {
|
||||
Some(ref s) => write!(f, "{}", s),
|
||||
None => write!(f, "{}", self.parsed),
|
||||
Some(ref s) => dest.write_str(s.as_slice()),
|
||||
None => self.parsed.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
pub struct CSSImage(pub Option<Image>);
|
||||
|
||||
impl fmt::Show for CSSImage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let &CSSImage(ref url) = self;
|
||||
match url {
|
||||
&Some(ref image) => write!(f, "{}", image),
|
||||
&None => write!(f, "none"),
|
||||
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||
}
|
||||
|
||||
impl ToCss for CSSImage {
|
||||
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),
|
||||
// Vmax(CSSFloat),
|
||||
}
|
||||
|
||||
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 {
|
||||
&Length::Au(length) => write!(f, "{}", length),
|
||||
&Length::Em(length) => write!(f, "{}em", length),
|
||||
&Length::Ex(length) => write!(f, "{}ex", length),
|
||||
&Length::Rem(length) => write!(f, "{}rem", length),
|
||||
&Length::ServoCharacterWidth(_) => panic!("internal CSS values should never be serialized"),
|
||||
&Length::Au(length) => write!(dest, "{}px", length.to_subpx()),
|
||||
&Length::Em(length) => write!(dest, "{}em", length),
|
||||
&Length::Ex(length) => write!(dest, "{}ex", length),
|
||||
&Length::Rem(length) => write!(dest, "{}rem", length),
|
||||
&Length::ServoCharacterWidth(_)
|
||||
=> panic!("internal CSS values should never be serialized"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const AU_PER_PX: CSSFloat = 60.;
|
||||
const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
|
||||
const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
|
||||
|
@ -156,11 +176,17 @@ pub mod specified {
|
|||
Length(Length),
|
||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||
}
|
||||
|
||||
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 {
|
||||
&LengthOrPercentage::Length(length) => write!(f, "{}", length),
|
||||
&LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
|
||||
&LengthOrPercentage::Length(length) => length.to_css(dest),
|
||||
&LengthOrPercentage::Percentage(percentage)
|
||||
=> write!(dest, "{}%", percentage * 100.),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,12 +221,18 @@ pub mod specified {
|
|||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||
Auto,
|
||||
}
|
||||
|
||||
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 {
|
||||
&LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length),
|
||||
&LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
|
||||
&LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
|
||||
&LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
|
||||
&LengthOrPercentageOrAuto::Percentage(percentage)
|
||||
=> 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]
|
||||
None,
|
||||
}
|
||||
|
||||
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 {
|
||||
&LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length),
|
||||
&LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
|
||||
&LengthOrPercentageOrNone::None => write!(f, "none"),
|
||||
&LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
|
||||
&LengthOrPercentageOrNone::Percentage(percentage)
|
||||
=> write!(dest, "{}%", percentage * 100.),
|
||||
&LengthOrPercentageOrNone::None => dest.write_str("none"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -312,10 +350,14 @@ pub mod specified {
|
|||
#[deriving(Clone, PartialEq, PartialOrd)]
|
||||
pub struct Angle(pub CSSFloat);
|
||||
|
||||
impl Show for Angle {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||
impl fmt::Show for Angle {
|
||||
#[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;
|
||||
write!(f, "{}", value)
|
||||
write!(dest, "{}rad", value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,11 +395,20 @@ pub mod specified {
|
|||
LinearGradient(LinearGradient),
|
||||
}
|
||||
|
||||
impl Show for Image {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||
impl fmt::Show for Image {
|
||||
#[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 {
|
||||
&Image::Url(ref url) => write!(f, "url(\"{}\")", url),
|
||||
&Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad),
|
||||
&Image::Url(ref url) => {
|
||||
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>,
|
||||
}
|
||||
|
||||
impl Show for LinearGradient {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||
let _ = write!(f, "{}", self.angle_or_corner);
|
||||
for stop in self.stops.iter() {
|
||||
let _ = write!(f, ", {}", stop);
|
||||
impl fmt::Show for LinearGradient {
|
||||
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||
}
|
||||
|
||||
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() {
|
||||
try!(dest.write_str(", "));
|
||||
try!(stop.to_css(dest));
|
||||
}
|
||||
try!(dest.write_char(')'));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -422,11 +480,21 @@ pub mod specified {
|
|||
Corner(HorizontalDirection, VerticalDirection),
|
||||
}
|
||||
|
||||
impl Show for AngleOrCorner {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||
impl fmt::Show for AngleOrCorner {
|
||||
#[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 {
|
||||
&AngleOrCorner::Angle(angle) => write!(f, "{}", angle),
|
||||
&AngleOrCorner::Corner(horiz, vert) => write!(f, "to {} {}", horiz, vert),
|
||||
&AngleOrCorner::Angle(angle) => angle.to_css(dest),
|
||||
&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>,
|
||||
}
|
||||
|
||||
impl Show for ColorStop {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||
let _ = write!(f, "{}", self.color);
|
||||
self.position.map(|pos| {
|
||||
let _ = write!(f, " {}", pos);
|
||||
});
|
||||
impl fmt::Show for ColorStop {
|
||||
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
pub enum HorizontalDirection {
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right)
|
||||
define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom)
|
||||
|
||||
fn parse_color_stop(source: ParserIter) -> Result<ColorStop,()> {
|
||||
let color = match source.next() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue