Bug 1453521 - Support prefs for aliases in Servo side. r?heycam draft
authorXidorn Quan <me@upsuper.org>
Thu, 12 Apr 2018 10:27:43 +1000
changeset 780764 5ec21256b95b3d5d1caf9c9c3b5ce3b8a5c55a33
parent 780763 07e410243eaaf363f79e785756e57d3556a0b627
push id106122
push userxquan@mozilla.com
push dateThu, 12 Apr 2018 00:29:02 +0000
reviewersheycam
bugs1453521
milestone61.0a1
Bug 1453521 - Support prefs for aliases in Servo side. r?heycam MozReview-Commit-ID: 8DAFmLDVYlR
servo/components/style/properties/data.py
servo/components/style/properties/longhand/box.mako.rs
servo/components/style/properties/longhand/column.mako.rs
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/properties/longhand/position.mako.rs
servo/components/style/properties/shorthand/border.mako.rs
servo/components/style/properties/shorthand/box.mako.rs
--- a/servo/components/style/properties/data.py
+++ b/servo/components/style/properties/data.py
@@ -140,16 +140,27 @@ class Keyword(object):
 
 def arg_to_bool(arg):
     if isinstance(arg, bool):
         return arg
     assert arg in ["True", "False"], "Unexpected value for boolean arguement: " + repr(arg)
     return arg == "True"
 
 
+def parse_property_aliases(alias_list):
+    result = []
+    if alias_list:
+        for alias in alias_list.split():
+            (name, _, pref) = alias.partition(":")
+            if name.startswith("-webkit-") and not pref:
+                pref = "layout.css.prefixes.webkit"
+            result.append((name, pref))
+    return result
+
+
 class Longhand(object):
     def __init__(self, style_struct, name, spec=None, animation_value_type=None, keyword=None,
                  predefined_type=None, servo_pref=None, gecko_pref=None,
                  enabled_in="content", need_index=False,
                  gecko_ffi_name=None,
                  allowed_in_keyframe_block=True, cast_type='u8',
                  logical=False, alias=None, extra_prefixes=None, boxed=False,
                  flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=False,
@@ -173,18 +184,18 @@ class Longhand(object):
         #  * "content" implies the property is accessible unconditionally,
         #    modulo a pref, set via servo_pref / gecko_pref.
         assert enabled_in in ["", "ua", "chrome", "content"]
         self.enabled_in = enabled_in
         self.need_index = need_index
         self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
         self.cast_type = cast_type
         self.logical = arg_to_bool(logical)
-        self.alias = alias.split() if alias else []
-        self.extra_prefixes = extra_prefixes.split() if extra_prefixes else []
+        self.alias = parse_property_aliases(alias)
+        self.extra_prefixes = parse_property_aliases(extra_prefixes)
         self.boxed = arg_to_bool(boxed)
         self.flags = flags.split() if flags else []
         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.is_vector = vector
 
         # https://drafts.csswg.org/css-animations/#keyframes
@@ -317,18 +328,18 @@ class Shorthand(object):
         self.spec = spec
         self.ident = to_rust_ident(name)
         self.camel_case = to_camel_case(self.ident)
         self.servo_pref = servo_pref
         self.gecko_pref = gecko_pref
         self.sub_properties = sub_properties
         assert enabled_in in ["", "ua", "chrome", "content"]
         self.enabled_in = enabled_in
-        self.alias = alias.split() if alias else []
-        self.extra_prefixes = extra_prefixes.split() if extra_prefixes else []
+        self.alias = parse_property_aliases(alias)
+        self.extra_prefixes = parse_property_aliases(extra_prefixes)
         self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule)
         self.flags = flags.split() if flags else []
 
         # https://drafts.csswg.org/css-animations/#keyframes
         # > The <declaration-list> inside of <keyframe-block> accepts any CSS property
         # > except those defined in this specification,
         # > but does accept the `animation-play-state` property and interprets it specially.
         self.allowed_in_keyframe_block = allowed_in_keyframe_block \
@@ -368,23 +379,23 @@ class Shorthand(object):
     def enabled_in_content(self):
         return self.enabled_in == "content"
 
     def nscsspropertyid(self):
         return "nsCSSPropertyID::eCSSProperty_%s" % self.ident
 
 
 class Alias(object):
-    def __init__(self, name, original):
+    def __init__(self, name, original, gecko_pref):
         self.name = name
         self.ident = to_rust_ident(name)
         self.camel_case = to_camel_case(self.ident)
         self.enabled_in = original.enabled_in
         self.servo_pref = original.servo_pref
-        self.gecko_pref = original.gecko_pref
+        self.gecko_pref = gecko_pref
         self.allowed_in_page_rule = original.allowed_in_page_rule
         self.allowed_in_keyframe_block = original.allowed_in_keyframe_block
 
     def experimental(self, product):
         if product == "gecko":
             return bool(self.gecko_pref)
         return bool(self.servo_pref)
 
@@ -457,43 +468,47 @@ class PropertiesData(object):
 
     def active_style_structs(self):
         return [s for s in self.style_structs if s.additional_methods or s.longhands]
 
     def add_prefixed_aliases(self, property):
         # FIXME Servo's DOM architecture doesn't support vendor-prefixed properties.
         #       See servo/servo#14941.
         if self.product == "gecko":
-            for prefix in property.extra_prefixes:
-                property.alias.append('-%s-%s' % (prefix, property.name))
+            for (prefix, pref) in property.extra_prefixes:
+                # All webkit prefixed properties are currently under
+                # control of this pref in Gecko currently.
+                if prefix == "webkit" and not pref:
+                    pref = "layout.css.prefixes.webkit"
+                property.alias.append(('-%s-%s' % (prefix, property.name), pref))
 
     def declare_longhand(self, name, products="gecko servo", **kwargs):
         products = products.split()
         if self.product not in products:
             return
 
         longhand = Longhand(self.current_style_struct, name, **kwargs)
         self.add_prefixed_aliases(longhand)
-        longhand.alias = list(map(lambda x: Alias(x, longhand), longhand.alias))
+        longhand.alias = list(map(lambda (x, p): Alias(x, longhand, p), longhand.alias))
         self.longhand_aliases += longhand.alias
         self.current_style_struct.longhands.append(longhand)
         self.longhands.append(longhand)
         self.longhands_by_name[name] = longhand
 
         return longhand
 
     def declare_shorthand(self, name, sub_properties, products="gecko servo", *args, **kwargs):
         products = products.split()
         if self.product not in products:
             return
 
         sub_properties = [self.longhands_by_name[s] for s in sub_properties]
         shorthand = Shorthand(name, sub_properties, *args, **kwargs)
         self.add_prefixed_aliases(shorthand)
-        shorthand.alias = list(map(lambda x: Alias(x, shorthand), shorthand.alias))
+        shorthand.alias = list(map(lambda (x, p): Alias(x, shorthand, p), shorthand.alias))
         self.shorthand_aliases += shorthand.alias
         self.shorthands.append(shorthand)
         return shorthand
 
     def shorthands_except_all(self):
         return [s for s in self.shorthands if s.name != "all"]
 
     def all_aliases(self):
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -221,151 +221,155 @@
 // We allow it to apply to placeholders for UA sheets, which set it !important.
 <%helpers:longhand name="overflow-y" animation_value_type="discrete"
                    flags="APPLIES_TO_PLACEHOLDER",
                    spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-y"
                    servo_restyle_damage = "reflow">
     pub use super::overflow_x::{SpecifiedValue, parse, get_initial_value, computed_value};
 </%helpers:longhand>
 
+<% transition_extra_prefixes = "moz:layout.css.prefixes.transitions webkit" %>
+
 ${helpers.predefined_type("transition-duration",
                           "Time",
                           "computed::Time::zero()",
                           initial_specified_value="specified::Time::zero()",
                           parse_method="parse_non_negative",
                           vector=True,
                           need_index=True,
                           animation_value_type="none",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=transition_extra_prefixes,
                           spec="https://drafts.csswg.org/css-transitions/#propdef-transition-duration")}
 
 ${helpers.predefined_type("transition-timing-function",
                           "TimingFunction",
                           "computed::TimingFunction::ease()",
                           initial_specified_value="specified::TimingFunction::ease()",
                           vector=True,
                           need_index=True,
                           animation_value_type="none",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=transition_extra_prefixes,
                           spec="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function")}
 
 ${helpers.predefined_type(
     "transition-property",
     "TransitionProperty",
     "computed::TransitionProperty::all()",
     initial_specified_value="specified::TransitionProperty::all()",
     vector=True,
     allow_empty="NotInitial",
     need_index=True,
     needs_context=False,
     animation_value_type="none",
-    extra_prefixes="moz webkit",
+    extra_prefixes=transition_extra_prefixes,
     spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property",
 )}
 
 ${helpers.predefined_type("transition-delay",
                           "Time",
                           "computed::Time::zero()",
                           initial_specified_value="specified::Time::zero()",
                           vector=True,
                           need_index=True,
                           animation_value_type="none",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=transition_extra_prefixes,
                           spec="https://drafts.csswg.org/css-transitions/#propdef-transition-delay")}
 
 
+<% animation_extra_prefixes = "moz:layout.css.prefixes.animations webkit" %>
+
 ${helpers.predefined_type(
     "animation-name",
     "AnimationName",
     "computed::AnimationName::none()",
     initial_specified_value="specified::AnimationName::none()",
     vector=True,
     need_index=True,
     animation_value_type="none",
-    extra_prefixes="moz webkit",
+    extra_prefixes=animation_extra_prefixes,
     allowed_in_keyframe_block=False,
     spec="https://drafts.csswg.org/css-animations/#propdef-animation-name",
 )}
 
 ${helpers.predefined_type("animation-duration",
                           "Time",
                           "computed::Time::zero()",
                           initial_specified_value="specified::Time::zero()",
                           parse_method="parse_non_negative",
                           vector=True,
                           need_index=True,
                           animation_value_type="none",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=animation_extra_prefixes,
                           spec="https://drafts.csswg.org/css-transitions/#propdef-transition-duration")}
 
 // animation-timing-function is the exception to the rule for allowed_in_keyframe_block:
 // https://drafts.csswg.org/css-animations/#keyframes
 ${helpers.predefined_type("animation-timing-function",
                           "TimingFunction",
                           "computed::TimingFunction::ease()",
                           initial_specified_value="specified::TimingFunction::ease()",
                           vector=True,
                           need_index=True,
                           animation_value_type="none",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=animation_extra_prefixes,
                           allowed_in_keyframe_block=True,
                           spec="https://drafts.csswg.org/css-transitions/#propdef-animation-timing-function")}
 
 ${helpers.predefined_type(
     "animation-iteration-count",
     "AnimationIterationCount",
     "computed::AnimationIterationCount::one()",
     initial_specified_value="specified::AnimationIterationCount::one()",
     vector=True,
     need_index=True,
     animation_value_type="none",
-    extra_prefixes="moz webkit",
+    extra_prefixes=animation_extra_prefixes,
     allowed_in_keyframe_block=False,
     spec="https://drafts.csswg.org/css-animations/#propdef-animation-iteration-count",
 )}
 
 <% animation_direction_custom_consts = { "alternate-reverse": "Alternate_reverse" } %>
 ${helpers.single_keyword("animation-direction",
                          "normal reverse alternate alternate-reverse",
                          need_index=True,
                          animation_value_type="none",
                          vector=True,
                          gecko_enum_prefix="PlaybackDirection",
                          custom_consts=animation_direction_custom_consts,
-                         extra_prefixes="moz webkit",
+                         extra_prefixes=animation_extra_prefixes,
                          spec="https://drafts.csswg.org/css-animations/#propdef-animation-direction",
                          allowed_in_keyframe_block=False)}
 
 ${helpers.single_keyword("animation-play-state",
                          "running paused",
                          need_index=True,
                          animation_value_type="none",
                          vector=True,
-                         extra_prefixes="moz webkit",
+                         extra_prefixes=animation_extra_prefixes,
                          spec="https://drafts.csswg.org/css-animations/#propdef-animation-play-state",
                          allowed_in_keyframe_block=False)}
 
 ${helpers.single_keyword("animation-fill-mode",
                          "none forwards backwards both",
                          need_index=True,
                          animation_value_type="none",
                          vector=True,
                          gecko_enum_prefix="FillMode",
-                         extra_prefixes="moz webkit",
+                         extra_prefixes=animation_extra_prefixes,
                          spec="https://drafts.csswg.org/css-animations/#propdef-animation-fill-mode",
                          allowed_in_keyframe_block=False)}
 
 ${helpers.predefined_type("animation-delay",
                           "Time",
                           "computed::Time::zero()",
                           initial_specified_value="specified::Time::zero()",
                           vector=True,
                           need_index=True,
                           animation_value_type="none",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=animation_extra_prefixes,
                           spec="https://drafts.csswg.org/css-animations/#propdef-animation-delay",
                           allowed_in_keyframe_block=False)}
 
 % for axis in ["x", "y"]:
     ${helpers.predefined_type(
         "scroll-snap-points-" + axis,
         "ScrollSnapPoint",
         "computed::ScrollSnapPoint::none()",
@@ -392,19 +396,21 @@
     vector=True,
     products="gecko",
     gecko_pref="layout.css.scroll-snap.enabled",
     spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-destination)",
     animation_value_type="discrete",
     allow_empty="NotInitial"
 )}
 
+<% transform_extra_prefixes = "moz:layout.css.prefixes.transforms webkit" %>
+
 ${helpers.predefined_type("transform", "Transform",
                           "generics::transform::Transform::none()",
-                          extra_prefixes="webkit moz",
+                          extra_prefixes=transform_extra_prefixes,
                           animation_value_type="ComputedValue",
                           gecko_ffi_name="mSpecifiedTransform",
                           flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
                           spec="https://drafts.csswg.org/css-transforms/#propdef-transform",
                           servo_restyle_damage = "reflow_out_of_flow")}
 
 ${helpers.predefined_type("rotate", "Rotate",
                           "generics::transform::Rotate::None",
@@ -512,35 +518,35 @@
                          animation_value_type="discrete")}
 
 ${helpers.predefined_type(
     "perspective",
     "Perspective",
     "computed::Perspective::none()",
     gecko_ffi_name="mChildPerspective",
     spec="https://drafts.csswg.org/css-transforms/#perspective",
-    extra_prefixes="moz webkit",
+    extra_prefixes=transform_extra_prefixes,
     flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
     animation_value_type="AnimatedPerspective",
     servo_restyle_damage = "reflow_out_of_flow",
 )}
 
 ${helpers.predefined_type("perspective-origin",
                           "position::Position",
                           "computed::position::Position::center()",
                           boxed=True,
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=transform_extra_prefixes,
                           spec="https://drafts.csswg.org/css-transforms-2/#perspective-origin-property",
                           animation_value_type="ComputedValue",
                           servo_restyle_damage = "reflow_out_of_flow")}
 
 ${helpers.single_keyword("backface-visibility",
                          "visible hidden",
                          spec="https://drafts.csswg.org/css-transforms/#backface-visibility-property",
-                         extra_prefixes="moz webkit",
+                         extra_prefixes=transform_extra_prefixes,
                          animation_value_type="discrete")}
 
 ${helpers.single_keyword("transform-box",
                          "border-box fill-box view-box",
                          gecko_enum_prefix="StyleGeometryBox",
                          products="gecko",
                          gecko_pref="svg.transform-box.enabled",
                          spec="https://drafts.csswg.org/css-transforms/#transform-box",
@@ -548,27 +554,27 @@
                          animation_value_type="discrete")}
 
 ${helpers.predefined_type(
     "transform-style",
     "TransformStyle",
     "computed::TransformStyle::" + ("Auto" if product == "servo" else "Flat"),
     spec="https://drafts.csswg.org/css-transforms-2/#transform-style-property",
     needs_context=False,
-    extra_prefixes="moz webkit",
+    extra_prefixes=transform_extra_prefixes,
     flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
     animation_value_type="discrete",
     servo_restyle_damage = "reflow_out_of_flow",
 )}
 
 ${helpers.predefined_type("transform-origin",
                           "TransformOrigin",
                           "computed::TransformOrigin::initial_value()",
                           animation_value_type="ComputedValue",
-                          extra_prefixes="moz webkit",
+                          extra_prefixes=transform_extra_prefixes,
                           gecko_ffi_name="mTransformOrigin",
                           boxed=True,
                           spec="https://drafts.csswg.org/css-transforms/#transform-origin-property",
                           servo_restyle_damage = "reflow_out_of_flow")}
 
 ${helpers.predefined_type("contain",
                           "Contain",
                           "specified::Contain::empty()",
--- a/servo/components/style/properties/longhand/column.mako.rs
+++ b/servo/components/style/properties/longhand/column.mako.rs
@@ -68,16 +68,16 @@
     ignored_when_colors_disabled=True,
     spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color",
 )}
 
 ${helpers.single_keyword("column-span", "none all",
                          products="gecko", animation_value_type="discrete",
                          gecko_pref="layout.css.column-span.enabled",
                          spec="https://drafts.csswg.org/css-multicol/#propdef-column-span",
-                         extra_prefixes="moz")}
+                         extra_prefixes="moz:layout.css.column-span.enabled")}
 
 ${helpers.single_keyword("column-rule-style",
                          "none hidden dotted dashed solid double groove ridge inset outset",
                          products="gecko", extra_prefixes="moz",
                          gecko_constant_prefix="NS_STYLE_BORDER_STYLE",
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-style")}
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -145,17 +145,17 @@
                                 flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
                                 animation_value_type="discrete")}
 
 ${helpers.predefined_type("font-feature-settings",
                           "FontFeatureSettings",
                           products="gecko",
                           initial_value="computed::FontFeatureSettings::normal()",
                           initial_specified_value="specified::FontFeatureSettings::normal()",
-                          extra_prefixes="moz",
+                          extra_prefixes="moz:layout.css.prefixes.font-features",
                           animation_value_type="discrete",
                           flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
                           spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings")}
 
 <%
 # This spec link is too long to fit elsewhere
 variation_spec = """\
 https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control-the-font-variation-settings-property\
@@ -173,17 +173,17 @@ https://drafts.csswg.org/css-fonts-4/#lo
                           spec="${variation_spec}")}
 
 ${helpers.predefined_type("font-language-override",
                           "FontLanguageOverride",
                           products="gecko",
                           initial_value="computed::FontLanguageOverride::zero()",
                           initial_specified_value="specified::FontLanguageOverride::normal()",
                           animation_value_type="discrete",
-                          extra_prefixes="moz",
+                          extra_prefixes="moz:layout.css.prefixes.font-features",
                           flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
                           spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override")}
 
 ${helpers.single_keyword_system("font-optical-sizing",
                                 "auto none",
                                 products="gecko",
                                 gecko_pref="layout.css.font-variations.enabled",
                                 gecko_ffi_name="mFont.opticalSizing",
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -52,22 +52,24 @@ macro_rules! impl_align_conversions {
 )}
 
 // CSS Flexible Box Layout Module Level 1
 // http://www.w3.org/TR/css3-flexbox/
 
 // Flex container properties
 ${helpers.single_keyword("flex-direction", "row row-reverse column column-reverse",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-direction-property",
-                         extra_prefixes="webkit", animation_value_type="discrete",
+                         extra_prefixes="webkit",
+                         animation_value_type="discrete",
                          servo_restyle_damage = "reflow")}
 
 ${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse",
                          spec="https://drafts.csswg.org/css-flexbox/#flex-wrap-property",
-                         extra_prefixes="webkit", animation_value_type="discrete",
+                         extra_prefixes="webkit",
+                         animation_value_type="discrete",
                          servo_restyle_damage = "reflow")}
 
 % if product == "servo":
     // FIXME: Update Servo to support the same Syntax as Gecko.
     ${helpers.single_keyword("justify-content", "flex-start stretch flex-end center space-between space-around",
                              extra_prefixes="webkit",
                              spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
                              animation_value_type="discrete",
@@ -262,17 +264,17 @@ macro_rules! impl_align_conversions {
                                   logical=logical,
                                   allow_quirks=not logical,
                                   servo_restyle_damage = "reflow")}
     % endif
 % endfor
 
 ${helpers.single_keyword("box-sizing",
                          "content-box border-box",
-                         extra_prefixes="moz webkit",
+                         extra_prefixes="moz:layout.css.prefixes.box-sizing webkit",
                          spec="https://drafts.csswg.org/css-ui/#propdef-box-sizing",
                          gecko_enum_prefix="StyleBoxSizing",
                          custom_consts={ "content-box": "Content", "border-box": "Border" },
                          animation_value_type="discrete",
                          servo_restyle_damage = "reflow")}
 
 ${helpers.single_keyword("object-fit", "fill contain cover none scale-down",
                          products="gecko", animation_value_type="discrete",
--- a/servo/components/style/properties/shorthand/border.mako.rs
+++ b/servo/components/style/properties/shorthand/border.mako.rs
@@ -241,17 +241,18 @@ pub fn parse_border<'i, 't>(
 
             BorderRadius::serialize_rects(widths, heights, dest)
         }
     }
 </%helpers:shorthand>
 
 <%helpers:shorthand name="border-image" sub_properties="border-image-outset
     border-image-repeat border-image-slice border-image-source border-image-width"
-    extra_prefixes="moz webkit" spec="https://drafts.csswg.org/css-backgrounds-3/#border-image">
+    extra_prefixes="moz:layout.css.prefixes.border-image webkit"
+    spec="https://drafts.csswg.org/css-backgrounds-3/#border-image">
     use properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
     use properties::longhands::{border_image_source, border_image_width};
 
     pub fn parse_value<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Longhands, ParseError<'i>> {
         % for name in "outset repeat slice source width".split():
--- a/servo/components/style/properties/shorthand/box.mako.rs
+++ b/servo/components/style/properties/shorthand/box.mako.rs
@@ -106,17 +106,18 @@ macro_rules! try_parse_one {
             }) {
                 $var = Some(value);
                 continue;
             }
         }
     };
 }
 
-<%helpers:shorthand name="transition" extra_prefixes="moz webkit"
+<%helpers:shorthand name="transition"
+                    extra_prefixes="moz:layout.css.prefixes.transitions webkit"
                     sub_properties="transition-property transition-duration
                                     transition-timing-function
                                     transition-delay"
                     spec="https://drafts.csswg.org/css-transitions/#propdef-transition">
     % for prop in "delay duration property timing_function".split():
     use properties::longhands::transition_${prop};
     % endfor
 
@@ -246,17 +247,18 @@ macro_rules! try_parse_one {
                     self.transition_${name}.0[i].to_css(dest)?;
                 % endfor
             }
             Ok(())
         }
     }
 </%helpers:shorthand>
 
-<%helpers:shorthand name="animation" extra_prefixes="moz webkit"
+<%helpers:shorthand name="animation"
+                    extra_prefixes="moz:layout.css.prefixes.animations webkit"
                     sub_properties="animation-name animation-duration
                                     animation-timing-function animation-delay
                                     animation-iteration-count animation-direction
                                     animation-fill-mode animation-play-state"
                     allowed_in_keyframe_block="False"
                     spec="https://drafts.csswg.org/css-animations/#propdef-animation">
     <%
         props = "name duration timing_function delay iteration_count \