diff --git a/components/style/properties/data.py b/components/style/properties/data.py index c0510d0c13f..32ab3079f03 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -151,7 +151,7 @@ class Longhand(object): allowed_in_keyframe_block=True, cast_type='u8', has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False, flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=False, - vector=False): + gecko_pref_ident=None, vector=False): self.name = name if not spec: raise TypeError("Spec should be specified for %s" % name) @@ -178,6 +178,7 @@ class Longhand(object): self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule) self.allow_quirks = allow_quirks self.ignored_when_colors_disabled = ignored_when_colors_disabled + self.gecko_pref_ident = gecko_pref_ident or self.ident self.is_vector = vector # https://drafts.csswg.org/css-animations/#keyframes @@ -214,7 +215,7 @@ class Longhand(object): class Shorthand(object): def __init__(self, name, sub_properties, spec=None, experimental=False, internal=False, allowed_in_keyframe_block=True, alias=None, extra_prefixes=None, - allowed_in_page_rule=False, flags=None): + allowed_in_page_rule=False, flags=None, gecko_pref_ident=None): self.name = name if not spec: raise TypeError("Spec should be specified for %s" % name) @@ -229,6 +230,7 @@ class Shorthand(object): self.extra_prefixes = extra_prefixes.split() if extra_prefixes else [] self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule) self.flags = flags.split() if flags else [] + self.gecko_pref_ident = gecko_pref_ident or self.ident # https://drafts.csswg.org/css-animations/#keyframes # > The inside of accepts any CSS property diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 871eb37513d..82cd921709a 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -171,6 +171,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed", gecko_enum_prefix="StyleFloat" gecko_inexhaustive="True" gecko_ffi_name="mFloat" + gecko_pref_ident="float_" spec="https://drafts.csswg.org/css-box/#propdef-float"> no_viewport_percentage!(SpecifiedValue); impl ToComputedValue for SpecifiedValue { diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 19d9cc54b0e..cb86628310d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1179,30 +1179,46 @@ impl ToCss for PropertyDeclaration { } } -<%def name="property_pref_check(property)"> - % if property.experimental and product == "servo": - if !PREFS.get("${property.experimental}") - .as_boolean().unwrap_or(false) { - return Err(PropertyDeclarationParseError::ExperimentalProperty) - } - % endif - % if product == "gecko": - <% - # gecko can't use the identifier `float` - # and instead uses `float_` - # XXXManishearth make this an attr on the property - # itself? - pref_ident = property.ident - if pref_ident == "float": - pref_ident = "float_" - %> - if structs::root::mozilla::SERVO_PREF_ENABLED_${pref_ident} { - let id = structs::${helpers.to_nscsspropertyid(property.ident)}; - let enabled = unsafe { bindings::Gecko_PropertyId_IsPrefEnabled(id) }; - if !enabled { - return Err(PropertyDeclarationParseError::ExperimentalProperty) +<%def name="property_exposure_check(property)"> + // For properties that are experimental but not internal, the pref will + // control its availability in all sheets. For properties that are + // both experimental and internal, the pref only controls its + // availability in non-UA sheets (and in UA sheets it is always available). + let is_experimental = + % if property.experimental and product == "servo": + true; + % elif product == "gecko": + structs::root::mozilla::SERVO_PREF_ENABLED_${property.gecko_pref_ident}; + % else: + false; + % endif + + let passes_pref_check = + % if property.experimental and product == "servo": + PREFS.get("${property.experimental}").as_boolean().unwrap_or(false); + % elif product == "gecko": + { + let id = structs::${helpers.to_nscsspropertyid(property.ident)}; + unsafe { bindings::Gecko_PropertyId_IsPrefEnabled(id) } + }; + % else: + true; + % endif + + % if property.internal: + if context.stylesheet_origin != Origin::UserAgent { + if is_experimental { + if !passes_pref_check { + return Err(PropertyDeclarationParseError::ExperimentalProperty); + } + } else { + return Err(PropertyDeclarationParseError::UnknownProperty); } } + % else: + if is_experimental && !passes_pref_check { + return Err(PropertyDeclarationParseError::ExperimentalProperty); + } % endif @@ -1418,18 +1434,13 @@ impl PropertyDeclaration { return Err(PropertyDeclarationParseError::AnimationPropertyInKeyframeBlock) } % endif - % if property.internal: - if context.stylesheet_origin != Origin::UserAgent { - return Err(PropertyDeclarationParseError::UnknownProperty) - } - % endif % if not property.allowed_in_page_rule: if rule_type == CssRuleType::Page { return Err(PropertyDeclarationParseError::NotAllowedInPageRule) } % endif - ${property_pref_check(property)} + ${property_exposure_check(property)} match longhands::${property.ident}::parse_declared(context, input) { Ok(value) => { @@ -1452,18 +1463,13 @@ impl PropertyDeclaration { return Err(PropertyDeclarationParseError::AnimationPropertyInKeyframeBlock) } % endif - % if shorthand.internal: - if context.stylesheet_origin != Origin::UserAgent { - return Err(PropertyDeclarationParseError::UnknownProperty) - } - % endif % if not shorthand.allowed_in_page_rule: if rule_type == CssRuleType::Page { return Err(PropertyDeclarationParseError::NotAllowedInPageRule) } % endif - ${property_pref_check(shorthand)} + ${property_exposure_check(shorthand)} match input.try(|i| CSSWideKeyword::parse(context, i)) { Ok(keyword) => {