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::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent_stylesheet, s)),
StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::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::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>>), Viewport(Arc<Locked<ViewportRule>>),
Keyframes(Arc<Locked<KeyframesRule>>), Keyframes(Arc<Locked<KeyframesRule>>),
Supports(Arc<Locked<SupportsRule>>), Supports(Arc<Locked<SupportsRule>>),
Page(Arc<Locked<PageRule>>),
} }
#[allow(missing_docs)] #[allow(missing_docs)]
@ -316,6 +317,7 @@ impl CssRule {
CssRule::Namespace(_) => CssRuleType::Namespace, CssRule::Namespace(_) => CssRuleType::Namespace,
CssRule::Viewport(_) => CssRuleType::Viewport, CssRule::Viewport(_) => CssRuleType::Viewport,
CssRule::Supports(_) => CssRuleType::Supports, CssRule::Supports(_) => CssRuleType::Supports,
CssRule::Page(_) => CssRuleType::Page,
} }
} }
@ -349,7 +351,8 @@ impl CssRule {
CssRule::Style(_) | CssRule::Style(_) |
CssRule::FontFace(_) | CssRule::FontFace(_) |
CssRule::Viewport(_) | CssRule::Viewport(_) |
CssRule::Keyframes(_) => { CssRule::Keyframes(_) |
CssRule::Page(_) => {
f(&[], None) f(&[], None)
} }
CssRule::Media(ref lock) => { 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::Keyframes(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::Media(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::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)] #[allow(missing_docs)]
#[derive(Debug)] #[derive(Debug)]
pub struct StyleRule { pub struct StyleRule {
@ -782,6 +808,7 @@ rule_filter! {
effective_viewport_rules(Viewport => ViewportRule), effective_viewport_rules(Viewport => ViewportRule),
effective_keyframes_rules(Keyframes => KeyframesRule), effective_keyframes_rules(Keyframes => KeyframesRule),
effective_supports_rules(Supports => SupportsRule), effective_supports_rules(Supports => SupportsRule),
effective_page_rules(Page => PageRule),
} }
/// The stylesheet loader is the abstraction used to trigger network requests /// The stylesheet loader is the abstraction used to trigger network requests
@ -858,6 +885,8 @@ enum AtRulePrelude {
Viewport, Viewport,
/// A @keyframes rule, with its animation name. /// A @keyframes rule, with its animation name.
Keyframes(Atom), 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)))) Ok(AtRuleType::WithBlock(AtRulePrelude::Keyframes(Atom::from(name))))
}, },
"page" => {
if cfg!(feature = "gecko") {
Ok(AtRuleType::WithBlock(AtRulePrelude::Page))
} else {
Err(())
}
},
_ => Err(()) _ => Err(())
} }
} }
@ -1077,6 +1113,12 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
keyframes: parse_keyframe_list(&self.context, input, self.shared_lock), 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))
)))))
}
} }
} }
} }