mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Auto merge of #16315 - jryans:at-page-stylo, r=xidorn
Stylo: @page support Reviewed by upsuper in https://bugzilla.mozilla.org/show_bug.cgi?id=1345206. - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16315) <!-- Reviewable:end -->
This commit is contained in:
commit
80f6160580
13 changed files with 150 additions and 22 deletions
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#![allow(non_snake_case, missing_docs)]
|
#![allow(non_snake_case, missing_docs)]
|
||||||
|
|
||||||
use gecko_bindings::bindings::{RawServoMediaList, RawServoMediaRule, RawServoNamespaceRule};
|
use gecko_bindings::bindings::{RawServoMediaList, RawServoMediaRule, RawServoNamespaceRule, RawServoPageRule};
|
||||||
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
|
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
|
||||||
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
|
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
|
||||||
use gecko_bindings::structs::{RawServoAnimationValue, RawServoAnimationValueMap, RawServoDeclarationBlock};
|
use gecko_bindings::structs::{RawServoAnimationValue, RawServoAnimationValueMap, RawServoDeclarationBlock};
|
||||||
|
@ -18,7 +18,7 @@ use parking_lot::RwLock;
|
||||||
use properties::{ComputedValues, PropertyDeclarationBlock};
|
use properties::{ComputedValues, PropertyDeclarationBlock};
|
||||||
use properties::animated_properties::{AnimationValue, AnimationValueMap};
|
use properties::animated_properties::{AnimationValue, AnimationValueMap};
|
||||||
use shared_lock::Locked;
|
use shared_lock::Locked;
|
||||||
use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule, MediaRule, NamespaceRule};
|
use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule, MediaRule, NamespaceRule, PageRule};
|
||||||
|
|
||||||
macro_rules! impl_arc_ffi {
|
macro_rules! impl_arc_ffi {
|
||||||
($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
|
($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
|
||||||
|
@ -71,3 +71,6 @@ impl_arc_ffi!(Locked<MediaRule> => RawServoMediaRule
|
||||||
|
|
||||||
impl_arc_ffi!(Locked<NamespaceRule> => RawServoNamespaceRule
|
impl_arc_ffi!(Locked<NamespaceRule> => RawServoNamespaceRule
|
||||||
[Servo_NamespaceRule_AddRef, Servo_NamespaceRule_Release]);
|
[Servo_NamespaceRule_AddRef, Servo_NamespaceRule_Release]);
|
||||||
|
|
||||||
|
impl_arc_ffi!(Locked<PageRule> => RawServoPageRule
|
||||||
|
[Servo_PageRule_AddRef, Servo_PageRule_Release]);
|
||||||
|
|
|
@ -235,6 +235,11 @@ pub type RawServoNamespaceRuleBorrowed<'a> = &'a RawServoNamespaceRule;
|
||||||
pub type RawServoNamespaceRuleBorrowedOrNull<'a> = Option<&'a RawServoNamespaceRule>;
|
pub type RawServoNamespaceRuleBorrowedOrNull<'a> = Option<&'a RawServoNamespaceRule>;
|
||||||
enum RawServoNamespaceRuleVoid { }
|
enum RawServoNamespaceRuleVoid { }
|
||||||
pub struct RawServoNamespaceRule(RawServoNamespaceRuleVoid);
|
pub struct RawServoNamespaceRule(RawServoNamespaceRuleVoid);
|
||||||
|
pub type RawServoPageRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoPageRule>;
|
||||||
|
pub type RawServoPageRuleBorrowed<'a> = &'a RawServoPageRule;
|
||||||
|
pub type RawServoPageRuleBorrowedOrNull<'a> = Option<&'a RawServoPageRule>;
|
||||||
|
enum RawServoPageRuleVoid { }
|
||||||
|
pub struct RawServoPageRule(RawServoPageRuleVoid);
|
||||||
pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>;
|
pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>;
|
||||||
pub type RawServoStyleSetOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<RawServoStyleSet>;
|
pub type RawServoStyleSetOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<RawServoStyleSet>;
|
||||||
pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet;
|
pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet;
|
||||||
|
@ -380,6 +385,12 @@ extern "C" {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_NamespaceRule_Release(ptr: RawServoNamespaceRuleBorrowed);
|
pub fn Servo_NamespaceRule_Release(ptr: RawServoNamespaceRuleBorrowed);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_PageRule_AddRef(ptr: RawServoPageRuleBorrowed);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_PageRule_Release(ptr: RawServoPageRuleBorrowed);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned);
|
pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned);
|
||||||
}
|
}
|
||||||
|
@ -1556,6 +1567,18 @@ extern "C" {
|
||||||
pub fn Servo_NamespaceRule_GetCssText(rule: RawServoNamespaceRuleBorrowed,
|
pub fn Servo_NamespaceRule_GetCssText(rule: RawServoNamespaceRuleBorrowed,
|
||||||
result: *mut nsAString);
|
result: *mut nsAString);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_CssRules_GetPageRuleAt(rules: ServoCssRulesBorrowed,
|
||||||
|
index: u32) -> RawServoPageRuleStrong;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_PageRule_Debug(rule: RawServoPageRuleBorrowed,
|
||||||
|
result: *mut nsACString);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_PageRule_GetCssText(rule: RawServoPageRuleBorrowed,
|
||||||
|
result: *mut nsAString);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed,
|
pub fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed,
|
||||||
index: u32)
|
index: u32)
|
||||||
|
@ -1590,6 +1613,15 @@ extern "C" {
|
||||||
pub fn Servo_NamespaceRule_GetURI(rule: RawServoNamespaceRuleBorrowed)
|
pub fn Servo_NamespaceRule_GetURI(rule: RawServoNamespaceRuleBorrowed)
|
||||||
-> *mut nsIAtom;
|
-> *mut nsIAtom;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_PageRule_GetStyle(rule: RawServoPageRuleBorrowed)
|
||||||
|
-> RawServoDeclarationBlockStrong;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_PageRule_SetStyle(rule: RawServoPageRuleBorrowed,
|
||||||
|
declarations:
|
||||||
|
RawServoDeclarationBlockBorrowed);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_ParseProperty(property: *const nsACString,
|
pub fn Servo_ParseProperty(property: *const nsACString,
|
||||||
value: *const nsACString,
|
value: *const nsACString,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use shared_lock::{SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use stylesheets::{MemoryHoleReporter, Stylesheet};
|
use stylesheets::{CssRuleType, MemoryHoleReporter, Stylesheet};
|
||||||
|
|
||||||
/// A number from 0 to 1, indicating the percentage of the animation when this
|
/// A number from 0 to 1, indicating the percentage of the animation when this
|
||||||
/// keyframe should run.
|
/// keyframe should run.
|
||||||
|
@ -403,7 +403,7 @@ impl<'a, 'b> DeclarationParser for KeyframeDeclarationParser<'a, 'b> {
|
||||||
|
|
||||||
fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<ParsedDeclaration, ()> {
|
fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<ParsedDeclaration, ()> {
|
||||||
let id = try!(PropertyId::parse(name.into()));
|
let id = try!(PropertyId::parse(name.into()));
|
||||||
match ParsedDeclaration::parse(id, self.context, input, true) {
|
match ParsedDeclaration::parse(id, self.context, input, true, CssRuleType::Keyframe) {
|
||||||
Ok(parsed) => {
|
Ok(parsed) => {
|
||||||
// In case there is still unparsed text in the declaration, we should roll back.
|
// In case there is still unparsed text in the declaration, we should roll back.
|
||||||
if !input.is_exhausted() {
|
if !input.is_exhausted() {
|
||||||
|
|
|
@ -97,7 +97,8 @@ class Longhand(object):
|
||||||
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False,
|
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False,
|
||||||
allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
|
allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
|
||||||
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False,
|
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False,
|
||||||
creates_stacking_context=False, fixpos_cb=False, abspos_cb=False):
|
creates_stacking_context=False, fixpos_cb=False, abspos_cb=False,
|
||||||
|
allowed_in_page_rule=False):
|
||||||
self.name = name
|
self.name = name
|
||||||
if not spec:
|
if not spec:
|
||||||
raise TypeError("Spec should be specified for %s" % name)
|
raise TypeError("Spec should be specified for %s" % name)
|
||||||
|
@ -124,6 +125,7 @@ class Longhand(object):
|
||||||
self.creates_stacking_context = arg_to_bool(creates_stacking_context)
|
self.creates_stacking_context = arg_to_bool(creates_stacking_context)
|
||||||
self.fixpos_cb = arg_to_bool(fixpos_cb)
|
self.fixpos_cb = arg_to_bool(fixpos_cb)
|
||||||
self.abspos_cb = arg_to_bool(abspos_cb)
|
self.abspos_cb = arg_to_bool(abspos_cb)
|
||||||
|
self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule)
|
||||||
|
|
||||||
# https://drafts.csswg.org/css-animations/#keyframes
|
# https://drafts.csswg.org/css-animations/#keyframes
|
||||||
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
||||||
|
@ -154,7 +156,8 @@ class Longhand(object):
|
||||||
|
|
||||||
class Shorthand(object):
|
class Shorthand(object):
|
||||||
def __init__(self, name, sub_properties, spec=None, experimental=False, internal=False,
|
def __init__(self, name, sub_properties, spec=None, experimental=False, internal=False,
|
||||||
allowed_in_keyframe_block=True, alias=None, extra_prefixes=None):
|
allowed_in_keyframe_block=True, alias=None, extra_prefixes=None,
|
||||||
|
allowed_in_page_rule=False):
|
||||||
self.name = name
|
self.name = name
|
||||||
if not spec:
|
if not spec:
|
||||||
raise TypeError("Spec should be specified for %s" % name)
|
raise TypeError("Spec should be specified for %s" % name)
|
||||||
|
@ -167,6 +170,7 @@ class Shorthand(object):
|
||||||
self.internal = internal
|
self.internal = internal
|
||||||
self.alias = alias.split() if alias else []
|
self.alias = alias.split() if alias else []
|
||||||
self.extra_prefixes = extra_prefixes.split() if extra_prefixes else []
|
self.extra_prefixes = extra_prefixes.split() if extra_prefixes else []
|
||||||
|
self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule)
|
||||||
|
|
||||||
# https://drafts.csswg.org/css-animations/#keyframes
|
# https://drafts.csswg.org/css-animations/#keyframes
|
||||||
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
||||||
|
|
|
@ -12,7 +12,7 @@ use error_reporting::ParseErrorReporter;
|
||||||
use parser::{ParserContext, log_css_error};
|
use parser::{ParserContext, log_css_error};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use stylesheets::{Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
use super::*;
|
use super::*;
|
||||||
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
|
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ pub fn parse_style_attribute(input: &str,
|
||||||
error_reporter: &ParseErrorReporter)
|
error_reporter: &ParseErrorReporter)
|
||||||
-> PropertyDeclarationBlock {
|
-> PropertyDeclarationBlock {
|
||||||
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
|
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
|
||||||
parse_property_declaration_list(&context, &mut Parser::new(input))
|
parse_property_declaration_list(&context, &mut Parser::new(input), CssRuleType::Style)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a given property declaration. Can result in multiple
|
/// Parse a given property declaration. Can result in multiple
|
||||||
|
@ -628,7 +628,7 @@ pub fn parse_one_declaration(id: PropertyId,
|
||||||
-> Result<ParsedDeclaration, ()> {
|
-> Result<ParsedDeclaration, ()> {
|
||||||
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
|
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
|
||||||
Parser::new(input).parse_entirely(|parser| {
|
Parser::new(input).parse_entirely(|parser| {
|
||||||
ParsedDeclaration::parse(id, &context, parser, false)
|
ParsedDeclaration::parse(id, &context, parser, false, CssRuleType::Style)
|
||||||
.map_err(|_| ())
|
.map_err(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -636,6 +636,7 @@ pub fn parse_one_declaration(id: PropertyId,
|
||||||
/// A struct to parse property declarations.
|
/// A struct to parse property declarations.
|
||||||
struct PropertyDeclarationParser<'a, 'b: 'a> {
|
struct PropertyDeclarationParser<'a, 'b: 'a> {
|
||||||
context: &'a ParserContext<'b>,
|
context: &'a ParserContext<'b>,
|
||||||
|
rule_type: CssRuleType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -653,7 +654,7 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> {
|
||||||
-> Result<(ParsedDeclaration, Importance), ()> {
|
-> Result<(ParsedDeclaration, Importance), ()> {
|
||||||
let id = try!(PropertyId::parse(name.into()));
|
let id = try!(PropertyId::parse(name.into()));
|
||||||
let parsed = input.parse_until_before(Delimiter::Bang, |input| {
|
let parsed = input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
ParsedDeclaration::parse(id, self.context, input, false)
|
ParsedDeclaration::parse(id, self.context, input, false, self.rule_type)
|
||||||
.map_err(|_| ())
|
.map_err(|_| ())
|
||||||
})?;
|
})?;
|
||||||
let importance = match input.try(parse_important) {
|
let importance = match input.try(parse_important) {
|
||||||
|
@ -672,11 +673,13 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> {
|
||||||
/// Parse a list of property declarations and return a property declaration
|
/// Parse a list of property declarations and return a property declaration
|
||||||
/// block.
|
/// block.
|
||||||
pub fn parse_property_declaration_list(context: &ParserContext,
|
pub fn parse_property_declaration_list(context: &ParserContext,
|
||||||
input: &mut Parser)
|
input: &mut Parser,
|
||||||
|
rule_type: CssRuleType)
|
||||||
-> PropertyDeclarationBlock {
|
-> PropertyDeclarationBlock {
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
let parser = PropertyDeclarationParser {
|
let parser = PropertyDeclarationParser {
|
||||||
context: context,
|
context: context,
|
||||||
|
rule_type: rule_type,
|
||||||
};
|
};
|
||||||
let mut iter = DeclarationListParser::new(input, parser);
|
let mut iter = DeclarationListParser::new(input, parser);
|
||||||
while let Some(declaration) = iter.next() {
|
while let Some(declaration) = iter.next() {
|
||||||
|
|
|
@ -15,5 +15,6 @@
|
||||||
${helpers.predefined_type("margin-%s" % side[0], "LengthOrPercentageOrAuto",
|
${helpers.predefined_type("margin-%s" % side[0], "LengthOrPercentageOrAuto",
|
||||||
"computed::LengthOrPercentageOrAuto::Length(Au(0))",
|
"computed::LengthOrPercentageOrAuto::Length(Au(0))",
|
||||||
alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"),
|
alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"),
|
||||||
animation_type="normal", logical = side[1], spec = spec)}
|
animation_type="normal", logical = side[1], spec = spec,
|
||||||
|
allowed_in_page_rule=True)}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
|
@ -32,7 +32,7 @@ use properties::animated_properties::TransitionProperty;
|
||||||
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
|
||||||
use shared_lock::StylesheetGuards;
|
use shared_lock::StylesheetGuards;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use stylesheets::{Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||||
#[cfg(feature = "servo")] use values::Either;
|
#[cfg(feature = "servo")] use values::Either;
|
||||||
use values::{HasViewportPercentage, computed};
|
use values::{HasViewportPercentage, computed};
|
||||||
use cascade_info::CascadeInfo;
|
use cascade_info::CascadeInfo;
|
||||||
|
@ -977,8 +977,12 @@ impl ParsedDeclaration {
|
||||||
/// to Importance::Normal. Parsing Importance values is the job of PropertyDeclarationParser,
|
/// to Importance::Normal. Parsing Importance values is the job of PropertyDeclarationParser,
|
||||||
/// we only set them here so that we don't have to reallocate
|
/// we only set them here so that we don't have to reallocate
|
||||||
pub fn parse(id: PropertyId, context: &ParserContext, input: &mut Parser,
|
pub fn parse(id: PropertyId, context: &ParserContext, input: &mut Parser,
|
||||||
in_keyframe_block: bool)
|
in_keyframe_block: bool, rule_type: CssRuleType)
|
||||||
-> Result<ParsedDeclaration, PropertyDeclarationParseError> {
|
-> Result<ParsedDeclaration, PropertyDeclarationParseError> {
|
||||||
|
debug_assert!(rule_type == CssRuleType::Keyframe ||
|
||||||
|
rule_type == CssRuleType::Page ||
|
||||||
|
rule_type == CssRuleType::Style,
|
||||||
|
"Declarations are only expected inside a keyframe, page, or style rule.");
|
||||||
match id {
|
match id {
|
||||||
PropertyId::Custom(name) => {
|
PropertyId::Custom(name) => {
|
||||||
let value = match input.try(|i| CSSWideKeyword::parse(context, i)) {
|
let value = match input.try(|i| CSSWideKeyword::parse(context, i)) {
|
||||||
|
@ -1004,6 +1008,11 @@ impl ParsedDeclaration {
|
||||||
return Err(PropertyDeclarationParseError::UnknownProperty)
|
return Err(PropertyDeclarationParseError::UnknownProperty)
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
% if not property.allowed_in_page_rule:
|
||||||
|
if rule_type == CssRuleType::Page {
|
||||||
|
return Err(PropertyDeclarationParseError::NotAllowedInPageRule)
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
|
||||||
${property_pref_check(property)}
|
${property_pref_check(property)}
|
||||||
|
|
||||||
|
@ -1032,6 +1041,11 @@ impl ParsedDeclaration {
|
||||||
return Err(PropertyDeclarationParseError::UnknownProperty)
|
return Err(PropertyDeclarationParseError::UnknownProperty)
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
% if not shorthand.allowed_in_page_rule:
|
||||||
|
if rule_type == CssRuleType::Page {
|
||||||
|
return Err(PropertyDeclarationParseError::NotAllowedInPageRule)
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
|
||||||
${property_pref_check(shorthand)}
|
${property_pref_check(shorthand)}
|
||||||
|
|
||||||
|
@ -1105,6 +1119,8 @@ pub enum PropertyDeclarationParseError {
|
||||||
///
|
///
|
||||||
/// See: https://drafts.csswg.org/css-animations/#keyframes
|
/// See: https://drafts.csswg.org/css-animations/#keyframes
|
||||||
AnimationPropertyInKeyframeBlock,
|
AnimationPropertyInKeyframeBlock,
|
||||||
|
/// The property is not allowed within a page rule.
|
||||||
|
NotAllowedInPageRule,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for PropertyDeclaration {
|
impl fmt::Debug for PropertyDeclaration {
|
||||||
|
|
|
@ -5,4 +5,5 @@
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse",
|
${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse",
|
||||||
spec="https://drafts.csswg.org/css-box/#propdef-margin")}
|
spec="https://drafts.csswg.org/css-box/#propdef-margin",
|
||||||
|
allowed_in_page_rule=True)}
|
||||||
|
|
|
@ -258,9 +258,11 @@ 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)]
|
||||||
|
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum CssRuleType {
|
pub enum CssRuleType {
|
||||||
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
||||||
Style = 1,
|
Style = 1,
|
||||||
|
@ -316,6 +318,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 +352,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 +426,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 +565,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 +809,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 +886,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 +1073,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 +1114,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, CssRuleType::Page);
|
||||||
|
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule(
|
||||||
|
Arc::new(self.shared_lock.wrap(declarations))
|
||||||
|
)))))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1138,7 @@ impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
|
|
||||||
fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser)
|
fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser)
|
||||||
-> Result<CssRule, ()> {
|
-> Result<CssRule, ()> {
|
||||||
let declarations = parse_property_declaration_list(self.context, input);
|
let declarations = parse_property_declaration_list(self.context, input, CssRuleType::Style);
|
||||||
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
||||||
selectors: prelude,
|
selectors: prelude,
|
||||||
block: Arc::new(self.shared_lock.wrap(declarations))
|
block: Arc::new(self.shared_lock.wrap(declarations))
|
||||||
|
|
|
@ -9,6 +9,7 @@ use parser::ParserContext;
|
||||||
use properties::{PropertyId, ParsedDeclaration};
|
use properties::{PropertyId, ParsedDeclaration};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
use stylesheets::CssRuleType;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// An @supports condition
|
/// An @supports condition
|
||||||
|
@ -211,7 +212,7 @@ impl Declaration {
|
||||||
return false
|
return false
|
||||||
};
|
};
|
||||||
let mut input = Parser::new(&self.val);
|
let mut input = Parser::new(&self.val);
|
||||||
let res = ParsedDeclaration::parse(id, cx, &mut input, /* in_keyframe */ false);
|
let res = ParsedDeclaration::parse(id, cx, &mut input, /* in_keyframe */ false, CssRuleType::Style);
|
||||||
let _ = input.try(parse_important);
|
let _ = input.try(parse_important);
|
||||||
res.is_ok() && input.is_exhausted()
|
res.is_ok() && input.is_exhausted()
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServo
|
||||||
use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaListStrong};
|
use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaListStrong};
|
||||||
use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
|
use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
|
||||||
use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
|
use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
|
||||||
|
use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
|
||||||
use style::gecko_bindings::bindings::{RawServoStyleRule, RawServoStyleRuleBorrowed};
|
use style::gecko_bindings::bindings::{RawServoStyleRule, RawServoStyleRuleBorrowed};
|
||||||
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
|
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
|
||||||
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
|
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
|
||||||
|
@ -80,7 +81,7 @@ use style::selector_parser::PseudoElementCascadeType;
|
||||||
use style::sequential;
|
use style::sequential;
|
||||||
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
|
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
|
||||||
use style::string_cache::Atom;
|
use style::string_cache::Atom;
|
||||||
use style::stylesheets::{CssRule, CssRules, ImportRule, MediaRule, NamespaceRule};
|
use style::stylesheets::{CssRule, CssRules, CssRuleType, ImportRule, MediaRule, NamespaceRule, PageRule};
|
||||||
use style::stylesheets::{Origin, Stylesheet, StyleRule};
|
use style::stylesheets::{Origin, Stylesheet, StyleRule};
|
||||||
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
|
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
|
||||||
use style::supports::parse_condition_or_declaration;
|
use style::supports::parse_condition_or_declaration;
|
||||||
|
@ -733,6 +734,12 @@ impl_basic_rule_funcs! { (Namespace, NamespaceRule, RawServoNamespaceRule),
|
||||||
to_css: Servo_NamespaceRule_GetCssText,
|
to_css: Servo_NamespaceRule_GetCssText,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_basic_rule_funcs! { (Page, PageRule, RawServoPageRule),
|
||||||
|
getter: Servo_CssRules_GetPageRuleAt,
|
||||||
|
debug: Servo_PageRule_Debug,
|
||||||
|
to_css: Servo_PageRule_GetCssText,
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed, index: u32)
|
pub extern "C" fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed, index: u32)
|
||||||
-> *mut nsCSSFontFaceRule
|
-> *mut nsCSSFontFaceRule
|
||||||
|
@ -795,6 +802,22 @@ pub extern "C" fn Servo_NamespaceRule_GetURI(rule: RawServoNamespaceRuleBorrowed
|
||||||
read_locked_arc(rule, |rule: &NamespaceRule| rule.url.0.as_ptr())
|
read_locked_arc(rule, |rule: &NamespaceRule| rule.url.0.as_ptr())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn Servo_PageRule_GetStyle(rule: RawServoPageRuleBorrowed) -> RawServoDeclarationBlockStrong {
|
||||||
|
read_locked_arc(rule, |rule: &PageRule| {
|
||||||
|
rule.0.clone().into_strong()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn Servo_PageRule_SetStyle(rule: RawServoPageRuleBorrowed,
|
||||||
|
declarations: RawServoDeclarationBlockBorrowed) {
|
||||||
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
write_locked_arc(rule, |rule: &mut PageRule| {
|
||||||
|
rule.0 = declarations.clone();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
||||||
pseudo_tag: *mut nsIAtom,
|
pseudo_tag: *mut nsIAtom,
|
||||||
|
@ -927,7 +950,7 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const
|
||||||
let reporter = StdoutErrorReporter;
|
let reporter = StdoutErrorReporter;
|
||||||
let context = ParserContext::new(Origin::Author, url_data, &reporter);
|
let context = ParserContext::new(Origin::Author, url_data, &reporter);
|
||||||
|
|
||||||
match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) {
|
match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false, CssRuleType::Style) {
|
||||||
Ok(parsed) => {
|
Ok(parsed) => {
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
|
|
|
@ -10,7 +10,7 @@ use style::parser::ParserContext;
|
||||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId};
|
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId};
|
||||||
use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
||||||
use style::properties::parse_property_declaration_list;
|
use style::properties::parse_property_declaration_list;
|
||||||
use style::stylesheets::Origin;
|
use style::stylesheets::{CssRuleType, Origin};
|
||||||
use style::values::{RGBA, Auto};
|
use style::values::{RGBA, Auto};
|
||||||
use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length, NoCalcLength};
|
use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length, NoCalcLength};
|
||||||
use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
||||||
|
@ -23,7 +23,7 @@ fn parse_declaration_block(css_properties: &str) -> PropertyDeclarationBlock {
|
||||||
let reporter = CSSErrorReporterTest;
|
let reporter = CSSErrorReporterTest;
|
||||||
let context = ParserContext::new(Origin::Author, &url, &reporter);
|
let context = ParserContext::new(Origin::Author, &url, &reporter);
|
||||||
let mut parser = Parser::new(css_properties);
|
let mut parser = Parser::new(css_properties);
|
||||||
parse_property_declaration_list(&context, &mut parser)
|
parse_property_declaration_list(&context, &mut parser, CssRuleType::Style)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue