diff options
author | Nazım Can Altınova <canaltinova@gmail.com> | 2016-11-15 23:25:03 +0300 |
---|---|---|
committer | Nazım Can Altınova <canaltinova@gmail.com> | 2016-11-18 12:17:53 +0300 |
commit | fdbadcdce224be644fcac44b4dcc1aea2b711aa5 (patch) | |
tree | 3fc5f4ed3e9157ad677c9702236e8720b4d7a088 | |
parent | 22aebdf5d41a3509cd6515ccf5edcdf33715a76d (diff) | |
download | servo-fdbadcdce224be644fcac44b4dcc1aea2b711aa5.tar.gz servo-fdbadcdce224be644fcac44b4dcc1aea2b711aa5.zip |
Implement ToCss serialization for CSSRules
-rw-r--r-- | components/script/dom/cssfontfacerule.rs | 4 | ||||
-rw-r--r-- | components/script/dom/csskeyframesrule.rs | 4 | ||||
-rw-r--r-- | components/script/dom/cssmediarule.rs | 4 | ||||
-rw-r--r-- | components/script/dom/cssnamespacerule.rs | 4 | ||||
-rw-r--r-- | components/script/dom/cssviewportrule.rs | 4 | ||||
-rw-r--r-- | components/style/font_face.rs | 46 | ||||
-rw-r--r-- | components/style/keyframes.rs | 17 | ||||
-rw-r--r-- | components/style/stylesheets.rs | 58 | ||||
-rw-r--r-- | components/style/values/specified/url.rs | 7 | ||||
-rw-r--r-- | components/style/viewport.rs | 78 |
10 files changed, 198 insertions, 28 deletions
diff --git a/components/script/dom/cssfontfacerule.rs b/components/script/dom/cssfontfacerule.rs index 88dcaf4603f..18371c89c45 100644 --- a/components/script/dom/cssfontfacerule.rs +++ b/components/script/dom/cssfontfacerule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::font_face::FontFaceRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSFontFaceRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSFontFaceRule { } fn get_css(&self) -> DOMString { - // self.fontfacerule.read().to_css_string().into() - "".into() + self.fontfacerule.read().to_css_string().into() } } diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index 3fced7751d6..138c8b20558 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::KeyframesRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSKeyframesRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSKeyframesRule { } fn get_css(&self) -> DOMString { - // self.keyframesrule.read().to_css_string().into() - "".into() + self.keyframesrule.read().to_css_string().into() } } diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index dc4f3e586ba..a8d8649b31f 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -13,6 +13,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::MediaRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSMediaRule { @@ -45,7 +46,6 @@ impl SpecificCSSRule for CSSMediaRule { } fn get_css(&self) -> DOMString { - // self.mediarule.read().to_css_string().into() - "".into() + self.mediarule.read().to_css_string().into() } } diff --git a/components/script/dom/cssnamespacerule.rs b/components/script/dom/cssnamespacerule.rs index 2c0866c5dbe..04c4431df77 100644 --- a/components/script/dom/cssnamespacerule.rs +++ b/components/script/dom/cssnamespacerule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::NamespaceRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSNamespaceRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSNamespaceRule { } fn get_css(&self) -> DOMString { - // self.namespacerule.read().to_css_string().into() - "".into() + self.namespacerule.read().to_css_string().into() } } diff --git a/components/script/dom/cssviewportrule.rs b/components/script/dom/cssviewportrule.rs index 89f1ada597d..f534c535a64 100644 --- a/components/script/dom/cssviewportrule.rs +++ b/components/script/dom/cssviewportrule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::viewport::ViewportRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSViewportRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSViewportRule { } fn get_css(&self) -> DOMString { - // self.viewportrule.read().to_css_string().into() - "".into() + self.viewportrule.read().to_css_string().into() } } diff --git a/components/style/font_face.rs b/components/style/font_face.rs index 8fc2d51c100..62d8f6ade19 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -10,7 +10,9 @@ use computed_values::font_family::FontFamily; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use parser::{ParserContext, log_css_error}; use properties::longhands::font_family::parse_one_family; +use std::fmt; use std::iter; +use style_traits::ToCss; use values::specified::url::SpecifiedUrl; #[derive(Clone, Debug, PartialEq, Eq)] @@ -20,6 +22,22 @@ pub enum Source { Local(FontFamily), } +impl ToCss for Source { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + Source::Url(ref url) => { + try!(dest.write_str("local(\"")); + try!(url.to_css(dest)); + }, + Source::Local(ref family) => { + try!(dest.write_str("url(\"")); + try!(family.to_css(dest)); + }, + } + dest.write_str("\")") + } +} + #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] pub struct UrlSource { @@ -27,6 +45,12 @@ pub struct UrlSource { pub format_hints: Vec<String>, } +impl ToCss for UrlSource { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + dest.write_str(self.url.as_str()) + } +} + #[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct FontFaceRule { @@ -34,6 +58,28 @@ pub struct FontFaceRule { pub sources: Vec<Source>, } +impl ToCss for FontFaceRule { + // Serialization of FontFaceRule is not specced. + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(dest.write_str("@font-face { font-family: ")); + try!(self.family.to_css(dest)); + try!(dest.write_str(";")); + + if self.sources.len() > 0 { + try!(dest.write_str(" src: ")); + let mut iter = self.sources.iter(); + try!(iter.next().unwrap().to_css(dest)); + for source in iter { + try!(dest.write_str(", ")); + try!(source.to_css(dest)); + } + try!(dest.write_str(";")); + } + + dest.write_str(" }") + } +} + pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) -> Result<FontFaceRule, ()> { let mut family = None; diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index f825fe11a52..c13cd1b5431 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -9,7 +9,9 @@ use parser::{ParserContext, log_css_error}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; use properties::PropertyDeclarationParseResult; use properties::animated_properties::TransitionProperty; +use std::fmt; use std::sync::Arc; +use style_traits::ToCss; /// A number from 1 to 100, indicating the percentage of the animation where /// this keyframe should run. @@ -82,6 +84,21 @@ pub struct Keyframe { pub block: Arc<RwLock<PropertyDeclarationBlock>>, } +impl ToCss for Keyframe { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let mut iter = self.selector.percentages().iter(); + try!(write!(dest, "{}%", iter.next().unwrap().0)); + for percentage in iter { + try!(write!(dest, ", ")); + try!(write!(dest, "{}%", percentage.0)); + } + try!(dest.write_str(" { ")); + try!(self.block.read().to_css(dest)); + try!(dest.write_str(" }")); + Ok(()) + } +} + /// A keyframes step value. This can be a synthetised keyframes animation, that /// is, one autogenerated from the current computed values, or a list of /// declarations to apply. diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 8b632737a89..60b4ba9ec6d 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -107,6 +107,20 @@ impl CssRule { } } +impl ToCss for CssRule { + // https://drafts.csswg.org/cssom/#serialize-a-css-rule + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + CssRule::Namespace(ref lock) => lock.read().to_css(dest), + CssRule::Style(ref lock) => lock.read().to_css(dest), + CssRule::FontFace(ref lock) => lock.read().to_css(dest), + CssRule::Viewport(ref lock) => lock.read().to_css(dest), + CssRule::Keyframes(ref lock) => lock.read().to_css(dest), + CssRule::Media(ref lock) => lock.read().to_css(dest), + } + } +} + #[derive(Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct NamespaceRule { @@ -115,18 +129,62 @@ pub struct NamespaceRule { pub url: Namespace, } +impl ToCss for NamespaceRule { + // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSNamespaceRule + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(dest.write_str("@namespace ")); + if let Some(ref prefix) = self.prefix { + try!(dest.write_str(&*prefix.to_string())); + try!(dest.write_str(" ")); + } + try!(dest.write_str("url(\"")); + try!(dest.write_str(&*self.url.to_string())); + dest.write_str("\");") + } +} + #[derive(Debug)] pub struct KeyframesRule { pub name: Atom, pub keyframes: Vec<Arc<RwLock<Keyframe>>>, } +impl ToCss for KeyframesRule { + // Serialization of KeyframesRule is not specced. + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(dest.write_str("@keyframes ")); + try!(dest.write_str(&*self.name.to_string())); + try!(dest.write_str(" { ")); + let iter = self.keyframes.iter(); + for lock in iter { + let keyframe = lock.read(); + try!(keyframe.to_css(dest)); + } + dest.write_str(" }") + } +} + #[derive(Debug)] pub struct MediaRule { pub media_queries: Arc<RwLock<MediaList>>, pub rules: CssRules, } +impl ToCss for MediaRule { + // Serialization of MediaRule is not specced. + // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSMediaRule + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(dest.write_str("@media (")); + try!(self.media_queries.read().to_css(dest)); + try!(dest.write_str(") {")); + for rule in self.rules.0.read().iter() { + try!(dest.write_str(" ")); + try!(rule.to_css(dest)); + } + dest.write_str(" }") + } +} + #[derive(Debug)] pub struct StyleRule { pub selectors: Vec<Selector<TheSelectorImpl>>, diff --git a/components/style/values/specified/url.rs b/components/style/values/specified/url.rs index 84fb5faf4a7..08a13be04f6 100644 --- a/components/style/values/specified/url.rs +++ b/components/style/values/specified/url.rs @@ -104,6 +104,13 @@ impl SpecifiedUrl { self.resolved.as_ref() } + pub fn as_str(&self) -> &str { + match self.resolved { + Some(ref url) => url.as_str(), + None => "", + } + } + /// Little helper for Gecko's ffi. pub fn as_slice_components(&self) -> (*const u8, usize) { match self.resolved { diff --git a/components/style/viewport.rs b/components/style/viewport.rs index a033a1c31d7..bbdd3a2ed35 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -9,6 +9,7 @@ use app_units::Au; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important}; +use cssparser::ToCss as ParserToCss; use euclid::scale_factor::ScaleFactor; use euclid::size::{Size2D, TypedSize2D}; use media_queries::Device; @@ -26,32 +27,34 @@ use values::computed::{Context, ToComputedValue}; use values::specified::{Length, LengthOrPercentageOrAuto, ViewportPercentageLength}; macro_rules! declare_viewport_descriptor { - ( $( $variant: ident($data: ident), )+ ) => { - declare_viewport_descriptor_inner!([] [ $( $variant($data), )+ ] 0); + ( $( $variant_name: expr => $variant: ident($data: ident), )+ ) => { + declare_viewport_descriptor_inner!([] [ $( $variant_name => $variant($data), )+ ] 0); }; } macro_rules! declare_viewport_descriptor_inner { ( - [ $( $assigned_variant: ident($assigned_data: ident) = $assigned_discriminant: expr, )* ] + [ $( $assigned_variant_name: expr => + $assigned_variant: ident($assigned_data: ident) = $assigned_discriminant: expr, )* ] [ - $next_variant: ident($next_data: ident), - $( $variant: ident($data: ident), )* + $next_variant_name: expr => $next_variant: ident($next_data: ident), + $( $variant_name: expr => $variant: ident($data: ident), )* ] $next_discriminant: expr ) => { declare_viewport_descriptor_inner! { [ - $( $assigned_variant($assigned_data) = $assigned_discriminant, )* - $next_variant($next_data) = $next_discriminant, + $( $assigned_variant_name => $assigned_variant($assigned_data) = $assigned_discriminant, )* + $next_variant_name => $next_variant($next_data) = $next_discriminant, ] - [ $( $variant($data), )* ] + [ $( $variant_name => $variant($data), )* ] $next_discriminant + 1 } }; ( - [ $( $assigned_variant: ident($assigned_data: ident) = $assigned_discriminant: expr, )* ] + [ $( $assigned_variant_name: expr => + $assigned_variant: ident($assigned_data: ident) = $assigned_discriminant: expr, )* ] [ ] $number_of_variants: expr ) => { @@ -74,22 +77,37 @@ macro_rules! declare_viewport_descriptor_inner { } } } + + impl ToCss for ViewportDescriptor { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + $( + ViewportDescriptor::$assigned_variant(val) => { + try!(dest.write_str($assigned_variant_name)); + try!(dest.write_str(": ")); + try!(val.to_css(dest)); + }, + )* + } + dest.write_str(";") + } + } }; } declare_viewport_descriptor! { - MinWidth(ViewportLength), - MaxWidth(ViewportLength), + "min-width" => MinWidth(ViewportLength), + "max-width" => MaxWidth(ViewportLength), - MinHeight(ViewportLength), - MaxHeight(ViewportLength), + "min-height" => MinHeight(ViewportLength), + "max-height" => MaxHeight(ViewportLength), - Zoom(Zoom), - MinZoom(Zoom), - MaxZoom(Zoom), + "zoom" => Zoom(Zoom), + "min-zoom" => MinZoom(Zoom), + "max-zoom" => MaxZoom(Zoom), - UserZoom(UserZoom), - Orientation(Orientation), + "user-zoom" => UserZoom(UserZoom), + "orientation" => Orientation(Orientation), } trait FromMeta: Sized { @@ -210,6 +228,16 @@ impl ViewportDescriptorDeclaration { } } +impl ToCss for ViewportDescriptorDeclaration { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(self.descriptor.to_css(dest)); + if self.important { + try!(dest.write_str(" !important")); + } + dest.write_str(";") + } +} + fn parse_shorthand(input: &mut Parser) -> Result<[ViewportLength; 2], ()> { let min = try!(ViewportLength::parse(input)); match input.try(|input| ViewportLength::parse(input)) { @@ -467,6 +495,20 @@ impl ViewportRule { } } +impl ToCss for ViewportRule { + // Serialization of ViewportRule is not specced. + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(dest.write_str("@viewport { ")); + let mut iter = self.declarations.iter(); + try!(iter.next().unwrap().to_css(dest)); + for declaration in iter { + try!(dest.write_str(" ")); + try!(declaration.to_css(dest)); + } + dest.write_str(" }") + } +} + /// Computes the cascade precedence as according to /// http://dev.w3.org/csswg/css-cascade/#cascade-origin fn cascade_precendence(origin: Origin, important: bool) -> u8 { |