Introduce a ToCssWithGuard trait

This commit is contained in:
Simon Sapin 2017-03-17 00:19:09 +01:00
parent 3ae2ecbec2
commit fe4e70c5f8
16 changed files with 104 additions and 54 deletions

View file

@ -14,6 +14,7 @@ use computed_values::font_family::FamilyName;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
#[cfg(feature = "gecko")] use cssparser::UnicodeRange;
use parser::{ParserContext, log_css_error, Parse};
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt;
use std::iter;
use style_traits::{ToCss, OneOrMoreCommaSeparated};
@ -230,11 +231,10 @@ macro_rules! font_face_descriptors {
}
}
impl ToCss for FontFaceRule {
impl ToCssWithGuard for FontFaceRule {
// Serialization of FontFaceRule is not specced.
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
{
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
dest.write_str("@font-face {\n")?;
$(
dest.write_str(concat!(" ", $m_name, ": "))?;

View file

@ -160,3 +160,20 @@ mod compile_time_assert {
impl<'a> Marker2 for SharedRwLockReadGuard<'a> {} // Assert SharedRwLockReadGuard: !Copy
impl<'a> Marker2 for SharedRwLockWriteGuard<'a> {} // Assert SharedRwLockWriteGuard: !Copy
}
/// Like ToCss, but with a lock guard given by the caller.
pub trait ToCssWithGuard {
/// Serialize `self` in CSS syntax, writing to `dest`, using the given lock guard.
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write;
/// Serialize `self` in CSS syntax using the given lock guard and return a string.
///
/// (This is a convenience wrapper for `to_css` and probably should not be overridden.)
#[inline]
fn to_css_string(&self, guard: &SharedRwLockReadGuard) -> String {
let mut s = String::new();
self.to_css(guard, &mut s).unwrap();
s
}
}

View file

@ -21,7 +21,7 @@ use selector_parser::{SelectorImpl, SelectorParser};
use selectors::parser::SelectorList;
use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use shared_lock::{SharedRwLock, Locked, SharedRwLockReadGuard};
use shared_lock::{SharedRwLock, Locked, SharedRwLockReadGuard, ToCssWithGuard};
use std::cell::Cell;
use std::fmt;
use std::sync::Arc;
@ -372,18 +372,19 @@ impl CssRule {
}
}
impl ToCss for CssRule {
impl ToCssWithGuard 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 {
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
match *self {
CssRule::Namespace(ref lock) => lock.read().to_css(dest),
CssRule::Import(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),
CssRule::Supports(ref lock) => lock.read().to_css(dest),
CssRule::Namespace(ref lock) => lock.read().to_css(guard, dest),
CssRule::Import(ref lock) => lock.read().to_css(guard, dest),
CssRule::Style(ref lock) => lock.read().to_css(guard, dest),
CssRule::FontFace(ref lock) => lock.read().to_css(guard, dest),
CssRule::Viewport(ref lock) => lock.read().to_css(guard, dest),
CssRule::Keyframes(ref lock) => lock.read().to_css(guard, dest),
CssRule::Media(ref lock) => lock.read().to_css(guard, dest),
CssRule::Supports(ref lock) => lock.read().to_css(guard, dest),
}
}
}
@ -396,9 +397,10 @@ pub struct NamespaceRule {
pub url: Namespace,
}
impl ToCss for NamespaceRule {
impl ToCssWithGuard 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 {
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, 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()));
@ -426,12 +428,12 @@ pub struct ImportRule {
pub stylesheet: Arc<Stylesheet>,
}
impl ToCss for ImportRule {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
impl ToCssWithGuard for ImportRule {
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
try!(dest.write_str("@import "));
try!(self.url.to_css(dest));
let guard = self.stylesheet.shared_lock.read(); // FIXME: have the caller pass this?
let media = self.stylesheet.media.read_with(&guard);
let media = self.stylesheet.media.read_with(guard);
if !media.is_empty() {
try!(dest.write_str(" "));
try!(media.to_css(dest));
@ -451,9 +453,10 @@ pub struct KeyframesRule {
pub keyframes: Vec<Arc<RwLock<Keyframe>>>,
}
impl ToCss for KeyframesRule {
impl ToCssWithGuard for KeyframesRule {
// Serialization of KeyframesRule is not specced.
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, 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(" { "));
@ -478,16 +481,17 @@ pub struct MediaRule {
pub rules: Arc<RwLock<CssRules>>,
}
impl ToCss for MediaRule {
impl ToCssWithGuard 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 {
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, 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.read().0.iter() {
try!(dest.write_str(" "));
try!(rule.to_css(dest));
try!(rule.to_css(guard, dest));
}
dest.write_str(" }")
}
@ -505,14 +509,15 @@ pub struct SupportsRule {
pub enabled: bool,
}
impl ToCss for SupportsRule {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
impl ToCssWithGuard for SupportsRule {
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
try!(dest.write_str("@supports "));
try!(self.condition.to_css(dest));
try!(dest.write_str(" {"));
for rule in self.rules.read().0.iter() {
try!(dest.write_str(" "));
try!(rule.to_css(dest));
try!(rule.to_css(guard, dest));
}
dest.write_str(" }")
}
@ -525,9 +530,10 @@ pub struct StyleRule {
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
}
impl ToCss for StyleRule {
impl ToCssWithGuard for StyleRule {
// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
// Step 1
try!(self.selectors.to_css(dest));
// Step 2

View file

@ -15,7 +15,7 @@ use cssparser::ToCss as ParserToCss;
use euclid::size::TypedSize2D;
use media_queries::Device;
use parser::{ParserContext, log_css_error};
use shared_lock::SharedRwLockReadGuard;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::fmt;
@ -505,9 +505,10 @@ impl ViewportRule {
}
}
impl ToCss for ViewportRule {
impl ToCssWithGuard for ViewportRule {
// Serialization of ViewportRule is not specced.
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, 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));