mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
style: Move property allowance tests to PropertyId::parse_into.
It's not only more consistent (since we have a proper ParserContext there), but also fixes a bunch of bugs where Gecko accidentally exposes and allows setting internal state because of conversions from nsCSSPropertyID to PropertyId. This adds the extra complexity of caring about aliases for longer, but that's probably not a big deal in practice, since we also have PropertyDeclarationId. MozReview-Commit-ID: C2Js8PfloxQ
This commit is contained in:
parent
5905f8d3ea
commit
8de554f334
9 changed files with 137 additions and 135 deletions
|
@ -689,9 +689,11 @@ pub fn process_resolved_style_request<'a, N>(context: &LayoutContext,
|
|||
let styles = resolve_style(&mut context, element, RuleInclusion::All, false, pseudo.as_ref());
|
||||
let style = styles.primary();
|
||||
let longhand_id = match *property {
|
||||
PropertyId::LonghandAlias(id, _) |
|
||||
PropertyId::Longhand(id) => id,
|
||||
// Firefox returns blank strings for the computed value of shorthands,
|
||||
// so this should be web-compatible.
|
||||
PropertyId::ShorthandAlias(..) |
|
||||
PropertyId::Shorthand(_) => return String::new(),
|
||||
PropertyId::Custom(ref name) => {
|
||||
return style.computed_value_to_string(PropertyDeclarationId::Custom(name))
|
||||
|
@ -737,12 +739,12 @@ where
|
|||
|
||||
let style = &*layout_el.resolved_style();
|
||||
let longhand_id = match *property {
|
||||
PropertyId::LonghandAlias(id, _) |
|
||||
PropertyId::Longhand(id) => id,
|
||||
|
||||
// Firefox returns blank strings for the computed value of shorthands,
|
||||
// so this should be web-compatible.
|
||||
PropertyId::ShorthandAlias(..) |
|
||||
PropertyId::Shorthand(_) => return String::new(),
|
||||
|
||||
PropertyId::Custom(ref name) => {
|
||||
return style.computed_value_to_string(PropertyDeclarationId::Custom(name))
|
||||
}
|
||||
|
|
|
@ -742,7 +742,7 @@ impl LayoutThread {
|
|||
Msg::RegisterPaint(name, mut properties, painter) => {
|
||||
debug!("Registering the painter");
|
||||
let properties = properties.drain(..)
|
||||
.filter_map(|name| PropertyId::parse(&*name, None)
|
||||
.filter_map(|name| PropertyId::parse(&*name)
|
||||
.ok().map(|id| (name.clone(), id)))
|
||||
.filter(|&(_, ref id)| id.as_shorthand().is_err())
|
||||
.collect();
|
||||
|
|
|
@ -299,7 +299,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
|
||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
||||
fn GetPropertyValue(&self, property: DOMString) -> DOMString {
|
||||
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property
|
||||
|
@ -310,7 +310,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
|
||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
||||
fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
|
||||
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property
|
||||
|
@ -334,7 +334,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
priority: DOMString)
|
||||
-> ErrorResult {
|
||||
// Step 3
|
||||
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
||||
id
|
||||
} else {
|
||||
// Unknown property
|
||||
|
@ -351,7 +351,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
}
|
||||
|
||||
// Step 2 & 3
|
||||
let id = match PropertyId::parse(&property, None) {
|
||||
let id = match PropertyId::parse(&property) {
|
||||
Ok(id) => id,
|
||||
Err(..) => return Ok(()), // Unkwown property
|
||||
};
|
||||
|
@ -383,7 +383,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
return Err(Error::NoModificationAllowed);
|
||||
}
|
||||
|
||||
let id = if let Ok(id) = PropertyId::parse(&property, None) {
|
||||
let id = if let Ok(id) = PropertyId::parse(&property) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property, cannot be there to remove.
|
||||
|
|
|
@ -560,7 +560,8 @@ impl PropertyDeclarationBlock {
|
|||
///
|
||||
/// Returns whether any declaration was actually removed.
|
||||
pub fn remove_property(&mut self, property: &PropertyId) -> bool {
|
||||
if let PropertyId::Longhand(id) = *property {
|
||||
let longhand_id = property.longhand_id();
|
||||
if let Some(id) = longhand_id {
|
||||
if !self.longhands.contains(id) {
|
||||
return false
|
||||
}
|
||||
|
@ -584,7 +585,7 @@ impl PropertyDeclarationBlock {
|
|||
!remove
|
||||
});
|
||||
|
||||
if let PropertyId::Longhand(_) = *property {
|
||||
if longhand_id.is_some() {
|
||||
debug_assert!(removed_at_least_one);
|
||||
}
|
||||
removed_at_least_one
|
||||
|
@ -681,7 +682,7 @@ impl PropertyDeclarationBlock {
|
|||
/// property.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn has_css_wide_keyword(&self, property: &PropertyId) -> bool {
|
||||
if let PropertyId::Longhand(id) = *property {
|
||||
if let Some(id) = property.longhand_id() {
|
||||
if !self.longhands.contains(id) {
|
||||
return false
|
||||
}
|
||||
|
@ -1092,12 +1093,14 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
|||
type Declaration = Importance;
|
||||
type Error = StyleParseErrorKind<'i>;
|
||||
|
||||
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
||||
-> Result<Importance, ParseError<'i>> {
|
||||
let prop_context = PropertyParserContext::new(self.context);
|
||||
let id = match PropertyId::parse(&name, Some(&prop_context)) {
|
||||
fn parse_value<'t>(
|
||||
&mut self,
|
||||
name: CowRcStr<'i>,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Importance, ParseError<'i>> {
|
||||
let id = match PropertyId::parse(&name) {
|
||||
Ok(id) => id,
|
||||
Err(()) => {
|
||||
Err(..) => {
|
||||
return Err(input.new_custom_error(if is_non_mozilla_vendor_identifier(&name) {
|
||||
StyleParseErrorKind::UnknownVendorProperty
|
||||
} else {
|
||||
|
@ -1107,7 +1110,6 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
|||
};
|
||||
input.parse_until_before(Delimiter::Bang, |input| {
|
||||
PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input)
|
||||
.map_err(|e| e.into())
|
||||
})?;
|
||||
let importance = match input.try(parse_important) {
|
||||
Ok(()) => Importance::Important,
|
||||
|
|
|
@ -3560,7 +3560,7 @@ fn static_assert() {
|
|||
Gecko_AppendWillChange(&mut self.gecko, feature.0.as_ptr());
|
||||
}
|
||||
|
||||
if let Ok(prop_id) = PropertyId::parse(&feature.0.to_string(), None) {
|
||||
if let Ok(prop_id) = PropertyId::parse(&feature.0.to_string()) {
|
||||
match prop_id.as_shorthand() {
|
||||
Ok(shorthand) => {
|
||||
for longhand in shorthand.longhands() {
|
||||
|
|
|
@ -604,7 +604,8 @@ impl LonghandId {
|
|||
/// Returns a longhand id from Gecko's nsCSSPropertyID.
|
||||
pub fn from_nscsspropertyid(id: nsCSSPropertyID) -> Result<Self, ()> {
|
||||
match PropertyId::from_nscsspropertyid(id) {
|
||||
Ok(PropertyId::Longhand(id)) => Ok(id),
|
||||
Ok(PropertyId::Longhand(id)) |
|
||||
Ok(PropertyId::LonghandAlias(id, _)) => Ok(id),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
@ -1052,8 +1053,10 @@ impl<'a> PropertyDeclarationId<'a> {
|
|||
match *self {
|
||||
PropertyDeclarationId::Longhand(id) => {
|
||||
match *other {
|
||||
PropertyId::Longhand(other_id) => id == other_id,
|
||||
PropertyId::Shorthand(shorthand) => self.is_longhand_of(shorthand),
|
||||
PropertyId::Longhand(other_id) |
|
||||
PropertyId::LonghandAlias(other_id, _) => id == other_id,
|
||||
PropertyId::Shorthand(shorthand) |
|
||||
PropertyId::ShorthandAlias(shorthand, _) => self.is_longhand_of(shorthand),
|
||||
PropertyId::Custom(_) => false,
|
||||
}
|
||||
}
|
||||
|
@ -1094,6 +1097,10 @@ pub enum PropertyId {
|
|||
Longhand(LonghandId),
|
||||
/// A shorthand property.
|
||||
Shorthand(ShorthandId),
|
||||
/// An alias for a longhand property.
|
||||
LonghandAlias(LonghandId, AliasId),
|
||||
/// An alias for a shorthand property.
|
||||
ShorthandAlias(ShorthandId, AliasId),
|
||||
/// A custom property.
|
||||
Custom(::custom_properties::Name),
|
||||
}
|
||||
|
@ -1111,6 +1118,8 @@ impl ToCss for PropertyId {
|
|||
match *self {
|
||||
PropertyId::Longhand(id) => dest.write_str(id.name()),
|
||||
PropertyId::Shorthand(id) => dest.write_str(id.name()),
|
||||
PropertyId::LonghandAlias(id, _) => dest.write_str(id.name()),
|
||||
PropertyId::ShorthandAlias(id, _) => dest.write_str(id.name()),
|
||||
PropertyId::Custom(_) => {
|
||||
serialize_identifier(&self.name(), dest)
|
||||
}
|
||||
|
@ -1119,17 +1128,26 @@ impl ToCss for PropertyId {
|
|||
}
|
||||
|
||||
impl PropertyId {
|
||||
/// Return the longhand id that this property id represents.
|
||||
#[inline]
|
||||
pub fn longhand_id(&self) -> Option<LonghandId> {
|
||||
Some(match *self {
|
||||
PropertyId::Longhand(id) => id,
|
||||
PropertyId::LonghandAlias(id, _) => id,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a given property from the string `s`.
|
||||
///
|
||||
/// Returns Err(()) for unknown non-custom properties
|
||||
/// 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, ()> {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this enum and use PropertyId
|
||||
// when stable Rust allows destructors in statics.
|
||||
// ShorthandAlias is not used in servo build. That's why we need to allow dead_code.
|
||||
/// Returns Err(()) for unknown non-custom properties.
|
||||
pub fn parse(property_name: &str) -> Result<Self, ()> {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this
|
||||
// enum and use PropertyId when stable Rust allows destructors in
|
||||
// statics.
|
||||
//
|
||||
// ShorthandAlias is not used in the Servo build.
|
||||
// That's why we need to allow dead_code.
|
||||
#[allow(dead_code)]
|
||||
pub enum StaticId {
|
||||
Longhand(LonghandId),
|
||||
|
@ -1153,42 +1171,25 @@ impl PropertyId {
|
|||
}
|
||||
}
|
||||
|
||||
let default;
|
||||
let context = match context {
|
||||
Some(context) => context,
|
||||
None => {
|
||||
default = PropertyParserContext {
|
||||
chrome_rules_enabled: false,
|
||||
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) {
|
||||
Ok(match static_id(property_name) {
|
||||
Some(&StaticId::Longhand(id)) => {
|
||||
(PropertyId::Longhand(id), None)
|
||||
PropertyId::Longhand(id)
|
||||
},
|
||||
Some(&StaticId::Shorthand(id)) => {
|
||||
(PropertyId::Shorthand(id), None)
|
||||
PropertyId::Shorthand(id)
|
||||
},
|
||||
Some(&StaticId::LonghandAlias(id, alias)) => {
|
||||
(PropertyId::Longhand(id), Some(alias))
|
||||
PropertyId::LonghandAlias(id, alias)
|
||||
},
|
||||
Some(&StaticId::ShorthandAlias(id, alias)) => {
|
||||
(PropertyId::Shorthand(id), Some(alias))
|
||||
PropertyId::ShorthandAlias(id, alias)
|
||||
},
|
||||
None => return ::custom_properties::parse_name(property_name)
|
||||
.map(|name| PropertyId::Custom(::custom_properties::Name::from(name))),
|
||||
};
|
||||
id.check_allowed_in(alias, context)?;
|
||||
Ok(id)
|
||||
None => {
|
||||
return ::custom_properties::parse_name(property_name).map(|name| {
|
||||
PropertyId::Custom(::custom_properties::Name::from(name))
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a property id from Gecko's nsCSSPropertyID.
|
||||
|
@ -1203,7 +1204,10 @@ impl PropertyId {
|
|||
}
|
||||
% for alias in property.alias:
|
||||
${helpers.alias_to_nscsspropertyid(alias)} => {
|
||||
Ok(PropertyId::Longhand(LonghandId::${property.camel_case}))
|
||||
Ok(PropertyId::LonghandAlias(
|
||||
LonghandId::${property.camel_case},
|
||||
AliasId::${to_camel_case(alias)}
|
||||
))
|
||||
}
|
||||
% endfor
|
||||
% endfor
|
||||
|
@ -1213,7 +1217,10 @@ impl PropertyId {
|
|||
}
|
||||
% for alias in property.alias:
|
||||
${helpers.alias_to_nscsspropertyid(alias)} => {
|
||||
Ok(PropertyId::Shorthand(ShorthandId::${property.camel_case}))
|
||||
Ok(PropertyId::ShorthandAlias(
|
||||
ShorthandId::${property.camel_case},
|
||||
AliasId::${to_camel_case(alias)}
|
||||
))
|
||||
}
|
||||
% endfor
|
||||
% endfor
|
||||
|
@ -1228,6 +1235,8 @@ impl PropertyId {
|
|||
match *self {
|
||||
PropertyId::Longhand(id) => Ok(id.to_nscsspropertyid()),
|
||||
PropertyId::Shorthand(id) => Ok(id.to_nscsspropertyid()),
|
||||
PropertyId::LonghandAlias(_, alias) => Ok(alias.to_nscsspropertyid()),
|
||||
PropertyId::ShorthandAlias(_, alias) => Ok(alias.to_nscsspropertyid()),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
@ -1236,7 +1245,9 @@ impl PropertyId {
|
|||
/// `PropertyDeclarationId`.
|
||||
pub fn as_shorthand(&self) -> Result<ShorthandId, PropertyDeclarationId> {
|
||||
match *self {
|
||||
PropertyId::ShorthandAlias(id, _) |
|
||||
PropertyId::Shorthand(id) => Ok(id),
|
||||
PropertyId::LonghandAlias(id, _) |
|
||||
PropertyId::Longhand(id) => Err(PropertyDeclarationId::Longhand(id)),
|
||||
PropertyId::Custom(ref name) => Err(PropertyDeclarationId::Custom(name)),
|
||||
}
|
||||
|
@ -1245,7 +1256,9 @@ impl PropertyId {
|
|||
/// Returns the name of the property without CSS escaping.
|
||||
pub fn name(&self) -> Cow<'static, str> {
|
||||
match *self {
|
||||
PropertyId::ShorthandAlias(id, _) |
|
||||
PropertyId::Shorthand(id) => id.name().into(),
|
||||
PropertyId::LonghandAlias(id, _) |
|
||||
PropertyId::Longhand(id) => id.name().into(),
|
||||
PropertyId::Custom(ref name) => {
|
||||
use std::fmt::Write;
|
||||
|
@ -1256,34 +1269,34 @@ impl PropertyId {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_allowed_in(
|
||||
&self,
|
||||
alias: Option<AliasId>,
|
||||
context: &PropertyParserContext,
|
||||
) -> Result<(), ()> {
|
||||
let id: NonCustomPropertyId;
|
||||
if let Some(alias_id) = alias {
|
||||
id = alias_id.into();
|
||||
} else {
|
||||
match *self {
|
||||
// Custom properties are allowed everywhere
|
||||
PropertyId::Custom(_) => return Ok(()),
|
||||
fn allowed_in(&self, context: &ParserContext) -> bool {
|
||||
let id: NonCustomPropertyId = match *self {
|
||||
// Custom properties are allowed everywhere
|
||||
PropertyId::Custom(_) => return true,
|
||||
PropertyId::Shorthand(shorthand_id) => shorthand_id.into(),
|
||||
PropertyId::Longhand(longhand_id) => longhand_id.into(),
|
||||
PropertyId::ShorthandAlias(_, alias_id) => alias_id.into(),
|
||||
PropertyId::LonghandAlias(_, alias_id) => alias_id.into(),
|
||||
};
|
||||
|
||||
PropertyId::Shorthand(shorthand_id) => id = shorthand_id.into(),
|
||||
PropertyId::Longhand(longhand_id) => id = longhand_id.into(),
|
||||
}
|
||||
}
|
||||
debug_assert!(
|
||||
matches!(
|
||||
context.rule_type(),
|
||||
CssRuleType::Keyframe | CssRuleType::Page | CssRuleType::Style
|
||||
),
|
||||
"Declarations are only expected inside a keyframe, page, or style rule."
|
||||
);
|
||||
|
||||
<% 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_PAGE_RULE", lambda p: not p.allowed_in_page_rule)}
|
||||
match context.rule_type {
|
||||
match context.rule_type() {
|
||||
CssRuleType::Keyframe if DISALLOWED_IN_KEYFRAME_BLOCK.contains(id) => {
|
||||
return Err(());
|
||||
return false;
|
||||
}
|
||||
CssRuleType::Page if DISALLOWED_IN_PAGE_RULE.contains(id) => {
|
||||
return Err(())
|
||||
return false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -1303,7 +1316,7 @@ impl PropertyId {
|
|||
${id_set("ENABLED_IN_UA_SHEETS", lambda p: p.explicitly_enabled_in_ua_sheets())}
|
||||
${id_set("ENABLED_IN_CHROME", lambda p: p.explicitly_enabled_in_chrome())}
|
||||
${id_set("EXPERIMENTAL", lambda p: p.experimental(product))}
|
||||
${id_set("ALWAYS_ENABLED", lambda p: not p.experimental(product) and p.enabled_in_content())}
|
||||
${id_set("ALWAYS_ENABLED", lambda p: (not p.experimental(product)) and p.enabled_in_content())}
|
||||
|
||||
let passes_pref_check = || {
|
||||
% if product == "servo":
|
||||
|
@ -1323,56 +1336,29 @@ impl PropertyId {
|
|||
|
||||
PREFS.get(pref).as_boolean().unwrap_or(false)
|
||||
% else:
|
||||
let id = match alias {
|
||||
Some(alias_id) => alias_id.to_nscsspropertyid().unwrap(),
|
||||
None => self.to_nscsspropertyid().unwrap(),
|
||||
};
|
||||
|
||||
unsafe { structs::nsCSSProps_gPropertyEnabled[id as usize] }
|
||||
unsafe { structs::nsCSSProps_gPropertyEnabled[self.to_nscsspropertyid().unwrap() as usize] }
|
||||
% endif
|
||||
};
|
||||
|
||||
if ALWAYS_ENABLED.contains(id) {
|
||||
return Ok(())
|
||||
return true
|
||||
}
|
||||
|
||||
if EXPERIMENTAL.contains(id) && passes_pref_check() {
|
||||
return Ok(())
|
||||
return true
|
||||
}
|
||||
|
||||
if context.stylesheet_origin == Origin::UserAgent &&
|
||||
ENABLED_IN_UA_SHEETS.contains(id)
|
||||
{
|
||||
return Ok(())
|
||||
return true
|
||||
}
|
||||
|
||||
if context.chrome_rules_enabled && ENABLED_IN_CHROME.contains(id) {
|
||||
return Ok(())
|
||||
if context.chrome_rules_enabled() && ENABLED_IN_CHROME.contains(id) {
|
||||
return true
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Parsing Context for PropertyId.
|
||||
pub struct PropertyParserContext {
|
||||
/// Whether the property is parsed in a chrome:// stylesheet.
|
||||
pub chrome_rules_enabled: bool,
|
||||
/// 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 {
|
||||
chrome_rules_enabled: context.chrome_rules_enabled(),
|
||||
stylesheet_origin: context.stylesheet_origin,
|
||||
rule_type: context.rule_type(),
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1635,6 +1621,13 @@ impl PropertyDeclaration {
|
|||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<(), ParseError<'i>> {
|
||||
assert!(declarations.is_empty());
|
||||
|
||||
if !id.allowed_in(context) {
|
||||
return Err(input.new_custom_error(
|
||||
StyleParseErrorKind::UnknownProperty(name)
|
||||
));
|
||||
}
|
||||
|
||||
let start = input.state();
|
||||
match id {
|
||||
PropertyId::Custom(property_name) => {
|
||||
|
@ -1651,6 +1644,7 @@ impl PropertyDeclaration {
|
|||
declarations.push(PropertyDeclaration::Custom(property_name, value));
|
||||
Ok(())
|
||||
}
|
||||
PropertyId::LonghandAlias(id, _) |
|
||||
PropertyId::Longhand(id) => {
|
||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||
input.try(|i| CSSWideKeyword::parse(i)).map(|keyword| {
|
||||
|
@ -1680,6 +1674,7 @@ impl PropertyDeclaration {
|
|||
declarations.push(declaration)
|
||||
})
|
||||
}
|
||||
PropertyId::ShorthandAlias(id, _) |
|
||||
PropertyId::Shorthand(id) => {
|
||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||
if let Ok(keyword) = input.try(|i| CSSWideKeyword::parse(i)) {
|
||||
|
@ -3592,13 +3587,13 @@ impl AliasId {
|
|||
/// Returns an nsCSSPropertyID.
|
||||
#[cfg(feature = "gecko")]
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
|
||||
pub fn to_nscsspropertyid(&self) -> nsCSSPropertyID {
|
||||
use gecko_bindings::structs::*;
|
||||
|
||||
match *self {
|
||||
% for property in data.all_aliases():
|
||||
AliasId::${property.camel_case} => {
|
||||
Ok(${helpers.alias_to_nscsspropertyid(property.ident)})
|
||||
${helpers.alias_to_nscsspropertyid(property.ident)}
|
||||
},
|
||||
% endfor
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, Source
|
|||
use error_reporting::{NullReporter, ContextualParseError, ParseErrorReporter};
|
||||
use parser::{ParserContext, ParserErrorContext};
|
||||
use properties::{DeclarationSource, Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
||||
use properties::{PropertyDeclarationId, PropertyParserContext, LonghandId, SourcePropertyDeclaration};
|
||||
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
|
||||
use properties::LonghandIdSet;
|
||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||
use servo_arc::Arc;
|
||||
|
@ -581,19 +581,22 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
|
|||
type Declaration = ();
|
||||
type Error = StyleParseErrorKind<'i>;
|
||||
|
||||
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
||||
-> Result<(), ParseError<'i>> {
|
||||
let property_context = PropertyParserContext::new(self.context);
|
||||
|
||||
let id = PropertyId::parse(&name, Some(&property_context)).map_err(|()| {
|
||||
fn parse_value<'t>(
|
||||
&mut self,
|
||||
name: CowRcStr<'i>,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<(), ParseError<'i>> {
|
||||
let id = PropertyId::parse(&name).map_err(|()| {
|
||||
input.new_custom_error(StyleParseErrorKind::UnknownProperty(name.clone()))
|
||||
})?;
|
||||
match PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input) {
|
||||
Ok(()) => {
|
||||
// In case there is still unparsed text in the declaration, we should roll back.
|
||||
input.expect_exhausted().map_err(|e| e.into())
|
||||
}
|
||||
Err(e) => Err(e.into())
|
||||
}
|
||||
|
||||
// TODO(emilio): Shouldn't this use parse_entirely?
|
||||
PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input)?;
|
||||
|
||||
// In case there is still unparsed text in the declaration, we should
|
||||
// roll back.
|
||||
input.expect_exhausted()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use cssparser::{ParseError as CssParseError, ParserInput};
|
|||
#[cfg(feature = "gecko")]
|
||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||
use parser::ParserContext;
|
||||
use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration};
|
||||
use properties::{PropertyId, PropertyDeclaration, SourcePropertyDeclaration};
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
use servo_arc::Arc;
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
|
@ -259,9 +259,8 @@ impl Declaration {
|
|||
let prop = input.expect_ident().unwrap().as_ref().to_owned();
|
||||
input.expect_colon().unwrap();
|
||||
|
||||
let property_context = PropertyParserContext::new(&context);
|
||||
let id = PropertyId::parse(&prop, Some(&property_context))
|
||||
.map_err(|()| input.new_custom_error(()))?;
|
||||
let id = PropertyId::parse(&prop)
|
||||
.map_err(|_| input.new_custom_error(()))?;
|
||||
|
||||
let mut declarations = SourcePropertyDeclaration::new();
|
||||
input.parse_until_before(Delimiter::Bang, |input| {
|
||||
|
|
|
@ -2443,7 +2443,8 @@ where
|
|||
url_data,
|
||||
reporter,
|
||||
parsing_mode,
|
||||
quirks_mode)
|
||||
quirks_mode,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -2690,7 +2691,7 @@ pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(
|
|||
macro_rules! get_property_id_from_property {
|
||||
($property: ident, $ret: expr) => {{
|
||||
let property = $property.as_ref().unwrap().as_str_unchecked();
|
||||
match PropertyId::parse(property.into(), None) {
|
||||
match PropertyId::parse(property.into()) {
|
||||
Ok(property_id) => property_id,
|
||||
Err(_) => { return $ret; }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue