mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add a pref checking mechanism for alias properties
This commit is contained in:
parent
4d10d39e8f
commit
6893446b71
9 changed files with 161 additions and 44 deletions
|
@ -744,7 +744,8 @@ impl LayoutThread {
|
||||||
Msg::RegisterPaint(name, mut properties, painter) => {
|
Msg::RegisterPaint(name, mut properties, painter) => {
|
||||||
debug!("Registering the painter");
|
debug!("Registering the painter");
|
||||||
let properties = properties.drain(..)
|
let properties = properties.drain(..)
|
||||||
.filter_map(|name| PropertyId::parse(&*name).ok().map(|id| (name.clone(), id)))
|
.filter_map(|name| PropertyId::parse(&*name, None)
|
||||||
|
.ok().map(|id| (name.clone(), id)))
|
||||||
.filter(|&(_, ref id)| id.as_shorthand().is_err())
|
.filter(|&(_, ref id)| id.as_shorthand().is_err())
|
||||||
.collect();
|
.collect();
|
||||||
let registered_painter = RegisteredPainterImpl {
|
let registered_painter = RegisteredPainterImpl {
|
||||||
|
|
|
@ -296,7 +296,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
|
|
||||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
||||||
fn GetPropertyValue(&self, property: DOMString) -> DOMString {
|
fn GetPropertyValue(&self, property: DOMString) -> DOMString {
|
||||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||||
id
|
id
|
||||||
} else {
|
} else {
|
||||||
// Unkwown property
|
// Unkwown property
|
||||||
|
@ -307,7 +307,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
|
|
||||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
||||||
fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
|
fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
|
||||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||||
id
|
id
|
||||||
} else {
|
} else {
|
||||||
// Unkwown property
|
// Unkwown property
|
||||||
|
@ -331,7 +331,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
priority: DOMString)
|
priority: DOMString)
|
||||||
-> ErrorResult {
|
-> ErrorResult {
|
||||||
// Step 3
|
// Step 3
|
||||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||||
id
|
id
|
||||||
} else {
|
} else {
|
||||||
// Unknown property
|
// Unknown property
|
||||||
|
@ -348,7 +348,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2 & 3
|
// Step 2 & 3
|
||||||
let id = match PropertyId::parse(&property) {
|
let id = match PropertyId::parse(&property, None) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(..) => return Ok(()), // Unkwown property
|
Err(..) => return Ok(()), // Unkwown property
|
||||||
};
|
};
|
||||||
|
@ -380,7 +380,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
return Err(Error::NoModificationAllowed);
|
return Err(Error::NoModificationAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||||
id
|
id
|
||||||
} else {
|
} else {
|
||||||
// Unkwown property, cannot be there to remove.
|
// Unkwown property, cannot be there to remove.
|
||||||
|
|
|
@ -265,6 +265,18 @@ class Shorthand(object):
|
||||||
transitionable = property(get_transitionable)
|
transitionable = property(get_transitionable)
|
||||||
|
|
||||||
|
|
||||||
|
class Alias(object):
|
||||||
|
def __init__(self, name, original):
|
||||||
|
self.name = name
|
||||||
|
self.ident = to_rust_ident(name)
|
||||||
|
self.camel_case = to_camel_case(self.ident)
|
||||||
|
self.gecko_pref_ident = to_rust_ident(name)
|
||||||
|
self.internal = original.internal
|
||||||
|
self.experimental = original.experimental
|
||||||
|
self.allowed_in_page_rule = original.allowed_in_page_rule
|
||||||
|
self.allowed_in_keyframe_block = original.allowed_in_keyframe_block
|
||||||
|
|
||||||
|
|
||||||
class Method(object):
|
class Method(object):
|
||||||
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):
|
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -311,7 +323,9 @@ class PropertiesData(object):
|
||||||
self.longhands = []
|
self.longhands = []
|
||||||
self.longhands_by_name = {}
|
self.longhands_by_name = {}
|
||||||
self.derived_longhands = {}
|
self.derived_longhands = {}
|
||||||
|
self.longhand_aliases = []
|
||||||
self.shorthands = []
|
self.shorthands = []
|
||||||
|
self.shorthand_aliases = []
|
||||||
|
|
||||||
def new_style_struct(self, *args, **kwargs):
|
def new_style_struct(self, *args, **kwargs):
|
||||||
style_struct = StyleStruct(*args, **kwargs)
|
style_struct = StyleStruct(*args, **kwargs)
|
||||||
|
@ -335,6 +349,7 @@ class PropertiesData(object):
|
||||||
|
|
||||||
longhand = Longhand(self.current_style_struct, name, **kwargs)
|
longhand = Longhand(self.current_style_struct, name, **kwargs)
|
||||||
self.add_prefixed_aliases(longhand)
|
self.add_prefixed_aliases(longhand)
|
||||||
|
self.longhand_aliases += list(map(lambda x: Alias(x, longhand), longhand.alias))
|
||||||
self.current_style_struct.longhands.append(longhand)
|
self.current_style_struct.longhands.append(longhand)
|
||||||
self.longhands.append(longhand)
|
self.longhands.append(longhand)
|
||||||
self.longhands_by_name[name] = longhand
|
self.longhands_by_name[name] = longhand
|
||||||
|
@ -352,8 +367,12 @@ class PropertiesData(object):
|
||||||
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
|
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
|
||||||
shorthand = Shorthand(name, sub_properties, *args, **kwargs)
|
shorthand = Shorthand(name, sub_properties, *args, **kwargs)
|
||||||
self.add_prefixed_aliases(shorthand)
|
self.add_prefixed_aliases(shorthand)
|
||||||
|
self.shorthand_aliases += list(map(lambda x: Alias(x, shorthand), shorthand.alias))
|
||||||
self.shorthands.append(shorthand)
|
self.shorthands.append(shorthand)
|
||||||
return shorthand
|
return shorthand
|
||||||
|
|
||||||
def shorthands_except_all(self):
|
def shorthands_except_all(self):
|
||||||
return [s for s in self.shorthands if s.name != "all"]
|
return [s for s in self.shorthands if s.name != "all"]
|
||||||
|
|
||||||
|
def all_aliases(self):
|
||||||
|
return self.longhand_aliases + self.shorthand_aliases
|
||||||
|
|
|
@ -947,7 +947,8 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
||||||
-> Result<Importance, ParseError<'i>> {
|
-> Result<Importance, ParseError<'i>> {
|
||||||
let id = match PropertyId::parse(&name) {
|
let prop_context = PropertyParserContext::new(self.context);
|
||||||
|
let id = match PropertyId::parse(&name, Some(&prop_context)) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
return Err(if is_non_mozilla_vendor_identifier(&name) {
|
return Err(if is_non_mozilla_vendor_identifier(&name) {
|
||||||
|
|
|
@ -3505,7 +3505,7 @@ fn static_assert() {
|
||||||
Gecko_AppendWillChange(&mut self.gecko, feature.0.as_ptr());
|
Gecko_AppendWillChange(&mut self.gecko, feature.0.as_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(prop_id) = PropertyId::parse(&feature.0.to_string()) {
|
if let Ok(prop_id) = PropertyId::parse(&feature.0.to_string(), None) {
|
||||||
match prop_id.as_shorthand() {
|
match prop_id.as_shorthand() {
|
||||||
Ok(shorthand) => {
|
Ok(shorthand) => {
|
||||||
for longhand in shorthand.longhands() {
|
for longhand in shorthand.longhands() {
|
||||||
|
|
|
@ -246,10 +246,16 @@ impl From<ShorthandId> for NonCustomPropertyId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of longhand properties
|
impl From<AliasId> for NonCustomPropertyId {
|
||||||
|
fn from(id: AliasId) -> Self {
|
||||||
|
NonCustomPropertyId(id as usize + ${len(data.longhands) + len(data.shorthands)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A set of all properties
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct NonCustomPropertyIdSet {
|
pub struct NonCustomPropertyIdSet {
|
||||||
storage: [u32; (${len(data.longhands) + len(data.shorthands)} - 1 + 32) / 32]
|
storage: [u32; (${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())} - 1 + 32) / 32]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NonCustomPropertyIdSet {
|
impl NonCustomPropertyIdSet {
|
||||||
|
@ -264,7 +270,7 @@ impl NonCustomPropertyIdSet {
|
||||||
<%def name="static_non_custom_property_id_set(name, is_member)">
|
<%def name="static_non_custom_property_id_set(name, is_member)">
|
||||||
static ${name}: NonCustomPropertyIdSet = NonCustomPropertyIdSet {
|
static ${name}: NonCustomPropertyIdSet = NonCustomPropertyIdSet {
|
||||||
<%
|
<%
|
||||||
storage = [0] * ((len(data.longhands) + len(data.shorthands) - 1 + 32) / 32)
|
storage = [0] * ((len(data.longhands) + len(data.shorthands) + len(data.all_aliases()) - 1 + 32) / 32)
|
||||||
for i, property in enumerate(data.longhands + data.shorthands):
|
for i, property in enumerate(data.longhands + data.shorthands):
|
||||||
if is_member(property):
|
if is_member(property):
|
||||||
storage[i / 32] |= 1 << (i % 32)
|
storage[i / 32] |= 1 << (i % 32)
|
||||||
|
@ -1003,33 +1009,75 @@ impl PropertyId {
|
||||||
/// Returns a given property from the string `s`.
|
/// Returns a given property from the string `s`.
|
||||||
///
|
///
|
||||||
/// Returns Err(()) for unknown non-custom properties
|
/// Returns Err(()) for unknown non-custom properties
|
||||||
pub fn parse(property_name: &str) -> Result<Self, ()> {
|
/// If caller wants to provide a different context, it can be provided with
|
||||||
|
/// Some(context), if None is given, default setting for PropertyParserContext
|
||||||
|
/// will be used. It is `Origin::Author` for stylesheet_origin and
|
||||||
|
/// `CssRuleType::Style` for rule_type.
|
||||||
|
pub fn parse(property_name: &str, context: Option< &PropertyParserContext>) -> Result<Self, ()> {
|
||||||
if let Ok(name) = ::custom_properties::parse_name(property_name) {
|
if let Ok(name) = ::custom_properties::parse_name(property_name) {
|
||||||
return Ok(PropertyId::Custom(::custom_properties::Name::from(name)))
|
return Ok(PropertyId::Custom(::custom_properties::Name::from(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this enum and use PropertyId
|
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this enum and use PropertyId
|
||||||
// when stable Rust allows destructors in statics.
|
// when stable Rust allows destructors in statics.
|
||||||
|
// ShorthandAlias is not used in servo build. That's why we need to allow dead_code.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum StaticId {
|
pub enum StaticId {
|
||||||
Longhand(LonghandId),
|
Longhand(LonghandId),
|
||||||
Shorthand(ShorthandId),
|
Shorthand(ShorthandId),
|
||||||
|
LonghandAlias(LonghandId, AliasId),
|
||||||
|
ShorthandAlias(ShorthandId, AliasId),
|
||||||
}
|
}
|
||||||
ascii_case_insensitive_phf_map! {
|
ascii_case_insensitive_phf_map! {
|
||||||
static_id -> StaticId = {
|
static_id -> StaticId = {
|
||||||
% for (kind, properties) in [("Longhand", data.longhands), ("Shorthand", data.shorthands)]:
|
% for (kind, properties) in [("Longhand", data.longhands), ("Shorthand", data.shorthands)]:
|
||||||
% for property in properties:
|
% for property in properties:
|
||||||
% for name in [property.name] + property.alias:
|
"${property.name}" => StaticId::${kind}(${kind}Id::${property.camel_case}),
|
||||||
"${name}" => StaticId::${kind}(${kind}Id::${property.camel_case}),
|
% for name in property.alias:
|
||||||
|
"${name}" => {
|
||||||
|
StaticId::${kind}Alias(${kind}Id::${property.camel_case},
|
||||||
|
AliasId::${to_camel_case(name)})
|
||||||
|
},
|
||||||
% endfor
|
% endfor
|
||||||
% endfor
|
% endfor
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match static_id(property_name) {
|
|
||||||
Some(&StaticId::Longhand(id)) => Ok(PropertyId::Longhand(id)),
|
let default;
|
||||||
Some(&StaticId::Shorthand(id)) => Ok(PropertyId::Shorthand(id)),
|
let context = match context {
|
||||||
None => Err(()),
|
Some(context) => context,
|
||||||
}
|
None => {
|
||||||
|
default = PropertyParserContext {
|
||||||
|
stylesheet_origin: Origin::Author,
|
||||||
|
rule_type: CssRuleType::Style,
|
||||||
|
};
|
||||||
|
&default
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let rule_type = context.rule_type;
|
||||||
|
debug_assert!(matches!(rule_type, CssRuleType::Keyframe |
|
||||||
|
CssRuleType::Page |
|
||||||
|
CssRuleType::Style),
|
||||||
|
"Declarations are only expected inside a keyframe, page, or style rule.");
|
||||||
|
|
||||||
|
let (id, alias) = match static_id(property_name) {
|
||||||
|
Some(&StaticId::Longhand(id)) => {
|
||||||
|
(PropertyId::Longhand(id), None)
|
||||||
|
},
|
||||||
|
Some(&StaticId::Shorthand(id)) => {
|
||||||
|
(PropertyId::Shorthand(id), None)
|
||||||
|
},
|
||||||
|
Some(&StaticId::LonghandAlias(id, alias)) => {
|
||||||
|
(PropertyId::Longhand(id), Some(alias))
|
||||||
|
},
|
||||||
|
Some(&StaticId::ShorthandAlias(id, alias)) => {
|
||||||
|
(PropertyId::Shorthand(id), Some(alias))
|
||||||
|
},
|
||||||
|
None => return Err(()),
|
||||||
|
};
|
||||||
|
id.check_allowed_in(alias, context).map_err(|_| ())?;
|
||||||
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a property id from Gecko's nsCSSPropertyID.
|
/// Returns a property id from Gecko's nsCSSPropertyID.
|
||||||
|
@ -1111,22 +1159,26 @@ impl PropertyId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_allowed_in(&self, rule_type: CssRuleType, stylesheet_origin: Origin)
|
fn check_allowed_in(&self, alias: Option<AliasId>, context: &PropertyParserContext)
|
||||||
-> Result<(), PropertyDeclarationParseError<'static>> {
|
-> Result<(), PropertyDeclarationParseError<'static>> {
|
||||||
let id: NonCustomPropertyId;
|
let id: NonCustomPropertyId;
|
||||||
match *self {
|
if let Some(alias_id) = alias {
|
||||||
// Custom properties are allowed everywhere
|
id = alias_id.into();
|
||||||
PropertyId::Custom(_) => return Ok(()),
|
} else {
|
||||||
|
match *self {
|
||||||
|
// Custom properties are allowed everywhere
|
||||||
|
PropertyId::Custom(_) => return Ok(()),
|
||||||
|
|
||||||
PropertyId::Shorthand(shorthand_id) => id = shorthand_id.into(),
|
PropertyId::Shorthand(shorthand_id) => id = shorthand_id.into(),
|
||||||
PropertyId::Longhand(longhand_id) => id = longhand_id.into(),
|
PropertyId::Longhand(longhand_id) => id = longhand_id.into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<% id_set = static_non_custom_property_id_set %>
|
<% id_set = static_non_custom_property_id_set %>
|
||||||
|
|
||||||
${id_set("DISALLOWED_IN_KEYFRAME_BLOCK", lambda p: not p.allowed_in_keyframe_block)}
|
${id_set("DISALLOWED_IN_KEYFRAME_BLOCK", lambda p: not p.allowed_in_keyframe_block)}
|
||||||
${id_set("DISALLOWED_IN_PAGE_RULE", lambda p: not p.allowed_in_page_rule)}
|
${id_set("DISALLOWED_IN_PAGE_RULE", lambda p: not p.allowed_in_page_rule)}
|
||||||
match rule_type {
|
match context.rule_type {
|
||||||
CssRuleType::Keyframe if DISALLOWED_IN_KEYFRAME_BLOCK.contains(id) => {
|
CssRuleType::Keyframe if DISALLOWED_IN_KEYFRAME_BLOCK.contains(id) => {
|
||||||
return Err(PropertyDeclarationParseError::AnimationPropertyInKeyframeBlock)
|
return Err(PropertyDeclarationParseError::AnimationPropertyInKeyframeBlock)
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1188,6 @@ impl PropertyId {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// For properties that are experimental but not internal, the pref will
|
// For properties that are experimental but not internal, the pref will
|
||||||
// control its availability in all sheets. For properties that are
|
// control its availability in all sheets. For properties that are
|
||||||
// both experimental and internal, the pref only controls its
|
// both experimental and internal, the pref only controls its
|
||||||
|
@ -1151,7 +1202,7 @@ impl PropertyId {
|
||||||
static EXPERIMENTAL: NonCustomPropertyIdSet = NonCustomPropertyIdSet {
|
static EXPERIMENTAL: NonCustomPropertyIdSet = NonCustomPropertyIdSet {
|
||||||
<%
|
<%
|
||||||
grouped = []
|
grouped = []
|
||||||
properties = data.longhands + data.shorthands
|
properties = data.longhands + data.shorthands + data.all_aliases()
|
||||||
while properties:
|
while properties:
|
||||||
grouped.append(properties[:32])
|
grouped.append(properties[:32])
|
||||||
properties = properties[32:]
|
properties = properties[32:]
|
||||||
|
@ -1185,14 +1236,16 @@ impl PropertyId {
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
use gecko_bindings::structs;
|
let id = match alias {
|
||||||
let id = self.to_nscsspropertyid().unwrap();
|
Some(alias_id) => alias_id.to_nscsspropertyid().unwrap(),
|
||||||
|
None => self.to_nscsspropertyid().unwrap(),
|
||||||
|
};
|
||||||
unsafe { structs::nsCSSProps_gPropertyEnabled[id as usize] }
|
unsafe { structs::nsCSSProps_gPropertyEnabled[id as usize] }
|
||||||
% endif
|
% endif
|
||||||
};
|
};
|
||||||
|
|
||||||
if INTERNAL.contains(id) {
|
if INTERNAL.contains(id) {
|
||||||
if stylesheet_origin != Origin::UserAgent {
|
if context.stylesheet_origin != Origin::UserAgent {
|
||||||
if EXPERIMENTAL.contains(id) {
|
if EXPERIMENTAL.contains(id) {
|
||||||
if !passes_pref_check() {
|
if !passes_pref_check() {
|
||||||
return Err(PropertyDeclarationParseError::ExperimentalProperty);
|
return Err(PropertyDeclarationParseError::ExperimentalProperty);
|
||||||
|
@ -1211,6 +1264,25 @@ impl PropertyId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parsing Context for PropertyId.
|
||||||
|
pub struct PropertyParserContext {
|
||||||
|
/// The Origin of the stylesheet, whether it's a user,
|
||||||
|
/// author or user-agent stylesheet.
|
||||||
|
pub stylesheet_origin: Origin,
|
||||||
|
/// The current rule type, if any.
|
||||||
|
pub rule_type: CssRuleType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PropertyParserContext {
|
||||||
|
/// Creates a PropertyParserContext with given stylesheet origin and rule type.
|
||||||
|
pub fn new(context: &ParserContext) -> Self {
|
||||||
|
Self {
|
||||||
|
stylesheet_origin: context.stylesheet_origin,
|
||||||
|
rule_type: context.rule_type(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Servo's representation for a property declaration.
|
/// Servo's representation for a property declaration.
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone)]
|
||||||
pub enum PropertyDeclaration {
|
pub enum PropertyDeclaration {
|
||||||
|
@ -1478,12 +1550,6 @@ impl PropertyDeclaration {
|
||||||
id: PropertyId, context: &ParserContext, input: &mut Parser<'i, 't>)
|
id: PropertyId, context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<(), PropertyDeclarationParseError<'i>> {
|
-> Result<(), PropertyDeclarationParseError<'i>> {
|
||||||
assert!(declarations.is_empty());
|
assert!(declarations.is_empty());
|
||||||
let rule_type = context.rule_type();
|
|
||||||
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.");
|
|
||||||
id.check_allowed_in(rule_type, context.stylesheet_origin)?;
|
|
||||||
match id {
|
match id {
|
||||||
PropertyId::Custom(name) => {
|
PropertyId::Custom(name) => {
|
||||||
let value = match input.try(|i| CSSWideKeyword::parse(i)) {
|
let value = match input.try(|i| CSSWideKeyword::parse(i)) {
|
||||||
|
@ -3428,6 +3494,33 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc<ComputedValues>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An identifier for a given alias property.
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub enum AliasId {
|
||||||
|
% for i, property in enumerate(data.all_aliases()):
|
||||||
|
/// ${property.name}
|
||||||
|
${property.camel_case} = ${i},
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AliasId {
|
||||||
|
/// Returns an nsCSSPropertyID.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
|
||||||
|
use gecko_bindings::structs::*;
|
||||||
|
|
||||||
|
match *self {
|
||||||
|
% for property in data.all_aliases():
|
||||||
|
AliasId::${property.camel_case} => {
|
||||||
|
Ok(${helpers.alias_to_nscsspropertyid(property.ident)})
|
||||||
|
},
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! css_properties_accessors {
|
macro_rules! css_properties_accessors {
|
||||||
($macro_name: ident) => {
|
($macro_name: ident) => {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, Parse
|
||||||
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
|
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
|
||||||
use error_reporting::{NullReporter, ContextualParseError};
|
use error_reporting::{NullReporter, ContextualParseError};
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, PropertyParserContext};
|
||||||
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
|
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
|
||||||
use properties::LonghandIdSet;
|
use properties::LonghandIdSet;
|
||||||
use properties::animated_properties::AnimatableLonghand;
|
use properties::animated_properties::AnimatableLonghand;
|
||||||
|
@ -532,7 +532,9 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
|
||||||
|
|
||||||
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
||||||
-> Result<(), ParseError<'i>> {
|
-> Result<(), ParseError<'i>> {
|
||||||
let id = PropertyId::parse(&name)
|
let property_context = PropertyParserContext::new(self.context);
|
||||||
|
|
||||||
|
let id = PropertyId::parse(&name, Some(&property_context))
|
||||||
.map_err(|()| PropertyDeclarationParseError::UnknownProperty(name))?;
|
.map_err(|()| PropertyDeclarationParseError::UnknownProperty(name))?;
|
||||||
match PropertyDeclaration::parse_into(self.declarations, id, self.context, input) {
|
match PropertyDeclaration::parse_into(self.declarations, id, self.context, input) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use cssparser::{BasicParseError, ParseError as CssParseError, ParserInput};
|
use cssparser::{BasicParseError, ParseError as CssParseError, ParserInput};
|
||||||
use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
|
use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use properties::{PropertyId, PropertyDeclaration, SourcePropertyDeclaration};
|
use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseError;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||||
|
@ -247,10 +247,11 @@ impl Declaration {
|
||||||
input.parse_entirely(|input| {
|
input.parse_entirely(|input| {
|
||||||
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
||||||
input.expect_colon().unwrap();
|
input.expect_colon().unwrap();
|
||||||
let id = PropertyId::parse(&prop)
|
|
||||||
.map_err(|_| StyleParseError::UnspecifiedError)?;
|
|
||||||
let mut declarations = SourcePropertyDeclaration::new();
|
|
||||||
let context = ParserContext::new_with_rule_type(cx, Some(CssRuleType::Style));
|
let context = ParserContext::new_with_rule_type(cx, Some(CssRuleType::Style));
|
||||||
|
let property_context = PropertyParserContext::new(&context);
|
||||||
|
let id = PropertyId::parse(&prop, Some(&property_context))
|
||||||
|
.map_err(|_| StyleParseError::UnspecifiedError)?;
|
||||||
|
let mut declarations = SourcePropertyDeclaration::new();
|
||||||
input.parse_until_before(Delimiter::Bang, |input| {
|
input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
|
PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
|
||||||
.map_err(|e| StyleParseError::PropertyDeclaration(e).into())
|
.map_err(|e| StyleParseError::PropertyDeclaration(e).into())
|
||||||
|
|
|
@ -2190,7 +2190,7 @@ pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDe
|
||||||
macro_rules! get_property_id_from_property {
|
macro_rules! get_property_id_from_property {
|
||||||
($property: ident, $ret: expr) => {{
|
($property: ident, $ret: expr) => {{
|
||||||
let property = unsafe { $property.as_ref().unwrap().as_str_unchecked() };
|
let property = unsafe { $property.as_ref().unwrap().as_str_unchecked() };
|
||||||
match PropertyId::parse(property.into()) {
|
match PropertyId::parse(property.into(), None) {
|
||||||
Ok(property_id) => property_id,
|
Ok(property_id) => property_id,
|
||||||
Err(_) => { return $ret; }
|
Err(_) => { return $ret; }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue