mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: Move most of allowed_in to NonCustomPropertyId.
Also simplify the servo property id to gecko property id conversion to be faster and less repetitive.
This commit is contained in:
parent
5af219e818
commit
1548520710
1 changed files with 108 additions and 125 deletions
|
@ -413,10 +413,112 @@ pub mod animated_properties {
|
||||||
<%include file="/helpers/animated_properties.mako.rs" />
|
<%include file="/helpers/animated_properties.mako.rs" />
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A longhand or shorthand porperty
|
/// A longhand or shorthand property.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct NonCustomPropertyId(usize);
|
pub struct NonCustomPropertyId(usize);
|
||||||
|
|
||||||
|
impl NonCustomPropertyId {
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn to_nscsspropertyid(self) -> nsCSSPropertyID {
|
||||||
|
static MAP: [nsCSSPropertyID; ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())}] = [
|
||||||
|
% for property in data.longhands:
|
||||||
|
${helpers.to_nscsspropertyid(property.ident)},
|
||||||
|
% endfor
|
||||||
|
% for property in data.shorthands:
|
||||||
|
${helpers.to_nscsspropertyid(property.ident)},
|
||||||
|
% endfor
|
||||||
|
% for property in data.all_aliases():
|
||||||
|
${helpers.alias_to_nscsspropertyid(property.ident)},
|
||||||
|
% endfor
|
||||||
|
];
|
||||||
|
|
||||||
|
MAP[self.0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allowed_in(self, context: &ParserContext) -> bool {
|
||||||
|
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() {
|
||||||
|
CssRuleType::Keyframe if DISALLOWED_IN_KEYFRAME_BLOCK.contains(self) => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CssRuleType::Page if DISALLOWED_IN_PAGE_RULE.contains(self) => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The semantics of these are kinda hard to reason about, what follows
|
||||||
|
// is a description of the different combinations that can happen with
|
||||||
|
// these three sets.
|
||||||
|
//
|
||||||
|
// Experimental properties are generally controlled by prefs, but an
|
||||||
|
// experimental property explicitly enabled in certain context (UA or
|
||||||
|
// chrome sheets) is always usable in the context regardless of the
|
||||||
|
// pref value.
|
||||||
|
//
|
||||||
|
// Non-experimental properties are either normal properties which are
|
||||||
|
// usable everywhere, or internal-only properties which are only usable
|
||||||
|
// in certain context they are explicitly enabled in.
|
||||||
|
${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())}
|
||||||
|
|
||||||
|
let passes_pref_check = || {
|
||||||
|
% if product == "servo":
|
||||||
|
static PREF_NAME: [Option< &str>; ${len(data.longhands) + len(data.shorthands)}] = [
|
||||||
|
% for property in data.longhands + data.shorthands:
|
||||||
|
% if property.servo_pref:
|
||||||
|
Some("${property.servo_pref}"),
|
||||||
|
% else:
|
||||||
|
None,
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
];
|
||||||
|
let pref = match PREF_NAME[self.0] {
|
||||||
|
None => return true,
|
||||||
|
Some(pref) => pref,
|
||||||
|
};
|
||||||
|
|
||||||
|
PREFS.get(pref).as_boolean().unwrap_or(false)
|
||||||
|
% else:
|
||||||
|
unsafe { structs::nsCSSProps_gPropertyEnabled[self.to_nscsspropertyid() as usize] }
|
||||||
|
% endif
|
||||||
|
};
|
||||||
|
|
||||||
|
if ALWAYS_ENABLED.contains(self) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if EXPERIMENTAL.contains(self) && passes_pref_check() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.stylesheet_origin == Origin::UserAgent &&
|
||||||
|
ENABLED_IN_UA_SHEETS.contains(self)
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.chrome_rules_enabled() && ENABLED_IN_CHROME.contains(self) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<LonghandId> for NonCustomPropertyId {
|
impl From<LonghandId> for NonCustomPropertyId {
|
||||||
fn from(id: LonghandId) -> Self {
|
fn from(id: LonghandId) -> Self {
|
||||||
NonCustomPropertyId(id as usize)
|
NonCustomPropertyId(id as usize)
|
||||||
|
@ -816,14 +918,9 @@ impl LonghandId {
|
||||||
|
|
||||||
/// Converts from a LonghandId to an adequate nsCSSPropertyID.
|
/// Converts from a LonghandId to an adequate nsCSSPropertyID.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[inline]
|
||||||
pub fn to_nscsspropertyid(self) -> nsCSSPropertyID {
|
pub fn to_nscsspropertyid(self) -> nsCSSPropertyID {
|
||||||
match self {
|
NonCustomPropertyId::from(self).to_nscsspropertyid()
|
||||||
% for property in data.longhands:
|
|
||||||
LonghandId::${property.camel_case} => {
|
|
||||||
${helpers.to_nscsspropertyid(property.ident)}
|
|
||||||
}
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -1038,14 +1135,9 @@ impl ShorthandId {
|
||||||
|
|
||||||
/// Converts from a ShorthandId to an adequate nsCSSPropertyID.
|
/// Converts from a ShorthandId to an adequate nsCSSPropertyID.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
#[inline]
|
||||||
pub fn to_nscsspropertyid(self) -> nsCSSPropertyID {
|
pub fn to_nscsspropertyid(self) -> nsCSSPropertyID {
|
||||||
match self {
|
NonCustomPropertyId::from(self).to_nscsspropertyid()
|
||||||
% for property in data.shorthands:
|
|
||||||
ShorthandId::${property.camel_case} => {
|
|
||||||
${helpers.to_nscsspropertyid(property.ident)}
|
|
||||||
}
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the longhand ids that form this shorthand.
|
/// Get the longhand ids that form this shorthand.
|
||||||
|
@ -1521,19 +1613,6 @@ impl PropertyId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an nsCSSPropertyID.
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
pub fn to_nscsspropertyid(&self) -> Result<nsCSSPropertyID, ()> {
|
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given this property id, get it either as a shorthand or as a
|
/// Given this property id, get it either as a shorthand or as a
|
||||||
/// `PropertyDeclarationId`.
|
/// `PropertyDeclarationId`.
|
||||||
pub fn as_shorthand(&self) -> Result<ShorthandId, PropertyDeclarationId> {
|
pub fn as_shorthand(&self) -> Result<ShorthandId, PropertyDeclarationId> {
|
||||||
|
@ -1571,86 +1650,7 @@ impl PropertyId {
|
||||||
PropertyId::LonghandAlias(_, alias_id) => alias_id.into(),
|
PropertyId::LonghandAlias(_, alias_id) => alias_id.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
debug_assert!(
|
id.allowed_in(context)
|
||||||
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() {
|
|
||||||
CssRuleType::Keyframe if DISALLOWED_IN_KEYFRAME_BLOCK.contains(id) => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CssRuleType::Page if DISALLOWED_IN_PAGE_RULE.contains(id) => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The semantics of these are kinda hard to reason about, what follows
|
|
||||||
// is a description of the different combinations that can happen with
|
|
||||||
// these three sets.
|
|
||||||
//
|
|
||||||
// Experimental properties are generally controlled by prefs, but an
|
|
||||||
// experimental property explicitly enabled in certain context (UA or
|
|
||||||
// chrome sheets) is always usable in the context regardless of the
|
|
||||||
// pref value.
|
|
||||||
//
|
|
||||||
// Non-experimental properties are either normal properties which are
|
|
||||||
// usable everywhere, or internal-only properties which are only usable
|
|
||||||
// in certain context they are explicitly enabled in.
|
|
||||||
${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())}
|
|
||||||
|
|
||||||
let passes_pref_check = || {
|
|
||||||
% if product == "servo":
|
|
||||||
static PREF_NAME: [Option< &str>; ${len(data.longhands) + len(data.shorthands)}] = [
|
|
||||||
% for property in data.longhands + data.shorthands:
|
|
||||||
% if property.servo_pref:
|
|
||||||
Some("${property.servo_pref}"),
|
|
||||||
% else:
|
|
||||||
None,
|
|
||||||
% endif
|
|
||||||
% endfor
|
|
||||||
];
|
|
||||||
let pref = match PREF_NAME[id.0] {
|
|
||||||
None => return true,
|
|
||||||
Some(pref) => pref,
|
|
||||||
};
|
|
||||||
|
|
||||||
PREFS.get(pref).as_boolean().unwrap_or(false)
|
|
||||||
% else:
|
|
||||||
unsafe { structs::nsCSSProps_gPropertyEnabled[self.to_nscsspropertyid().unwrap() as usize] }
|
|
||||||
% endif
|
|
||||||
};
|
|
||||||
|
|
||||||
if ALWAYS_ENABLED.contains(id) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if EXPERIMENTAL.contains(id) && passes_pref_check() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.stylesheet_origin == Origin::UserAgent &&
|
|
||||||
ENABLED_IN_UA_SHEETS.contains(id)
|
|
||||||
{
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.chrome_rules_enabled() && ENABLED_IN_CHROME.contains(id) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3859,23 +3859,6 @@ impl fmt::Debug for AliasId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AliasId {
|
|
||||||
/// Returns an nsCSSPropertyID.
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
pub fn to_nscsspropertyid(&self) -> nsCSSPropertyID {
|
|
||||||
use gecko_bindings::structs::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
% for property in data.all_aliases():
|
|
||||||
AliasId::${property.camel_case} => {
|
|
||||||
${helpers.alias_to_nscsspropertyid(property.ident)}
|
|
||||||
},
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(emilio): This macro doesn't account for experimental properties, so
|
// FIXME(emilio): This macro doesn't account for experimental properties, so
|
||||||
// even with the pref disabled you can set them from CSSOM in Servo.
|
// even with the pref disabled you can set them from CSSOM in Servo.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue