Servo parsing / serialization for @page

Adds basic parsing and serialization for @page rules in Servo.  It is handled
in the same manner as a regular style rule.

MozReview-Commit-ID: JRr3DDGcUIl
This commit is contained in:
J. Ryan Stinnett 2017-03-30 20:05:55 -05:00
parent 6020c2feeb
commit f0e849cbd8
2 changed files with 44 additions and 1 deletions

View file

@ -83,6 +83,7 @@ impl CSSRule {
StyleCssRule::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent_stylesheet, s)),
StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent_stylesheet, s)),
StyleCssRule::Supports(s) => Root::upcast(CSSSupportsRule::new(window, parent_stylesheet, s)),
StyleCssRule::Page(_) => unreachable!(),
}
}

View file

@ -258,6 +258,7 @@ pub enum CssRule {
Viewport(Arc<Locked<ViewportRule>>),
Keyframes(Arc<Locked<KeyframesRule>>),
Supports(Arc<Locked<SupportsRule>>),
Page(Arc<Locked<PageRule>>),
}
#[allow(missing_docs)]
@ -316,6 +317,7 @@ impl CssRule {
CssRule::Namespace(_) => CssRuleType::Namespace,
CssRule::Viewport(_) => CssRuleType::Viewport,
CssRule::Supports(_) => CssRuleType::Supports,
CssRule::Page(_) => CssRuleType::Page,
}
}
@ -349,7 +351,8 @@ impl CssRule {
CssRule::Style(_) |
CssRule::FontFace(_) |
CssRule::Viewport(_) |
CssRule::Keyframes(_) => {
CssRule::Keyframes(_) |
CssRule::Page(_) => {
f(&[], None)
}
CssRule::Media(ref lock) => {
@ -422,6 +425,7 @@ impl ToCssWithGuard for CssRule {
CssRule::Keyframes(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::Media(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::Supports(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::Page(ref lock) => lock.read_with(guard).to_css(guard, dest),
}
}
}
@ -560,6 +564,28 @@ impl ToCssWithGuard for SupportsRule {
}
}
/// A [`@page`][page] rule. This implements only a limited subset of the CSS 2.2 syntax. In this
/// subset, [page selectors][page-selectors] are not implemented.
///
/// [page]: https://drafts.csswg.org/css2/page.html#page-box
/// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors
#[derive(Debug)]
pub struct PageRule(pub Arc<Locked<PropertyDeclarationBlock>>);
impl ToCssWithGuard for PageRule {
// Serialization of PageRule is not specced, adapted from steps for StyleRule.
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
dest.write_str("@page { ")?;
let declaration_block = self.0.read_with(guard);
declaration_block.to_css(dest)?;
if declaration_block.declarations().len() > 0 {
write!(dest, " ")?;
}
dest.write_str("}")
}
}
#[allow(missing_docs)]
#[derive(Debug)]
pub struct StyleRule {
@ -782,6 +808,7 @@ rule_filter! {
effective_viewport_rules(Viewport => ViewportRule),
effective_keyframes_rules(Keyframes => KeyframesRule),
effective_supports_rules(Supports => SupportsRule),
effective_page_rules(Page => PageRule),
}
/// The stylesheet loader is the abstraction used to trigger network requests
@ -858,6 +885,8 @@ enum AtRulePrelude {
Viewport,
/// A @keyframes rule, with its animation name.
Keyframes(Atom),
/// A @page rule prelude.
Page,
}
@ -1043,6 +1072,13 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
Ok(AtRuleType::WithBlock(AtRulePrelude::Keyframes(Atom::from(name))))
},
"page" => {
if cfg!(feature = "gecko") {
Ok(AtRuleType::WithBlock(AtRulePrelude::Page))
} else {
Err(())
}
},
_ => Err(())
}
}
@ -1077,6 +1113,12 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
keyframes: parse_keyframe_list(&self.context, input, self.shared_lock),
}))))
}
AtRulePrelude::Page => {
let declarations = parse_property_declaration_list(self.context, input);
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule(
Arc::new(self.shared_lock.wrap(declarations))
)))))
}
}
}
}