mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
servo: Merge #14238 - Implement ToCss serialization for CSSRules (from canaltinova:cssom-tocss); r=Manishearth
<!-- Please describe your changes on the following line: --> Implementation of ToCss serialization for CSSRules. It requires #14190 to merge first to uncomment `CssRule::Style` branch in CssRule's ToCss implementation. r? @Manishearth --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14195 (github issue number if applicable). - [X] These changes do not require tests because it's serialization changes and I'm not sure there is a test for that. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 731264f20e1f19687bf0d77fb364568bd1ac034e
This commit is contained in:
parent
f0f7f3ea1f
commit
3bd7c5ba21
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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>>,
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user