From 4a9d5b1130e5f6201bd291324d4db2ca61c2774e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Dec 2014 00:02:34 +0000 Subject: [PATCH 1/8] Upgrade cssparser to a version with the new ToCss trait. --- components/servo/Cargo.lock | 8 +++++++- components/style/properties/mod.rs.mako | 6 +++--- components/style/stylesheets.rs | 2 +- ports/cef/Cargo.lock | 8 +++++++- ports/gonk/Cargo.lock | 8 +++++++- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index f09a4de3093..b0584810f6f 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -124,9 +124,10 @@ dependencies = [ [[package]] name = "cssparser" version = "0.1.0" -source = "git+https://github.com/servo/rust-cssparser#97d8c3b20a240881573748d4eadcda610bfb888c" +source = "git+https://github.com/servo/rust-cssparser#a2b0b6b00ad84dc3a4b4faf77ddd63611c8ce58a" dependencies = [ "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -681,6 +682,11 @@ dependencies = [ name = "task_info" version = "0.0.1" +[[package]] +name = "text_writer" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "time" version = "0.1.0" diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index f6abe506c57..bc43ce62a94 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -2547,13 +2547,13 @@ pub fn parse_property_declaration_list>(input: I, base_url: &U }; match PropertyDeclaration::parse(n.as_slice(), v.as_slice(), list, base_url, seen) { PropertyDeclarationParseResult::UnknownProperty => log_css_error(l, format!( - "Unsupported property: {}:{}", n, v.iter().to_css()).as_slice()), + "Unsupported property: {}:{}", n, v.to_css_string()).as_slice()), PropertyDeclarationParseResult::ExperimentalProperty => log_css_error(l, format!( "Experimental property, use `servo --enable_experimental` \ or `servo -e` to enable: {}:{}", - n, v.iter().to_css()).as_slice()), + n, v.to_css_string()).as_slice()), PropertyDeclarationParseResult::InvalidValue => log_css_error(l, format!( - "Invalid value: {}:{}", n, v.iter().to_css()).as_slice()), + "Invalid value: {}:{}", n, v.to_css_string()).as_slice()), PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => (), } } diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index b271e4e77be..454f4cb5052 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -168,7 +168,7 @@ pub fn parse_style_rule(context: &ParserContext, block } = rule; // FIXME: avoid doing this for valid selectors - let serialized = prelude.iter().to_css(); + let serialized = prelude.to_css_string(); match selectors::parse_selector_list(context, prelude.into_iter(), namespaces) { Ok(selectors) => parent_rules.push(CSSRule::Style(StyleRule{ selectors: selectors, diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 9c70c1e8c43..1eb0fa96386 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -120,9 +120,10 @@ dependencies = [ [[package]] name = "cssparser" version = "0.1.0" -source = "git+https://github.com/servo/rust-cssparser#97d8c3b20a240881573748d4eadcda610bfb888c" +source = "git+https://github.com/servo/rust-cssparser#a2b0b6b00ad84dc3a4b4faf77ddd63611c8ce58a" dependencies = [ "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -665,6 +666,11 @@ dependencies = [ name = "task_info" version = "0.0.1" +[[package]] +name = "text_writer" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "time" version = "0.1.0" diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index c5209915585..f9baefb333e 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -103,9 +103,10 @@ dependencies = [ [[package]] name = "cssparser" version = "0.1.0" -source = "git+https://github.com/servo/rust-cssparser#97d8c3b20a240881573748d4eadcda610bfb888c" +source = "git+https://github.com/servo/rust-cssparser#a2b0b6b00ad84dc3a4b4faf77ddd63611c8ce58a" dependencies = [ "encoding 0.2.3 (git+https://github.com/lifthrasiir/rust-encoding)", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -613,6 +614,11 @@ dependencies = [ name = "task_info" version = "0.0.1" +[[package]] +name = "text_writer" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "time" version = "0.1.0" From 45a08c94a448f7c16b19ea48be7661e474902d65 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Dec 2014 00:04:53 +0000 Subject: [PATCH 2/8] Implement ToCss for types in style::properties::common_values::specified --- components/plugins/lib.rs | 46 +++++ components/style/lib.rs | 4 + components/style/properties/common_types.rs | 208 ++++++++++++-------- 3 files changed, 177 insertions(+), 81 deletions(-) diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index a7d356f47ee..662eeedc385 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -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(&self, dest: &mut W) -> ::text_writer::Result + where W: ::text_writer::TextWriter { + match self { + $( &$name::$variant => dest.write_str($css) ),+ + } + } + } + } +} diff --git a/components/style/lib.rs b/components/style/lib.rs index fec6c2d5b61..19f62ff36dd 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -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; diff --git a/components/style/properties/common_types.rs b/components/style/properties/common_types.rs index 9dcd65d6fc5..52a0fb3be40 100644 --- a/components/style/properties/common_types.rs +++ b/components/style/properties/common_types.rs @@ -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(&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, } 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(&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); + 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(&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(&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(&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(&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(&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(&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(&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, } - impl Show for LinearGradient { - fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { - let _ = write!(f, "{}", self.angle_or_corner); + 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(&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() { - let _ = write!(f, ", {}", stop); + 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(&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, } - 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(&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 { let color = match source.next() { From 8be85c5e6b62e5a8fd3b20026e9f02b39d5a2270 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Dec 2014 00:25:29 +0000 Subject: [PATCH 3/8] Implement ToCss for Cursor and de-duplicate variants and string values. --- components/style/properties/mod.rs.mako | 139 ++---------------------- components/util/cursor.rs | 106 +++++++++++------- components/util/lib.rs | 1 + 3 files changed, 80 insertions(+), 166 deletions(-) diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index bc43ce62a94..b9531a2ad4b 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -159,40 +159,21 @@ pub mod longhands { <%def name="single_keyword_computed(name, values, experimental=False)"> <%self:single_component_value name="${name}" experimental="${experimental}"> + pub use self::computed_value::T as SpecifiedValue; ${caller.body()} pub mod computed_value { - use std::fmt; - #[allow(non_camel_case_types)] - #[deriving(PartialEq, Clone, FromPrimitive)] - pub enum T { + define_css_keyword_enum! { T: % for value in values.split(): - ${to_rust_ident(value)}, + "${value}" => ${to_rust_ident(value)}, % endfor } - impl fmt::Show for T { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - % for value in values.split(): - &T::${to_rust_ident(value)} => write!(f, "${value}"), - % endfor - } - } - } } - pub type SpecifiedValue = computed_value::T; #[inline] pub fn get_initial_value() -> computed_value::T { T::${to_rust_ident(values.split()[0])} } pub fn from_component_value(v: &ComponentValue, _base_url: &Url) -> Result { - get_ident_lower(v).and_then(|keyword| { - match keyword.as_slice() { - % for value in values.split(): - "${value}" => Ok(T::${to_rust_ident(value)}), - % endfor - _ => Err(()), - } - }) + computed_value::T::parse(v) } @@ -1550,111 +1531,13 @@ pub mod longhands { pub fn from_component_value(value: &ComponentValue, _: &Url) -> Result { match value { - &Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(T::AutoCursor), - &Ident(ref value) if value.eq_ignore_ascii_case("none") => { - Ok(T::SpecifiedCursor(util_cursor::NoCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("default") => { - Ok(T::SpecifiedCursor(util_cursor::DefaultCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("pointer") => { - Ok(T::SpecifiedCursor(util_cursor::PointerCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("context-menu") => { - Ok(T::SpecifiedCursor(util_cursor::ContextMenuCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("help") => { - Ok(T::SpecifiedCursor(util_cursor::HelpCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("progress") => { - Ok(T::SpecifiedCursor(util_cursor::ProgressCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("wait") => { - Ok(T::SpecifiedCursor(util_cursor::WaitCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("cell") => { - Ok(T::SpecifiedCursor(util_cursor::CellCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("crosshair") => { - Ok(T::SpecifiedCursor(util_cursor::CrosshairCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("text") => { - Ok(T::SpecifiedCursor(util_cursor::TextCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("vertical-text") => { - Ok(T::SpecifiedCursor(util_cursor::VerticalTextCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("alias") => { - Ok(T::SpecifiedCursor(util_cursor::AliasCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("copy") => { - Ok(T::SpecifiedCursor(util_cursor::CopyCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("move") => { - Ok(T::SpecifiedCursor(util_cursor::MoveCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("no-drop") => { - Ok(T::SpecifiedCursor(util_cursor::NoDropCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("not-allowed") => { - Ok(T::SpecifiedCursor(util_cursor::NotAllowedCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("grab") => { - Ok(T::SpecifiedCursor(util_cursor::GrabCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("grabbing") => { - Ok(T::SpecifiedCursor(util_cursor::GrabbingCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("e-resize") => { - Ok(T::SpecifiedCursor(util_cursor::EResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("n-resize") => { - Ok(T::SpecifiedCursor(util_cursor::NResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("ne-resize") => { - Ok(T::SpecifiedCursor(util_cursor::NeResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("nw-resize") => { - Ok(T::SpecifiedCursor(util_cursor::NwResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("s-resize") => { - Ok(T::SpecifiedCursor(util_cursor::SResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("se-resize") => { - Ok(T::SpecifiedCursor(util_cursor::SeResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("sw-resize") => { - Ok(T::SpecifiedCursor(util_cursor::SwResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("w-resize") => { - Ok(T::SpecifiedCursor(util_cursor::WResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("ew-resize") => { - Ok(T::SpecifiedCursor(util_cursor::EwResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("ns-resize") => { - Ok(T::SpecifiedCursor(util_cursor::NsResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("nesw-resize") => { - Ok(T::SpecifiedCursor(util_cursor::NeswResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("nwse-resize") => { - Ok(T::SpecifiedCursor(util_cursor::NwseResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("col-resize") => { - Ok(T::SpecifiedCursor(util_cursor::ColResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("row-resize") => { - Ok(T::SpecifiedCursor(util_cursor::RowResizeCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("all-scroll") => { - Ok(T::SpecifiedCursor(util_cursor::AllScrollCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("zoom-in") => { - Ok(T::SpecifiedCursor(util_cursor::ZoomInCursor)) - } - &Ident(ref value) if value.eq_ignore_ascii_case("zoom-out") => { - Ok(T::SpecifiedCursor(util_cursor::ZoomOutCursor)) + &Ident(ref ident) => { + if ident.eq_ignore_ascii_case("auto") { + Ok(T::AutoCursor) + } else { + util_cursor::Cursor::from_css_keyword(ident.as_slice()) + .map(T::SpecifiedCursor) + } } _ => Err(()) } diff --git a/components/util/cursor.rs b/components/util/cursor.rs index d295487ac9b..7a12dc05ec6 100644 --- a/components/util/cursor.rs +++ b/components/util/cursor.rs @@ -4,43 +4,73 @@ //! A list of common mouse cursors per CSS3-UI ยง 8.1.1. -#[deriving(Clone, PartialEq, FromPrimitive, Show)] -#[repr(u8)] -pub enum Cursor { - NoCursor = 0, - DefaultCursor = 1, - PointerCursor = 2, - ContextMenuCursor = 3, - HelpCursor = 4, - ProgressCursor = 5, - WaitCursor = 6, - CellCursor = 7, - CrosshairCursor = 8, - TextCursor = 9, - VerticalTextCursor = 10, - AliasCursor = 11, - CopyCursor = 12, - MoveCursor = 13, - NoDropCursor = 14, - NotAllowedCursor = 15, - GrabCursor = 16, - GrabbingCursor = 17, - EResizeCursor = 18, - NResizeCursor = 19, - NeResizeCursor = 20, - NwResizeCursor = 21, - SResizeCursor = 22, - SeResizeCursor = 23, - SwResizeCursor = 24, - WResizeCursor = 25, - EwResizeCursor = 26, - NsResizeCursor = 27, - NeswResizeCursor = 28, - NwseResizeCursor = 29, - ColResizeCursor = 30, - RowResizeCursor = 31, - AllScrollCursor = 32, - ZoomInCursor = 33, - ZoomOutCursor = 34, +use cssparser::ToCss; +use std::ascii::AsciiExt; +use text_writer::TextWriter; + + +macro_rules! define_cursor { + ($( $css: expr => $variant: ident = $value: expr, )+) => { + #[deriving(Clone, PartialEq, Eq, FromPrimitive, Show)] + #[repr(u8)] + pub enum Cursor { + $( $variant = $value ),+ + } + + impl Cursor { + pub fn from_css_keyword(keyword: &str) -> Result { + match keyword.to_ascii_lower().as_slice() { + $( concat!($css) => Ok(Cursor::$variant), )+ + _ => Err(()) + } + } + } + + impl ToCss for Cursor { + fn to_css(&self, dest: &mut W) -> ::text_writer::Result where W: TextWriter { + match self { + $( &Cursor::$variant => dest.write_str($css) ),+ + } + } + } + } } + +define_cursor! { + "none" => NoCursor = 0, + "defalut" => DefaultCursor = 1, + "pointer" => PointerCursor = 2, + "context-menu" => ContextMenuCursor = 3, + "help" => HelpCursor = 4, + "progress" => ProgressCursor = 5, + "wait" => WaitCursor = 6, + "cell" => CellCursor = 7, + "crosshair" => CrosshairCursor = 8, + "text" => TextCursor = 9, + "vertical-text" => VerticalTextCursor = 10, + "alias" => AliasCursor = 11, + "copy" => CopyCursor = 12, + "move" => MoveCursor = 13, + "no-drop" => NoDropCursor = 14, + "not-allowed" => NotAllowedCursor = 15, + "grab" => GrabCursor = 16, + "grabbing" => GrabbingCursor = 17, + "e-resize" => EResizeCursor = 18, + "n-resize" => NResizeCursor = 19, + "ne-resize" => NeResizeCursor = 20, + "nw-resize" => NwResizeCursor = 21, + "s-resize" => SResizeCursor = 22, + "se-resize" => SeResizeCursor = 23, + "sw-resize" => SwResizeCursor = 24, + "w-resize" => WResizeCursor = 25, + "ew-resize" => EwResizeCursor = 26, + "ns-resize" => NsResizeCursor = 27, + "nesw-resize" => NeswResizeCursor = 28, + "nwse-resize" => NwseResizeCursor = 29, + "col-resize" => ColResizeCursor = 30, + "row-resize" => RowResizeCursor = 31, + "all-scroll" => AllScrollCursor = 32, + "zoom-in" => ZoomInCursor = 33, + "zoom-out" => ZoomOutCursor = 34, +} diff --git a/components/util/lib.rs b/components/util/lib.rs index 02daa6be76f..78160d8950a 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -26,6 +26,7 @@ extern crate sync; #[cfg(target_os="macos")] extern crate task_info; extern crate "time" as std_time; +extern crate text_writer; extern crate string_cache; extern crate unicode; extern crate url; From b9a57531eabbfd919895323525a4891b6e57b122 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Dec 2014 00:31:36 +0000 Subject: [PATCH 4/8] Remove some tabs @jdm, can you configure your editor to not insert them in the first place? --- components/style/properties/mod.rs.mako | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index b9531a2ad4b..4bfe6fe696b 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -448,14 +448,14 @@ pub mod longhands { pub use super::computed_as_specified as to_computed_value; pub type SpecifiedValue = computed_value::T; pub mod computed_value { - use std::fmt; + use std::fmt; #[deriving(PartialEq, Clone)] pub enum T { Auto, Number(i32), } - impl fmt::Show for T { + impl fmt::Show for T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &T::Auto => write!(f, "auto"), @@ -555,7 +555,7 @@ pub mod longhands { &SpecifiedValue::Normal => write!(f, "normal"), &SpecifiedValue::Length(length) => write!(f, "{}", length), &SpecifiedValue::Number(number) => write!(f, "{}", number), - &SpecifiedValue::Percentage(number) => write!(f, "{}%", number * 100.), + &SpecifiedValue::Percentage(number) => write!(f, "{}%", number * 100.), } } } @@ -628,7 +628,7 @@ pub mod longhands { % for keyword in vertical_align_keywords: &SpecifiedValue::${to_rust_ident(keyword)} => write!(f, "${keyword}"), % endfor - &SpecifiedValue::LengthOrPercentage(lop) => write!(f, "{}", lop), + &SpecifiedValue::LengthOrPercentage(lop) => write!(f, "{}", lop), } } } @@ -708,13 +708,13 @@ pub mod longhands { <%self:longhand name="content"> pub use super::computed_as_specified as to_computed_value; pub mod computed_value { - use std::fmt; + use std::fmt; #[deriving(PartialEq, Clone)] pub enum ContentItem { StringContent(String), } impl fmt::Show for ContentItem { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &ContentItem::StringContent(ref s) => write!(f, "\"{}\"", s), } @@ -728,16 +728,16 @@ pub mod longhands { Content(Vec), } impl fmt::Show for T { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &T::normal => write!(f, "normal"), - &T::none => write!(f, "none"), - &T::Content(ref content) => { + &T::normal => write!(f, "normal"), + &T::none => write!(f, "none"), + &T::Content(ref content) => { for c in content.iter() { let _ = write!(f, "{}", c); } Ok(()) - } + } } } } @@ -866,7 +866,7 @@ pub mod longhands { pub vertical: LengthOrPercentage, } impl fmt::Show for T { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{} {}", self.horizontal, self.vertical) } } @@ -1356,7 +1356,7 @@ pub mod longhands { } let _ = write!(f, "line-through"); } - Ok(()) + Ok(()) } } pub mod computed_value { @@ -1602,7 +1602,7 @@ pub mod longhands { if let Some(ref color) = self.color { let _ = write!(f, "{}", color); } - Ok(()) + Ok(()) } } @@ -1630,7 +1630,7 @@ pub mod longhands { } let _ = write!(f, "{} {} {} {} {}", self.offset_x, self.offset_y, self.blur_radius, self.spread_radius, self.color); - Ok(()) + Ok(()) } } } @@ -2510,7 +2510,7 @@ impl PropertyDeclaration { % for property in LONGHANDS: % if property.derived_from is None: &PropertyDeclaration::${property.camel_case}Declaration(..) => "${property.name}".to_string(), - % endif + % endif % endfor _ => "".to_string(), } @@ -2523,7 +2523,7 @@ impl PropertyDeclaration { &PropertyDeclaration::${property.camel_case}Declaration(ref value) => value.specified_value() .unwrap_or_else(|| format!("{}", longhands::${property.ident}::get_initial_value())), - % endif + % endif % endfor decl => panic!("unsupported property declaration: {}", decl.name()), } @@ -2535,7 +2535,7 @@ impl PropertyDeclaration { % for property in LONGHANDS: % if property.derived_from is None: (&PropertyDeclaration::${property.camel_case}Declaration(..), "${property.name}") => true, - % endif + % endif % endfor _ => false, } From 540d21888558751a5fae0b71011306068a58bc6f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Dec 2014 10:36:31 +0000 Subject: [PATCH 5/8] Declare dependencies on text_writer. Transitive dependencies being available is considered a bug: https://github.com/rust-lang/cargo/issues/1037 --- components/servo/Cargo.lock | 2 ++ components/style/Cargo.toml | 2 ++ components/util/Cargo.toml | 3 +++ ports/cef/Cargo.lock | 2 ++ ports/gonk/Cargo.lock | 2 ++ 5 files changed, 11 insertions(+) diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index b0584810f6f..9075a588342 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -674,6 +674,7 @@ dependencies = [ "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.1.0 (git+https://github.com/servo/rust-url)", "util 0.0.1", ] @@ -715,6 +716,7 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.0 (git+https://github.com/rust-lang/time)", "url 0.1.0 (git+https://github.com/servo/rust-url)", ] diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index f0ab29d7148..db2cbe9ffc4 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -36,3 +36,5 @@ git = "https://github.com/servo/string-cache" [dependencies.string_cache_macros] git = "https://github.com/servo/string-cache" +[dependencies] +text_writer = "0.1.1" diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index e7faaebee97..086a57dad39 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -30,3 +30,6 @@ git = "https://github.com/servo/rust-url" [dependencies.time] git = "https://github.com/rust-lang/time" + +[dependencies] +text_writer = "0.1.1" diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 1eb0fa96386..3ebeef17673 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -658,6 +658,7 @@ dependencies = [ "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.1.0 (git+https://github.com/servo/rust-url)", "util 0.0.1", ] @@ -699,6 +700,7 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.0 (git+https://github.com/rust-lang/time)", "url 0.1.0 (git+https://github.com/servo/rust-url)", ] diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index f9baefb333e..19641c7399c 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -606,6 +606,7 @@ dependencies = [ "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.1.0 (git+https://github.com/servo/rust-url)", "util 0.0.1", ] @@ -647,6 +648,7 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", + "text_writer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.0 (git+https://github.com/rust-lang/time)", "url 0.1.0 (git+https://github.com/servo/rust-url)", ] From 2e35d4e9879089759a0afe865cb6fb7796084938 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Dec 2014 11:17:53 +0000 Subject: [PATCH 6/8] Add a match_ignore_ascii_case! macro that does not allocate. It should replace `match foo.to_ascii_lower().as_slice() { ...}` @Manishearth I changed map.get to map.find in the lint to work around an ICE: task 'rustc' panicked at 'couldn't find node id 0 in the AST map' Does this look OK? --- components/plugins/lib.rs | 25 ++++++++++++++++++++++--- components/plugins/lints.rs | 6 +++--- components/servo/Cargo.lock | 1 + components/util/Cargo.toml | 3 +++ components/util/cursor.rs | 4 ++-- components/util/lib.rs | 7 +++---- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index 662eeedc385..69f823c2d91 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -65,11 +65,10 @@ macro_rules! define_css_keyword_enum { 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), )+ + match_ignore_ascii_case! { value: + $( $css => Ok($name::$variant) ),+ _ => Err(()) } } @@ -96,3 +95,23 @@ macro_rules! define_css_keyword_enum { } } } + + +#[macro_export] +macro_rules! match_ignore_ascii_case { + ( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr, ) => { + match_ignore_ascii_case! { $value: + $( $string => $result ),+ + _ => $fallback + } + }; + ( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr ) => { + { + use std::ascii::AsciiExt; + match $value.as_slice() { + $( s if s.eq_ignore_ascii_case($string) => $result, )+ + _ => $fallback + } + } + }; +} diff --git a/components/plugins/lints.rs b/components/plugins/lints.rs index a170cb6a4a1..3cb4cb91e1f 100644 --- a/components/plugins/lints.rs +++ b/components/plugins/lints.rs @@ -104,8 +104,8 @@ fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) { // Determines if a block is in an unsafe context so that an unhelpful // lint can be aborted. fn unsafe_context(map: &ast_map::Map, id: ast::NodeId) -> bool { - match map.get(map.get_parent(id)) { - ast_map::NodeImplItem(itm) => { + match map.find(map.get_parent(id)) { + Some(ast_map::NodeImplItem(itm)) => { match *itm { ast::MethodImplItem(ref meth) => match meth.node { ast::MethDecl(_, _, _, _, style, _, _, _) => match style { @@ -117,7 +117,7 @@ fn unsafe_context(map: &ast_map::Map, id: ast::NodeId) -> bool { _ => false, } }, - ast_map::NodeItem(itm) => { + Some(ast_map::NodeItem(itm)) => { match itm.node { ast::ItemFn(_, style, _, _, _) => match style { ast::UnsafeFn => true, diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 9075a588342..e3662c1a3c4 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -713,6 +713,7 @@ dependencies = [ "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", + "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index 086a57dad39..87969f90af7 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"] name = "util" path = "lib.rs" +[dependencies.plugins] +path = "../plugins" + [dependencies.cssparser] git = "https://github.com/servo/rust-cssparser" diff --git a/components/util/cursor.rs b/components/util/cursor.rs index 7a12dc05ec6..0549ff7592c 100644 --- a/components/util/cursor.rs +++ b/components/util/cursor.rs @@ -19,8 +19,8 @@ macro_rules! define_cursor { impl Cursor { pub fn from_css_keyword(keyword: &str) -> Result { - match keyword.to_ascii_lower().as_slice() { - $( concat!($css) => Ok(Cursor::$variant), )+ + match_ignore_ascii_case! { keyword: + $( concat!($css) => Ok(Cursor::$variant) ),+ _ => Err(()) } } diff --git a/components/util/lib.rs b/components/util/lib.rs index 78160d8950a..6dbac1094d6 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -31,10 +31,9 @@ extern crate string_cache; extern crate unicode; extern crate url; -#[phase(plugin)] -extern crate string_cache_macros; -#[phase(plugin)] -extern crate lazy_static; +#[phase(plugin)] extern crate plugins; +#[phase(plugin)] extern crate string_cache_macros; +#[phase(plugin)] extern crate lazy_static; use std::sync::Arc; From 5e08e96e38cd3b9f6d81657f505ad785e6606e0b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 24 Dec 2014 15:42:42 +0100 Subject: [PATCH 7/8] Fix typo in a cursor keyword. Thanks @nuss-justin! --- components/util/cursor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/util/cursor.rs b/components/util/cursor.rs index 0549ff7592c..0a094ce117d 100644 --- a/components/util/cursor.rs +++ b/components/util/cursor.rs @@ -39,7 +39,7 @@ macro_rules! define_cursor { define_cursor! { "none" => NoCursor = 0, - "defalut" => DefaultCursor = 1, + "default" => DefaultCursor = 1, "pointer" => PointerCursor = 2, "context-menu" => ContextMenuCursor = 3, "help" => HelpCursor = 4, From a29cb0e5d0292a812c28d9143565b9936c57f39e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 29 Dec 2014 21:52:12 +0100 Subject: [PATCH 8/8] Move the define_css_keyword_enum macro to the style crate. --- components/plugins/lib.rs | 46 -------------------- components/style/properties/common_types.rs | 47 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index 69f823c2d91..9017958ea39 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -51,52 +51,6 @@ pub fn plugin_registrar(reg: &mut Registry) { } -#[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, ()> { - match component_value { - &::cssparser::ast::Ident(ref value) => { - match_ignore_ascii_case! { value: - $( $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(&self, dest: &mut W) -> ::text_writer::Result - where W: ::text_writer::TextWriter { - match self { - $( &$name::$variant => dest.write_str($css) ),+ - } - } - } - } -} - - #[macro_export] macro_rules! match_ignore_ascii_case { ( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr, ) => { diff --git a/components/style/properties/common_types.rs b/components/style/properties/common_types.rs index 52a0fb3be40..f55d9ee7fb2 100644 --- a/components/style/properties/common_types.rs +++ b/components/style/properties/common_types.rs @@ -3,11 +3,58 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![allow(non_camel_case_types)] +#![macro_escape] use url::{Url, UrlParser}; pub use servo_util::geometry::Au; + +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, ()> { + match component_value { + &::cssparser::ast::Ident(ref value) => { + match_ignore_ascii_case! { value: + $( $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(&self, dest: &mut W) -> ::text_writer::Result + where W: ::text_writer::TextWriter { + match self { + $( &$name::$variant => dest.write_str($css) ),+ + } + } + } + } +} + + pub type CSSFloat = f64; pub mod specified {