summaryrefslogtreecommitdiffstats
path: root/servo/components/style/properties/longhands
diff options
context:
space:
mode:
Diffstat (limited to 'servo/components/style/properties/longhands')
-rw-r--r--servo/components/style/properties/longhands/background.mako.rs116
-rw-r--r--servo/components/style/properties/longhands/border.mako.rs159
-rw-r--r--servo/components/style/properties/longhands/box.mako.rs587
-rw-r--r--servo/components/style/properties/longhands/column.mako.rs83
-rw-r--r--servo/components/style/properties/longhands/counters.mako.rs48
-rw-r--r--servo/components/style/properties/longhands/effects.mako.rs86
-rw-r--r--servo/components/style/properties/longhands/font.mako.rs488
-rw-r--r--servo/components/style/properties/longhands/inherited_box.mako.rs97
-rw-r--r--servo/components/style/properties/longhands/inherited_svg.mako.rs217
-rw-r--r--servo/components/style/properties/longhands/inherited_table.mako.rs49
-rw-r--r--servo/components/style/properties/longhands/inherited_text.mako.rs408
-rw-r--r--servo/components/style/properties/longhands/inherited_ui.mako.rs118
-rw-r--r--servo/components/style/properties/longhands/list.mako.rs75
-rw-r--r--servo/components/style/properties/longhands/margin.mako.rs52
-rw-r--r--servo/components/style/properties/longhands/outline.mako.rs53
-rw-r--r--servo/components/style/properties/longhands/padding.mako.rs41
-rw-r--r--servo/components/style/properties/longhands/page.mako.rs42
-rw-r--r--servo/components/style/properties/longhands/position.mako.rs448
-rw-r--r--servo/components/style/properties/longhands/svg.mako.rs258
-rw-r--r--servo/components/style/properties/longhands/table.mako.rs28
-rw-r--r--servo/components/style/properties/longhands/text.mako.rs81
-rw-r--r--servo/components/style/properties/longhands/ui.mako.rs395
-rw-r--r--servo/components/style/properties/longhands/xul.mako.rs79
23 files changed, 4008 insertions, 0 deletions
diff --git a/servo/components/style/properties/longhands/background.mako.rs b/servo/components/style/properties/longhands/background.mako.rs
new file mode 100644
index 0000000000..76b71b12cd
--- /dev/null
+++ b/servo/components/style/properties/longhands/background.mako.rs
@@ -0,0 +1,116 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("Background", inherited=False) %>
+
+${helpers.predefined_type(
+ "background-color",
+ "Color",
+ "computed::Color::transparent()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="SpecifiedValue::transparent()",
+ spec="https://drafts.csswg.org/css-backgrounds/#background-color",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ allow_quirks="Yes",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+)}
+
+${helpers.predefined_type(
+ "background-image",
+ "Image",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::Image::None",
+ initial_specified_value="specified::Image::None",
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
+ vector="True",
+ animation_value_type="discrete",
+ ignored_when_colors_disabled="True",
+)}
+
+% for (axis, direction, initial) in [("x", "Horizontal", "left"), ("y", "Vertical", "top")]:
+ ${helpers.predefined_type(
+ "background-position-" + axis,
+ "position::" + direction + "Position",
+ "computed::LengthPercentage::zero_percent()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="SpecifiedValue::initial_specified_value()",
+ spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-" + axis,
+ animation_value_type="ComputedValue",
+ vector=True,
+ vector_animation_type="repeatable_list",
+ )}
+% endfor
+
+${helpers.predefined_type(
+ "background-repeat",
+ "BackgroundRepeat",
+ "computed::BackgroundRepeat::repeat()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::BackgroundRepeat::repeat()",
+ animation_value_type="discrete",
+ vector=True,
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat",
+)}
+
+${helpers.single_keyword(
+ "background-attachment",
+ "scroll" + (" fixed" if engine in ["gecko", "servo-2013"] else "") + (" local" if engine == "gecko" else ""),
+ engines="gecko servo-2013 servo-2020",
+ vector=True,
+ gecko_enum_prefix="StyleImageLayerAttachment",
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-attachment",
+ animation_value_type="discrete",
+)}
+
+${helpers.single_keyword(
+ "background-clip",
+ "border-box padding-box content-box",
+ engines="gecko servo-2013 servo-2020",
+ extra_gecko_values="text",
+ vector=True, extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
+ gecko_inexhaustive=True,
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-clip",
+ animation_value_type="discrete",
+)}
+
+${helpers.single_keyword(
+ "background-origin",
+ "padding-box border-box content-box",
+ engines="gecko servo-2013 servo-2020",
+ vector=True, extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
+ gecko_inexhaustive=True,
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-origin",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "background-size",
+ "BackgroundSize",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::BackgroundSize::auto()",
+ initial_specified_value="specified::BackgroundSize::auto()",
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-size",
+ vector=True,
+ vector_animation_type="repeatable_list",
+ animation_value_type="BackgroundSizeList",
+ extra_prefixes="webkit")}
+
+// https://drafts.fxtf.org/compositing/#background-blend-mode
+${helpers.single_keyword(
+ "background-blend-mode",
+ """normal multiply screen overlay darken lighten color-dodge
+ color-burn hard-light soft-light difference exclusion hue
+ saturation color luminosity""",
+ gecko_enum_prefix="StyleBlend",
+ vector=True,
+ engines="gecko",
+ animation_value_type="discrete",
+ gecko_inexhaustive=True,
+ spec="https://drafts.fxtf.org/compositing/#background-blend-mode",
+)}
diff --git a/servo/components/style/properties/longhands/border.mako.rs b/servo/components/style/properties/longhands/border.mako.rs
new file mode 100644
index 0000000000..299b330b66
--- /dev/null
+++ b/servo/components/style/properties/longhands/border.mako.rs
@@ -0,0 +1,159 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import Keyword, Method, ALL_CORNERS, PHYSICAL_SIDES, ALL_SIDES, maybe_moz_logical_alias %>
+
+<% data.new_style_struct("Border", inherited=False,
+ additional_methods=[Method("border_" + side + "_has_nonzero_width",
+ "bool") for side in ["top", "right", "bottom", "left"]]) %>
+<%
+ def maybe_logical_spec(side, kind):
+ if side[1]: # if it is logical
+ return "https://drafts.csswg.org/css-logical-props/#propdef-border-%s-%s" % (side[0], kind)
+ else:
+ return "https://drafts.csswg.org/css-backgrounds/#border-%s-%s" % (side[0], kind)
+%>
+% for side in ALL_SIDES:
+ <%
+ side_name = side[0]
+ is_logical = side[1]
+ %>
+ ${helpers.predefined_type(
+ "border-%s-color" % side_name, "Color",
+ "computed_value::T::currentcolor()",
+ engines="gecko servo-2013 servo-2020",
+ aliases=maybe_moz_logical_alias(engine, side, "-moz-border-%s-color"),
+ spec=maybe_logical_spec(side, "color"),
+ animation_value_type="AnimatedColor",
+ logical=is_logical,
+ logical_group="border-color",
+ allow_quirks="No" if is_logical else "Yes",
+ ignored_when_colors_disabled=True,
+ )}
+
+ ${helpers.predefined_type(
+ "border-%s-style" % side_name, "BorderStyle",
+ "specified::BorderStyle::None",
+ engines="gecko servo-2013 servo-2020",
+ aliases=maybe_moz_logical_alias(engine, side, "-moz-border-%s-style"),
+ spec=maybe_logical_spec(side, "style"),
+ animation_value_type="discrete" if not is_logical else "none",
+ logical=is_logical,
+ logical_group="border-style",
+ )}
+
+ ${helpers.predefined_type(
+ "border-%s-width" % side_name,
+ "BorderSideWidth",
+ "app_units::Au::from_px(3)",
+ engines="gecko servo-2013 servo-2020",
+ aliases=maybe_moz_logical_alias(engine, side, "-moz-border-%s-width"),
+ spec=maybe_logical_spec(side, "width"),
+ animation_value_type="NonNegativeLength",
+ logical=is_logical,
+ logical_group="border-width",
+ allow_quirks="No" if is_logical else "Yes",
+ servo_restyle_damage="reflow rebuild_and_reflow_inline"
+ )}
+% endfor
+
+% for corner in ALL_CORNERS:
+ <%
+ corner_name = corner[0]
+ is_logical = corner[1]
+ if is_logical:
+ prefixes = None
+ else:
+ prefixes = "webkit"
+ %>
+ ${helpers.predefined_type(
+ "border-%s-radius" % corner_name,
+ "BorderCornerRadius",
+ "computed::BorderCornerRadius::zero()",
+ "parse",
+ engines="gecko servo-2013 servo-2020",
+ extra_prefixes=prefixes,
+ spec=maybe_logical_spec(corner, "radius"),
+ boxed=True,
+ animation_value_type="BorderCornerRadius",
+ logical_group="border-radius",
+ logical=is_logical,
+ )}
+% endfor
+
+${helpers.single_keyword(
+ "box-decoration-break",
+ "slice clone",
+ engines="gecko",
+ gecko_enum_prefix="StyleBoxDecorationBreak",
+ spec="https://drafts.csswg.org/css-break/#propdef-box-decoration-break",
+ animation_value_type="discrete",
+)}
+
+${helpers.single_keyword(
+ "-moz-float-edge",
+ "content-box margin-box",
+ engines="gecko",
+ gecko_ffi_name="mFloatEdge",
+ gecko_enum_prefix="StyleFloatEdge",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-float-edge)",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "border-image-source",
+ "Image",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::Image::None",
+ initial_specified_value="specified::Image::None",
+ spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
+ vector=False,
+ animation_value_type="discrete",
+ boxed=engine == "servo-2013",
+ ignored_when_colors_disabled=True
+)}
+
+${helpers.predefined_type(
+ "border-image-outset",
+ "NonNegativeLengthOrNumberRect",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())",
+ initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())",
+ spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
+ animation_value_type="NonNegativeLengthOrNumberRect",
+ boxed=True,
+)}
+
+${helpers.predefined_type(
+ "border-image-repeat",
+ "BorderImageRepeat",
+ "computed::BorderImageRepeat::stretch()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::BorderImageRepeat::stretch()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat",
+)}
+
+${helpers.predefined_type(
+ "border-image-width",
+ "BorderImageWidth",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())",
+ initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
+ spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
+ animation_value_type="BorderImageWidth",
+ boxed=True,
+)}
+
+${helpers.predefined_type(
+ "border-image-slice",
+ "BorderImageSlice",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::BorderImageSlice::hundred_percent()",
+ initial_specified_value="specified::BorderImageSlice::hundred_percent()",
+ spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
+ animation_value_type="BorderImageSlice",
+ boxed=True,
+)}
diff --git a/servo/components/style/properties/longhands/box.mako.rs b/servo/components/style/properties/longhands/box.mako.rs
new file mode 100644
index 0000000000..e8212a3296
--- /dev/null
+++ b/servo/components/style/properties/longhands/box.mako.rs
@@ -0,0 +1,587 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import ALL_AXES, Keyword, Method, to_rust_ident, to_camel_case%>
+
+<% data.new_style_struct("Box",
+ inherited=False,
+ gecko_name="Display") %>
+
+${helpers.predefined_type(
+ "display",
+ "Display",
+ "computed::Display::inline()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Display::inline()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-display/#propdef-display",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "-moz-top-layer",
+ "none top",
+ engines="gecko",
+ gecko_enum_prefix="StyleTopLayer",
+ gecko_ffi_name="mTopLayer",
+ animation_value_type="none",
+ enabled_in="ua",
+ spec="Internal (not web-exposed)",
+)}
+
+// An internal-only property for elements in a top layer
+// https://fullscreen.spec.whatwg.org/#top-layer
+${helpers.single_keyword(
+ "-servo-top-layer",
+ "none top",
+ engines="servo-2013 servo-2020",
+ animation_value_type="none",
+ enabled_in="ua",
+ spec="Internal (not web-exposed)",
+)}
+
+<%helpers:single_keyword
+ name="position"
+ values="static absolute relative fixed ${'sticky' if engine in ['gecko', 'servo-2013'] else ''}"
+ engines="gecko servo-2013 servo-2020"
+ animation_value_type="discrete"
+ gecko_enum_prefix="StylePositionProperty"
+ spec="https://drafts.csswg.org/css-position/#position-property"
+ servo_restyle_damage="rebuild_and_reflow"
+>
+impl computed_value::T {
+ pub fn is_absolutely_positioned(self) -> bool {
+ matches!(self, Self::Absolute | Self::Fixed)
+ }
+ pub fn is_relative(self) -> bool {
+ self == Self::Relative
+ }
+}
+</%helpers:single_keyword>
+
+${helpers.predefined_type(
+ "float",
+ "Float",
+ "computed::Float::None",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ initial_specified_value="specified::Float::None",
+ spec="https://drafts.csswg.org/css-box/#propdef-float",
+ animation_value_type="discrete",
+ servo_restyle_damage="rebuild_and_reflow",
+ gecko_ffi_name="mFloat",
+)}
+
+${helpers.predefined_type(
+ "clear",
+ "Clear",
+ "computed::Clear::None",
+ engines="gecko servo-2013",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css2/#propdef-clear",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "vertical-align",
+ "VerticalAlign",
+ "computed::VerticalAlign::baseline()",
+ engines="gecko servo-2013",
+ animation_value_type="ComputedValue",
+ spec="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align",
+ servo_restyle_damage = "reflow",
+)}
+
+${helpers.predefined_type(
+ "baseline-source",
+ "BaselineSource",
+ "computed::BaselineSource::Auto",
+ engines="gecko servo-2013",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-inline-3/#baseline-source",
+ servo_restyle_damage = "reflow",
+)}
+
+// CSS 2.1, Section 11 - Visual effects
+
+${helpers.single_keyword(
+ "-servo-overflow-clip-box",
+ "padding-box content-box",
+ engines="servo-2013",
+ animation_value_type="none",
+ enabled_in="ua",
+ spec="Internal, not web-exposed, \
+ may be standardized in the future (https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box)",
+)}
+
+% for direction in ["inline", "block"]:
+ ${helpers.predefined_type(
+ "overflow-clip-box-" + direction,
+ "OverflowClipBox",
+ "computed::OverflowClipBox::PaddingBox",
+ engines="gecko",
+ enabled_in="ua",
+ gecko_pref="layout.css.overflow-clip-box.enabled",
+ animation_value_type="discrete",
+ spec="Internal, may be standardized in the future: \
+ https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box",
+ )}
+% endfor
+
+% for (axis, logical) in ALL_AXES:
+ <% full_name = "overflow-{}".format(axis) %>
+ ${helpers.predefined_type(
+ full_name,
+ "Overflow",
+ "computed::Overflow::Visible",
+ engines="gecko servo-2013 servo-2020",
+ logical_group="overflow",
+ logical=logical,
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-overflow-3/#propdef-{}".format(full_name),
+ servo_restyle_damage = "reflow",
+ gecko_pref="layout.css.overflow-logical.enabled" if logical else None,
+ )}
+% endfor
+
+${helpers.predefined_type(
+ "overflow-anchor",
+ "OverflowAnchor",
+ "computed::OverflowAnchor::Auto",
+ engines="gecko",
+ initial_specified_value="specified::OverflowAnchor::Auto",
+ gecko_pref="layout.css.scroll-anchoring.enabled",
+ spec="https://drafts.csswg.org/css-scroll-anchoring/#exclusion-api",
+ animation_value_type="discrete",
+)}
+
+<% transform_extra_prefixes = "moz:layout.css.prefixes.transforms webkit" %>
+
+${helpers.predefined_type(
+ "transform",
+ "Transform",
+ "generics::transform::Transform::none()",
+ engines="gecko servo-2013 servo-2020",
+ extra_prefixes=transform_extra_prefixes,
+ animation_value_type="ComputedValue",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ 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",
+ engines="gecko servo-2013",
+ animation_value_type="ComputedValue",
+ boxed=True,
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ gecko_pref="layout.css.individual-transform.enabled",
+ spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms",
+ servo_restyle_damage = "reflow_out_of_flow",
+)}
+
+${helpers.predefined_type(
+ "scale",
+ "Scale",
+ "generics::transform::Scale::None",
+ engines="gecko servo-2013",
+ animation_value_type="ComputedValue",
+ boxed=True,
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ gecko_pref="layout.css.individual-transform.enabled",
+ spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms",
+ servo_restyle_damage = "reflow_out_of_flow",
+)}
+
+${helpers.predefined_type(
+ "translate",
+ "Translate",
+ "generics::transform::Translate::None",
+ engines="gecko servo-2013",
+ animation_value_type="ComputedValue",
+ boxed=True,
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ gecko_pref="layout.css.individual-transform.enabled",
+ spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms",
+ servo_restyle_damage="reflow_out_of_flow",
+)}
+
+// Motion Path Module Level 1
+${helpers.predefined_type(
+ "offset-path",
+ "OffsetPath",
+ "computed::OffsetPath::none()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ gecko_pref="layout.css.motion-path.enabled",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ spec="https://drafts.fxtf.org/motion-1/#offset-path-property",
+ servo_restyle_damage="reflow_out_of_flow"
+)}
+
+// Motion Path Module Level 1
+${helpers.predefined_type(
+ "offset-distance",
+ "LengthPercentage",
+ "computed::LengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ gecko_pref="layout.css.motion-path.enabled",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ spec="https://drafts.fxtf.org/motion-1/#offset-distance-property",
+ servo_restyle_damage="reflow_out_of_flow"
+)}
+
+// Motion Path Module Level 1
+${helpers.predefined_type(
+ "offset-rotate",
+ "OffsetRotate",
+ "computed::OffsetRotate::auto()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ gecko_pref="layout.css.motion-path.enabled",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ spec="https://drafts.fxtf.org/motion-1/#offset-rotate-property",
+ servo_restyle_damage="reflow_out_of_flow"
+)}
+
+// Motion Path Module Level 1
+${helpers.predefined_type(
+ "offset-anchor",
+ "PositionOrAuto",
+ "computed::PositionOrAuto::auto()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ gecko_pref="layout.css.motion-path.enabled",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ spec="https://drafts.fxtf.org/motion-1/#offset-anchor-property",
+ servo_restyle_damage="reflow_out_of_flow",
+ boxed=True
+)}
+
+// Motion Path Module Level 1
+${helpers.predefined_type(
+ "offset-position",
+ "OffsetPosition",
+ "computed::OffsetPosition::auto()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ gecko_pref="layout.css.motion-path-offset-position.enabled",
+ spec="https://drafts.fxtf.org/motion-1/#offset-position-property",
+ servo_restyle_damage="reflow_out_of_flow",
+ boxed=True
+)}
+
+// CSSOM View Module
+// https://www.w3.org/TR/cssom-view-1/
+${helpers.single_keyword(
+ "scroll-behavior",
+ "auto smooth",
+ engines="gecko",
+ spec="https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior",
+ animation_value_type="discrete",
+ gecko_enum_prefix="StyleScrollBehavior",
+)}
+
+${helpers.predefined_type(
+ "scroll-snap-align",
+ "ScrollSnapAlign",
+ "computed::ScrollSnapAlign::none()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "scroll-snap-type",
+ "ScrollSnapType",
+ "computed::ScrollSnapType::none()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-type",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "scroll-snap-stop",
+ "ScrollSnapStop",
+ "computed::ScrollSnapStop::Normal",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-stop",
+ animation_value_type="discrete",
+)}
+
+% for (axis, logical) in ALL_AXES:
+ ${helpers.predefined_type(
+ "overscroll-behavior-" + axis,
+ "OverscrollBehavior",
+ "computed::OverscrollBehavior::Auto",
+ engines="gecko",
+ logical_group="overscroll-behavior",
+ logical=logical,
+ gecko_pref="layout.css.overscroll-behavior.enabled",
+ spec="https://wicg.github.io/overscroll-behavior/#overscroll-behavior-properties",
+ animation_value_type="discrete",
+ )}
+% endfor
+
+// Compositing and Blending Level 1
+// http://www.w3.org/TR/compositing-1/
+${helpers.single_keyword(
+ "isolation",
+ "auto isolate",
+ engines="gecko",
+ spec="https://drafts.fxtf.org/compositing/#isolation",
+ gecko_enum_prefix="StyleIsolation",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "break-after",
+ "BreakBetween",
+ "computed::BreakBetween::Auto",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-break/#propdef-break-after",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "break-before",
+ "BreakBetween",
+ "computed::BreakBetween::Auto",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-break/#propdef-break-before",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "break-inside",
+ "BreakWithin",
+ "computed::BreakWithin::Auto",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-break/#propdef-break-inside",
+ animation_value_type="discrete",
+)}
+
+// CSS Basic User Interface Module Level 3
+// http://dev.w3.org/csswg/css-ui
+${helpers.predefined_type(
+ "resize",
+ "Resize",
+ "computed::Resize::None",
+ engines="gecko",
+ animation_value_type="discrete",
+ gecko_ffi_name="mResize",
+ spec="https://drafts.csswg.org/css-ui/#propdef-resize",
+)}
+
+${helpers.predefined_type(
+ "perspective",
+ "Perspective",
+ "computed::Perspective::none()",
+ engines="gecko servo-2013 servo-2020",
+ gecko_ffi_name="mChildPerspective",
+ spec="https://drafts.csswg.org/css-transforms/#perspective",
+ extra_prefixes=transform_extra_prefixes,
+ animation_value_type="AnimatedPerspective",
+ servo_restyle_damage = "reflow_out_of_flow",
+)}
+
+${helpers.predefined_type(
+ "perspective-origin",
+ "Position",
+ "computed::position::Position::center()",
+ engines="gecko servo-2013 servo-2020",
+ boxed=True,
+ 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",
+ engines="gecko servo-2013 servo-2020",
+ gecko_enum_prefix="StyleBackfaceVisibility",
+ spec="https://drafts.csswg.org/css-transforms/#backface-visibility-property",
+ extra_prefixes=transform_extra_prefixes,
+ animation_value_type="discrete",
+)}
+
+${helpers.single_keyword(
+ "transform-box",
+ "border-box fill-box view-box",
+ engines="gecko",
+ gecko_enum_prefix="StyleGeometryBox",
+ spec="https://drafts.csswg.org/css-transforms/#transform-box",
+ gecko_inexhaustive="True",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "transform-style",
+ "TransformStyle",
+ "computed::TransformStyle::Flat",
+ engines="gecko servo-2013 servo-2020",
+ spec="https://drafts.csswg.org/css-transforms-2/#transform-style-property",
+ extra_prefixes=transform_extra_prefixes,
+ animation_value_type="discrete",
+ servo_restyle_damage = "reflow_out_of_flow",
+)}
+
+${helpers.predefined_type(
+ "transform-origin",
+ "TransformOrigin",
+ "computed::TransformOrigin::initial_value()",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="ComputedValue",
+ 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()",
+ engines="gecko",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-contain/#contain-property",
+)}
+
+${helpers.predefined_type(
+ "content-visibility",
+ "ContentVisibility",
+ "computed::ContentVisibility::Visible",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-contain/#content-visibility",
+ gecko_pref="layout.css.content-visibility.enabled",
+ animation_value_type="none",
+)}
+
+${helpers.predefined_type(
+ "container-type",
+ "ContainerType",
+ "computed::ContainerType::Normal",
+ engines="gecko",
+ animation_value_type="none",
+ enabled_in="ua",
+ gecko_pref="layout.css.container-queries.enabled",
+ spec="https://drafts.csswg.org/css-contain-3/#container-type",
+)}
+
+${helpers.predefined_type(
+ "container-name",
+ "ContainerName",
+ "computed::ContainerName::none()",
+ engines="gecko",
+ animation_value_type="none",
+ enabled_in="ua",
+ gecko_pref="layout.css.container-queries.enabled",
+ spec="https://drafts.csswg.org/css-contain-3/#container-name",
+)}
+
+${helpers.predefined_type(
+ "appearance",
+ "Appearance",
+ "computed::Appearance::None",
+ engines="gecko",
+ aliases="-moz-appearance -webkit-appearance",
+ spec="https://drafts.csswg.org/css-ui-4/#propdef-appearance",
+ animation_value_type="discrete",
+ gecko_ffi_name="mAppearance",
+)}
+
+// The inherent widget type of an element, selected by specifying
+// `appearance: auto`.
+${helpers.predefined_type(
+ "-moz-default-appearance",
+ "Appearance",
+ "computed::Appearance::None",
+ engines="gecko",
+ animation_value_type="none",
+ spec="Internal (not web-exposed)",
+ enabled_in="chrome",
+ gecko_ffi_name="mDefaultAppearance",
+)}
+
+${helpers.single_keyword(
+ "-moz-orient",
+ "inline block horizontal vertical",
+ engines="gecko",
+ gecko_ffi_name="mOrient",
+ gecko_enum_prefix="StyleOrient",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-orient)",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "will-change",
+ "WillChange",
+ "computed::WillChange::auto()",
+ engines="gecko",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-will-change/#will-change",
+)}
+
+// The spec issue for the parse_method: https://github.com/w3c/csswg-drafts/issues/4102.
+${helpers.predefined_type(
+ "shape-image-threshold",
+ "Opacity",
+ "0.0",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-shapes/#shape-image-threshold-property",
+)}
+
+${helpers.predefined_type(
+ "shape-margin",
+ "NonNegativeLengthPercentage",
+ "computed::NonNegativeLengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="NonNegativeLengthPercentage",
+ spec="https://drafts.csswg.org/css-shapes/#shape-margin-property",
+)}
+
+${helpers.predefined_type(
+ "shape-outside",
+ "basic_shape::ShapeOutside",
+ "generics::basic_shape::ShapeOutside::None",
+ engines="gecko",
+ animation_value_type="basic_shape::ShapeOutside",
+ spec="https://drafts.csswg.org/css-shapes/#shape-outside-property",
+)}
+
+${helpers.predefined_type(
+ "touch-action",
+ "TouchAction",
+ "computed::TouchAction::auto()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://compat.spec.whatwg.org/#touch-action",
+)}
+
+${helpers.predefined_type(
+ "-webkit-line-clamp",
+ "LineClamp",
+ "computed::LineClamp::none()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-overflow-3/#line-clamp",
+)}
+
+${helpers.predefined_type(
+ "scrollbar-gutter",
+ "ScrollbarGutter",
+ "computed::ScrollbarGutter::AUTO",
+ engines="gecko",
+ gecko_pref="layout.css.scrollbar-gutter.enabled",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-overflow-3/#scrollbar-gutter-property",
+)}
diff --git a/servo/components/style/properties/longhands/column.mako.rs b/servo/components/style/properties/longhands/column.mako.rs
new file mode 100644
index 0000000000..1e0e92b7f3
--- /dev/null
+++ b/servo/components/style/properties/longhands/column.mako.rs
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("Column", inherited=False) %>
+
+${helpers.predefined_type(
+ "column-width",
+ "length::NonNegativeLengthOrAuto",
+ "computed::length::NonNegativeLengthOrAuto::auto()",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ initial_specified_value="specified::length::NonNegativeLengthOrAuto::auto()",
+ animation_value_type="NonNegativeLengthOrAuto",
+ servo_2013_pref="layout.columns.enabled",
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-width",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "column-count",
+ "ColumnCount",
+ "computed::ColumnCount::auto()",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ initial_specified_value="specified::ColumnCount::auto()",
+ servo_2013_pref="layout.columns.enabled",
+ animation_value_type="AnimatedColumnCount",
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-count",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "column-fill",
+ "balance auto",
+ engines="gecko",
+ animation_value_type="discrete",
+ gecko_enum_prefix="StyleColumnFill",
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-fill",
+)}
+
+${helpers.predefined_type(
+ "column-rule-width",
+ "BorderSideWidth",
+ "app_units::Au::from_px(3)",
+ engines="gecko",
+ initial_specified_value="specified::BorderSideWidth::medium()",
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-width",
+ animation_value_type="NonNegativeLength",
+)}
+
+// https://drafts.csswg.org/css-multicol-1/#crc
+${helpers.predefined_type(
+ "column-rule-color",
+ "Color",
+ "computed_value::T::currentcolor()",
+ engines="gecko",
+ initial_specified_value="specified::Color::currentcolor()",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color",
+)}
+
+${helpers.single_keyword(
+ "column-span",
+ "none all",
+ engines="gecko",
+ animation_value_type="discrete",
+ gecko_enum_prefix="StyleColumnSpan",
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-span",
+)}
+
+${helpers.predefined_type(
+ "column-rule-style",
+ "BorderStyle",
+ "computed::BorderStyle::None",
+ engines="gecko",
+ initial_specified_value="specified::BorderStyle::None",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-style",
+)}
diff --git a/servo/components/style/properties/longhands/counters.mako.rs b/servo/components/style/properties/longhands/counters.mako.rs
new file mode 100644
index 0000000000..2ad0f72cd4
--- /dev/null
+++ b/servo/components/style/properties/longhands/counters.mako.rs
@@ -0,0 +1,48 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("Counters", inherited=False, gecko_name="Content") %>
+
+${helpers.predefined_type(
+ "content",
+ "Content",
+ "computed::Content::normal()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Content::normal()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-content/#propdef-content",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "counter-increment",
+ "CounterIncrement",
+ engines="gecko servo-2013",
+ initial_value="Default::default()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-lists/#propdef-counter-increment",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "counter-reset",
+ "CounterReset",
+ engines="gecko servo-2013",
+ initial_value="Default::default()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "counter-set",
+ "CounterSet",
+ engines="gecko",
+ initial_value="Default::default()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-set",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
diff --git a/servo/components/style/properties/longhands/effects.mako.rs b/servo/components/style/properties/longhands/effects.mako.rs
new file mode 100644
index 0000000000..1860f4b179
--- /dev/null
+++ b/servo/components/style/properties/longhands/effects.mako.rs
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+// Box-shadow, etc.
+<% data.new_style_struct("Effects", inherited=False) %>
+
+${helpers.predefined_type(
+ "opacity",
+ "Opacity",
+ "1.0",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="ComputedValue",
+ flags="CAN_ANIMATE_ON_COMPOSITOR",
+ spec="https://drafts.csswg.org/css-color/#transparency",
+ servo_restyle_damage = "reflow_out_of_flow",
+)}
+
+${helpers.predefined_type(
+ "box-shadow",
+ "BoxShadow",
+ None,
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ vector=True,
+ simple_vector_bindings=True,
+ animation_value_type="AnimatedBoxShadowList",
+ vector_animation_type="with_zero",
+ extra_prefixes="webkit",
+ ignored_when_colors_disabled=True,
+ spec="https://drafts.csswg.org/css-backgrounds/#box-shadow",
+)}
+
+${helpers.predefined_type(
+ "clip",
+ "ClipRectOrAuto",
+ "computed::ClipRectOrAuto::auto()",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="ComputedValue",
+ boxed=True,
+ allow_quirks="Yes",
+ spec="https://drafts.fxtf.org/css-masking/#clip-property",
+)}
+
+${helpers.predefined_type(
+ "filter",
+ "Filter",
+ None,
+ engines="gecko servo-2013 servo-2020",
+ vector=True,
+ simple_vector_bindings=True,
+ gecko_ffi_name="mFilters",
+ separator="Space",
+ animation_value_type="AnimatedFilterList",
+ vector_animation_type="with_zero",
+ extra_prefixes="webkit",
+ spec="https://drafts.fxtf.org/filters/#propdef-filter",
+)}
+
+${helpers.predefined_type(
+ "backdrop-filter",
+ "Filter",
+ None,
+ engines="gecko",
+ vector=True,
+ simple_vector_bindings=True,
+ gecko_ffi_name="mBackdropFilters",
+ separator="Space",
+ animation_value_type="AnimatedFilterList",
+ vector_animation_type="with_zero",
+ gecko_pref="layout.css.backdrop-filter.enabled",
+ spec="https://drafts.fxtf.org/filter-effects-2/#propdef-backdrop-filter",
+)}
+
+${helpers.single_keyword(
+ "mix-blend-mode",
+ """normal multiply screen overlay darken lighten color-dodge
+ color-burn hard-light soft-light difference exclusion hue
+ saturation color luminosity plus-lighter""",
+ engines="gecko servo-2013 servo-2020",
+ gecko_enum_prefix="StyleBlend",
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode",
+)}
diff --git a/servo/components/style/properties/longhands/font.mako.rs b/servo/components/style/properties/longhands/font.mako.rs
new file mode 100644
index 0000000000..3f975aa198
--- /dev/null
+++ b/servo/components/style/properties/longhands/font.mako.rs
@@ -0,0 +1,488 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import Method, to_camel_case, to_rust_ident, to_camel_case_lower, SYSTEM_FONT_LONGHANDS %>
+
+<% data.new_style_struct("Font", inherited=True) %>
+
+${helpers.predefined_type(
+ "font-family",
+ "FontFamily",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::FontFamily::serif()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-family",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "font-style",
+ "FontStyle",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::FontStyle::normal()",
+ initial_specified_value="specified::FontStyle::normal()",
+ animation_value_type="FontStyle",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-style",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+<% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS",
+ "all-small-caps": "ALLSMALL",
+ "petite-caps": "PETITECAPS",
+ "all-petite-caps": "ALLPETITE",
+ "titling-caps": "TITLING" } %>
+
+${helpers.single_keyword(
+ "font-variant-caps",
+ "normal small-caps",
+ engines="gecko servo-2013 servo-2020",
+ extra_gecko_values="all-small-caps petite-caps all-petite-caps unicase titling-caps",
+ gecko_constant_prefix="NS_FONT_VARIANT_CAPS",
+ gecko_ffi_name="mFont.variantCaps",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps",
+ custom_consts=font_variant_caps_custom_consts,
+ animation_value_type="discrete",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "font-weight",
+ "FontWeight",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::FontWeight::normal()",
+ initial_specified_value="specified::FontWeight::normal()",
+ animation_value_type="Number",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "font-size",
+ "FontSize",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::FontSize::medium()",
+ initial_specified_value="specified::FontSize::medium()",
+ animation_value_type="NonNegativeLength",
+ allow_quirks="Yes",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-size",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "font-size-adjust",
+ "FontSizeAdjust",
+ engines="gecko",
+ initial_value="computed::FontSizeAdjust::None",
+ initial_specified_value="specified::FontSizeAdjust::None",
+ animation_value_type="FontSizeAdjust",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust",
+)}
+
+${helpers.predefined_type(
+ "font-synthesis-weight",
+ "FontSynthesis",
+ engines="gecko",
+ initial_value="computed::FontSynthesis::Auto",
+ initial_specified_value="specified::FontSynthesis::Auto",
+ gecko_ffi_name="mFont.synthesisWeight",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-weight",
+)}
+
+${helpers.predefined_type(
+ "font-synthesis-style",
+ "FontSynthesis",
+ engines="gecko",
+ initial_value="computed::FontSynthesis::Auto",
+ initial_specified_value="specified::FontSynthesis::Auto",
+ gecko_ffi_name="mFont.synthesisStyle",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-style",
+)}
+
+${helpers.predefined_type(
+ "font-synthesis-small-caps",
+ "FontSynthesis",
+ engines="gecko",
+ initial_value="computed::FontSynthesis::Auto",
+ initial_specified_value="specified::FontSynthesis::Auto",
+ gecko_ffi_name="mFont.synthesisSmallCaps",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-small-caps",
+)}
+
+${helpers.predefined_type(
+ "font-stretch",
+ "FontStretch",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::FontStretch::hundred()",
+ initial_specified_value="specified::FontStretch::normal()",
+ animation_value_type="Percentage",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "font-kerning",
+ "auto none normal",
+ engines="gecko",
+ gecko_ffi_name="mFont.kerning",
+ gecko_constant_prefix="NS_FONT_KERNING",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-kerning",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "font-variant-alternates",
+ "FontVariantAlternates",
+ engines="gecko",
+ initial_value="computed::FontVariantAlternates::default()",
+ initial_specified_value="specified::FontVariantAlternates::default()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates",
+)}
+
+${helpers.predefined_type(
+ "font-variant-east-asian",
+ "FontVariantEastAsian",
+ engines="gecko",
+ initial_value="computed::FontVariantEastAsian::empty()",
+ initial_specified_value="specified::FontVariantEastAsian::empty()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian",
+)}
+
+${helpers.single_keyword(
+ "font-variant-emoji",
+ "normal text emoji unicode",
+ engines="gecko",
+ gecko_pref="layout.css.font-variant-emoji.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ gecko_enum_prefix="StyleFontVariantEmoji",
+ gecko_ffi_name="mFont.variantEmoji",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-emoji",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "font-variant-ligatures",
+ "FontVariantLigatures",
+ engines="gecko",
+ initial_value="computed::FontVariantLigatures::empty()",
+ initial_specified_value="specified::FontVariantLigatures::empty()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures",
+)}
+
+${helpers.predefined_type(
+ "font-variant-numeric",
+ "FontVariantNumeric",
+ engines="gecko",
+ initial_value="computed::FontVariantNumeric::empty()",
+ initial_specified_value="specified::FontVariantNumeric::empty()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric",
+)}
+
+${helpers.single_keyword(
+ "font-variant-position",
+ "normal sub super",
+ engines="gecko",
+ gecko_ffi_name="mFont.variantPosition",
+ gecko_constant_prefix="NS_FONT_VARIANT_POSITION",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "font-feature-settings",
+ "FontFeatureSettings",
+ engines="gecko",
+ initial_value="computed::FontFeatureSettings::normal()",
+ initial_specified_value="specified::FontFeatureSettings::normal()",
+ extra_prefixes="moz:layout.css.prefixes.font-features",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings",
+)}
+
+${helpers.predefined_type(
+ "font-variation-settings",
+ "FontVariationSettings",
+ engines="gecko",
+ gecko_pref="layout.css.font-variations.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ initial_value="computed::FontVariationSettings::normal()",
+ initial_specified_value="specified::FontVariationSettings::normal()",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-fonts-4/#propdef-font-variation-settings"
+)}
+
+${helpers.predefined_type(
+ "font-language-override",
+ "FontLanguageOverride",
+ engines="gecko",
+ initial_value="computed::FontLanguageOverride::normal()",
+ initial_specified_value="specified::FontLanguageOverride::normal()",
+ animation_value_type="discrete",
+ extra_prefixes="moz:layout.css.prefixes.font-features",
+ spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override",
+)}
+
+${helpers.single_keyword(
+ "font-optical-sizing",
+ "auto none",
+ engines="gecko",
+ gecko_pref="layout.css.font-variations.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ gecko_ffi_name="mFont.opticalSizing",
+ gecko_constant_prefix="NS_FONT_OPTICAL_SIZING",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/css-fonts-4/#font-optical-sizing-def",
+)}
+
+${helpers.predefined_type(
+ "font-palette",
+ "FontPalette",
+ engines="gecko",
+ initial_value="computed::FontPalette::normal()",
+ initial_specified_value="specified::FontPalette::normal()",
+ animation_value_type="discrete",
+ gecko_pref="layout.css.font-palette.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ spec="https://drafts.csswg.org/css-fonts/#font-palette-prop",
+)}
+
+${helpers.predefined_type(
+ "-x-lang",
+ "XLang",
+ engines="gecko",
+ initial_value="computed::XLang::get_initial_value()",
+ animation_value_type="none",
+ enabled_in="",
+ has_effect_on_gecko_scrollbars=False,
+ spec="Internal (not web-exposed)",
+)}
+
+${helpers.predefined_type(
+ "-moz-script-size-multiplier",
+ "MozScriptSizeMultiplier",
+ engines="gecko",
+ initial_value="computed::MozScriptSizeMultiplier::get_initial_value()",
+ animation_value_type="none",
+ gecko_ffi_name="mScriptSizeMultiplier",
+ enabled_in="",
+ has_effect_on_gecko_scrollbars=False,
+ spec="Internal (not web-exposed)",
+)}
+
+${helpers.predefined_type(
+ "math-depth",
+ "MathDepth",
+ "0",
+ engines="gecko",
+ gecko_pref="layout.css.math-depth.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ animation_value_type="none",
+ enabled_in="ua",
+ spec="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property",
+)}
+
+${helpers.single_keyword(
+ "math-style",
+ "normal compact",
+ engines="gecko",
+ gecko_enum_prefix="StyleMathStyle",
+ gecko_pref="layout.css.math-style.enabled",
+ spec="https://mathml-refresh.github.io/mathml-core/#the-math-style-property",
+ has_effect_on_gecko_scrollbars=False,
+ animation_value_type="none",
+ enabled_in="ua",
+ needs_conversion=True,
+)}
+
+${helpers.single_keyword(
+ "-moz-math-variant",
+ """none normal bold italic bold-italic script bold-script
+ fraktur double-struck bold-fraktur sans-serif
+ bold-sans-serif sans-serif-italic sans-serif-bold-italic
+ monospace initial tailed looped stretched""",
+ engines="gecko",
+ gecko_enum_prefix="StyleMathVariant",
+ gecko_ffi_name="mMathVariant",
+ spec="Internal (not web-exposed)",
+ animation_value_type="none",
+ enabled_in="",
+ has_effect_on_gecko_scrollbars=False,
+ needs_conversion=True,
+)}
+
+${helpers.predefined_type(
+ "-moz-script-min-size",
+ "MozScriptMinSize",
+ "specified::MozScriptMinSize::get_initial_value()",
+ engines="gecko",
+ animation_value_type="none",
+ enabled_in="",
+ has_effect_on_gecko_scrollbars=False,
+ gecko_ffi_name="mScriptMinSize",
+ spec="Internal (not web-exposed)",
+)}
+
+${helpers.predefined_type(
+ "-x-text-scale",
+ "XTextScale",
+ "computed::XTextScale::All",
+ engines="gecko",
+ animation_value_type="none",
+ enabled_in="",
+ has_effect_on_gecko_scrollbars=False,
+ spec="Internal (not web-exposed)",
+)}
+
+% if engine == "gecko":
+pub mod system_font {
+ //! We deal with system fonts here
+ //!
+ //! System fonts can only be set as a group via the font shorthand.
+ //! They resolve at compute time (not parse time -- this lets the
+ //! browser respond to changes to the OS font settings).
+ //!
+ //! While Gecko handles these as a separate property and keyword
+ //! values on each property indicating that the font should be picked
+ //! from the -x-system-font property, we avoid this. Instead,
+ //! each font longhand has a special SystemFont variant which contains
+ //! the specified system font. When the cascade function (in helpers)
+ //! detects that a value has a system font, it will resolve it, and
+ //! cache it on the ComputedValues. After this, it can be just fetched
+ //! whenever a font longhand on the same element needs the system font.
+ //!
+ //! When a longhand property is holding a SystemFont, it's serialized
+ //! to an empty string as if its value comes from a shorthand with
+ //! variable reference. We may want to improve this behavior at some
+ //! point. See also https://github.com/w3c/csswg-drafts/issues/1586.
+
+ use crate::properties::longhands;
+ use std::hash::{Hash, Hasher};
+ use crate::values::computed::{ToComputedValue, Context};
+ use crate::values::specified::font::SystemFont;
+ // ComputedValues are compared at times
+ // so we need these impls. We don't want to
+ // add Eq to Number (which contains a float)
+ // so instead we have an eq impl which skips the
+ // cached values
+ impl PartialEq for ComputedSystemFont {
+ fn eq(&self, other: &Self) -> bool {
+ self.system_font == other.system_font
+ }
+ }
+ impl Eq for ComputedSystemFont {}
+
+ impl Hash for ComputedSystemFont {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.system_font.hash(hasher)
+ }
+ }
+
+ impl ToComputedValue for SystemFont {
+ type ComputedValue = ComputedSystemFont;
+
+ fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
+ use crate::gecko_bindings::bindings;
+ use crate::gecko_bindings::structs::nsFont;
+ use crate::values::computed::font::FontSize;
+ use crate::values::specified::font::KeywordInfo;
+ use crate::values::generics::NonNegative;
+ use std::mem;
+
+ let mut system = mem::MaybeUninit::<nsFont>::uninit();
+ let system = unsafe {
+ bindings::Gecko_nsFont_InitSystem(
+ system.as_mut_ptr(),
+ *self,
+ &**cx.style().get_font(),
+ cx.device().document()
+ );
+ &mut *system.as_mut_ptr()
+ };
+ let size = NonNegative(cx.maybe_zoom_text(system.size.0));
+ let ret = ComputedSystemFont {
+ font_family: system.family.clone(),
+ font_size: FontSize {
+ computed_size: size,
+ used_size: size,
+ keyword_info: KeywordInfo::none()
+ },
+ font_weight: system.weight,
+ font_stretch: system.stretch,
+ font_style: system.style,
+ system_font: *self,
+ };
+ unsafe { bindings::Gecko_nsFont_Destroy(system); }
+ ret
+ }
+
+ fn from_computed_value(_: &ComputedSystemFont) -> Self {
+ unreachable!()
+ }
+ }
+
+ #[inline]
+ /// Compute and cache a system font
+ ///
+ /// Must be called before attempting to compute a system font
+ /// specified value
+ pub fn resolve_system_font(system: SystemFont, context: &mut Context) {
+ // Checking if context.cached_system_font.is_none() isn't enough,
+ // if animating from one system font to another the cached system font
+ // may change
+ if Some(system) != context.cached_system_font.as_ref().map(|x| x.system_font) {
+ let computed = system.to_computed_value(context);
+ context.cached_system_font = Some(computed);
+ }
+ }
+
+ #[derive(Clone, Debug)]
+ pub struct ComputedSystemFont {
+ % for name in SYSTEM_FONT_LONGHANDS:
+ pub ${name}: longhands::${name}::computed_value::T,
+ % endfor
+ pub system_font: SystemFont,
+ }
+
+}
+% endif
+
+${helpers.single_keyword(
+ "-moz-osx-font-smoothing",
+ "auto grayscale",
+ engines="gecko",
+ gecko_constant_prefix="NS_FONT_SMOOTHING",
+ gecko_ffi_name="mFont.smoothing",
+ gecko_pref="layout.css.osx-font-smoothing.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "-moz-font-smoothing-background-color",
+ "color::MozFontSmoothingBackgroundColor",
+ "computed::color::MozFontSmoothingBackgroundColor::transparent()",
+ engines="gecko",
+ animation_value_type="none",
+ gecko_ffi_name="mFont.fontSmoothingBackgroundColor",
+ enabled_in="chrome",
+ spec="None (Nonstandard internal property)",
+)}
+
+${helpers.predefined_type(
+ "-moz-min-font-size-ratio",
+ "Percentage",
+ "computed::Percentage::hundred()",
+ engines="gecko",
+ animation_value_type="none",
+ enabled_in="ua",
+ spec="Nonstandard (Internal-only)",
+)}
diff --git a/servo/components/style/properties/longhands/inherited_box.mako.rs b/servo/components/style/properties/longhands/inherited_box.mako.rs
new file mode 100644
index 0000000000..0b41a76ea6
--- /dev/null
+++ b/servo/components/style/properties/longhands/inherited_box.mako.rs
@@ -0,0 +1,97 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("InheritedBox", inherited=True, gecko_name="Visibility") %>
+
+// TODO: collapse. Well, do tables first.
+${helpers.single_keyword(
+ "visibility",
+ "visible hidden collapse",
+ engines="gecko servo-2013 servo-2020",
+ gecko_ffi_name="mVisible",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-box/#propdef-visibility",
+ gecko_enum_prefix="StyleVisibility",
+)}
+
+// CSS Writing Modes Level 3
+// https://drafts.csswg.org/css-writing-modes-3
+${helpers.single_keyword(
+ "writing-mode",
+ "horizontal-tb vertical-rl vertical-lr",
+ engines="gecko servo-2013 servo-2020",
+ extra_gecko_values="sideways-rl sideways-lr",
+ gecko_aliases="lr=horizontal-tb lr-tb=horizontal-tb \
+ rl=horizontal-tb rl-tb=horizontal-tb \
+ tb=vertical-rl tb-rl=vertical-rl",
+ servo_2013_pref="layout.writing-mode.enabled",
+ servo_2020_pref="layout.writing-mode.enabled",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode",
+ gecko_enum_prefix="StyleWritingModeProperty",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "direction",
+ "ltr rtl",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
+ gecko_enum_prefix="StyleDirection",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "-moz-box-collapse",
+ "flex legacy",
+ engines="gecko",
+ gecko_enum_prefix="StyleMozBoxCollapse",
+ animation_value_type="none",
+ enabled_in="chrome",
+ spec="None (internal)",
+)}
+
+${helpers.single_keyword(
+ "text-orientation",
+ "mixed upright sideways",
+ engines="gecko",
+ gecko_aliases="sideways-right=sideways",
+ gecko_enum_prefix="StyleTextOrientation",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-writing-modes/#propdef-text-orientation",
+)}
+
+${helpers.predefined_type(
+ "print-color-adjust",
+ "PrintColorAdjust",
+ "computed::PrintColorAdjust::Economy",
+ engines="gecko",
+ aliases="color-adjust",
+ spec="https://drafts.csswg.org/css-color-adjust/#print-color-adjust",
+ animation_value_type="discrete",
+)}
+
+// According to to CSS-IMAGES-3, `optimizespeed` and `optimizequality` are synonyms for `auto`
+// And, firefox doesn't support `pixelated` yet (https://bugzilla.mozilla.org/show_bug.cgi?id=856337)
+${helpers.predefined_type(
+ "image-rendering",
+ "ImageRendering",
+ "computed::ImageRendering::Auto",
+ engines="gecko servo-2013 servo-2020",
+ spec="https://drafts.csswg.org/css-images/#propdef-image-rendering",
+ animation_value_type="discrete",
+)}
+
+${helpers.single_keyword(
+ "image-orientation",
+ "from-image none",
+ engines="gecko",
+ gecko_enum_prefix="StyleImageOrientation",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-images/#propdef-image-orientation",
+)}
diff --git a/servo/components/style/properties/longhands/inherited_svg.mako.rs b/servo/components/style/properties/longhands/inherited_svg.mako.rs
new file mode 100644
index 0000000000..b9d55c01b2
--- /dev/null
+++ b/servo/components/style/properties/longhands/inherited_svg.mako.rs
@@ -0,0 +1,217 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+// SVG 1.1 (Second Edition)
+// https://www.w3.org/TR/SVG/
+<% data.new_style_struct("InheritedSVG", inherited=True, gecko_name="SVG") %>
+
+// Section 10 - Text
+
+${helpers.single_keyword(
+ "dominant-baseline",
+ """auto ideographic alphabetic hanging mathematical central middle
+ text-after-edge text-before-edge""",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/css-inline-3/#propdef-dominant-baseline",
+ gecko_enum_prefix="StyleDominantBaseline",
+)}
+
+${helpers.single_keyword(
+ "text-anchor",
+ "start middle end",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG/text.html#TextAnchorProperty",
+ gecko_enum_prefix="StyleTextAnchor",
+)}
+
+// Section 11 - Painting: Filling, Stroking and Marker Symbols
+${helpers.single_keyword(
+ "color-interpolation",
+ "srgb auto linearrgb",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperty",
+ gecko_enum_prefix="StyleColorInterpolation",
+)}
+
+${helpers.single_keyword(
+ "color-interpolation-filters",
+ "linearrgb auto srgb",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty",
+ gecko_enum_prefix="StyleColorInterpolation",
+)}
+
+${helpers.predefined_type(
+ "fill",
+ "SVGPaint",
+ "crate::values::computed::SVGPaint::black()",
+ engines="gecko",
+ animation_value_type="IntermediateSVGPaint",
+ boxed=True,
+ spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint",
+)}
+
+${helpers.predefined_type(
+ "fill-opacity",
+ "SVGOpacity",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/painting.html#FillOpacity",
+)}
+
+${helpers.predefined_type(
+ "fill-rule",
+ "FillRule",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#FillRuleProperty",
+)}
+
+${helpers.single_keyword(
+ "shape-rendering",
+ "auto optimizespeed crispedges geometricprecision",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty",
+ gecko_enum_prefix = "StyleShapeRendering",
+)}
+
+${helpers.predefined_type(
+ "stroke",
+ "SVGPaint",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="IntermediateSVGPaint",
+ boxed=True,
+ spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint",
+)}
+
+${helpers.predefined_type(
+ "stroke-width",
+ "SVGWidth",
+ "computed::SVGWidth::one()",
+ engines="gecko",
+ animation_value_type="crate::values::computed::SVGWidth",
+ spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth",
+)}
+
+${helpers.single_keyword(
+ "stroke-linecap",
+ "butt round square",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty",
+ gecko_enum_prefix = "StyleStrokeLinecap",
+)}
+
+${helpers.single_keyword(
+ "stroke-linejoin",
+ "miter round bevel",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinejoinProperty",
+ gecko_enum_prefix = "StyleStrokeLinejoin",
+)}
+
+${helpers.predefined_type(
+ "stroke-miterlimit",
+ "NonNegativeNumber",
+ "From::from(4.0)",
+ engines="gecko",
+ animation_value_type="crate::values::computed::NonNegativeNumber",
+ spec="https://www.w3.org/TR/SVG2/painting.html#StrokeMiterlimitProperty",
+)}
+
+${helpers.predefined_type(
+ "stroke-opacity",
+ "SVGOpacity",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/painting.html#StrokeOpacity",
+)}
+
+${helpers.predefined_type(
+ "stroke-dasharray",
+ "SVGStrokeDashArray",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="crate::values::computed::SVGStrokeDashArray",
+ spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing",
+)}
+
+${helpers.predefined_type(
+ "stroke-dashoffset",
+ "SVGLength",
+ "computed::SVGLength::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing",
+)}
+
+// Section 14 - Clipping, Masking and Compositing
+${helpers.predefined_type(
+ "clip-rule",
+ "FillRule",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty",
+)}
+
+${helpers.predefined_type(
+ "marker-start",
+ "url::UrlOrNone",
+ "computed::url::UrlOrNone::none()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties",
+)}
+
+${helpers.predefined_type(
+ "marker-mid",
+ "url::UrlOrNone",
+ "computed::url::UrlOrNone::none()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties",
+)}
+
+${helpers.predefined_type(
+ "marker-end",
+ "url::UrlOrNone",
+ "computed::url::UrlOrNone::none()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties",
+)}
+
+${helpers.predefined_type(
+ "paint-order",
+ "SVGPaintOrder",
+ "computed::SVGPaintOrder::normal()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder",
+)}
+
+${helpers.predefined_type(
+ "-moz-context-properties",
+ "MozContextProperties",
+ "computed::MozContextProperties::default()",
+ engines="gecko",
+ enabled_in="chrome",
+ gecko_pref="svg.context-properties.content.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ animation_value_type="none",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties)",
+)}
diff --git a/servo/components/style/properties/longhands/inherited_table.mako.rs b/servo/components/style/properties/longhands/inherited_table.mako.rs
new file mode 100644
index 0000000000..b38df2423a
--- /dev/null
+++ b/servo/components/style/properties/longhands/inherited_table.mako.rs
@@ -0,0 +1,49 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("InheritedTable", inherited=True, gecko_name="TableBorder") %>
+
+${helpers.single_keyword(
+ "border-collapse",
+ "separate collapse",
+ engines="gecko servo-2013",
+ gecko_enum_prefix="StyleBorderCollapse",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-tables/#propdef-border-collapse",
+ servo_restyle_damage = "reflow",
+)}
+
+${helpers.single_keyword(
+ "empty-cells",
+ "show hide",
+ engines="gecko servo-2013",
+ gecko_enum_prefix="StyleEmptyCells",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-tables/#propdef-empty-cells",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "caption-side",
+ "table::CaptionSide",
+ "computed::table::CaptionSide::Top",
+ engines="gecko servo-2013",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-tables/#propdef-caption-side",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "border-spacing",
+ "BorderSpacing",
+ "computed::BorderSpacing::zero()",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ animation_value_type="BorderSpacing",
+ boxed=True,
+ spec="https://drafts.csswg.org/css-tables/#propdef-border-spacing",
+ servo_restyle_damage="reflow",
+)}
diff --git a/servo/components/style/properties/longhands/inherited_text.mako.rs b/servo/components/style/properties/longhands/inherited_text.mako.rs
new file mode 100644
index 0000000000..c1b110c086
--- /dev/null
+++ b/servo/components/style/properties/longhands/inherited_text.mako.rs
@@ -0,0 +1,408 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import Keyword %>
+<% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
+
+${helpers.predefined_type(
+ "color",
+ "ColorPropertyValue",
+ "crate::color::AbsoluteColor::black()",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="AbsoluteColor",
+ ignored_when_colors_disabled="True",
+ spec="https://drafts.csswg.org/css-color/#color",
+)}
+
+${helpers.predefined_type(
+ "line-height",
+ "LineHeight",
+ "computed::LineHeight::normal()",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="LineHeight",
+ spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height",
+ servo_restyle_damage="reflow"
+)}
+
+// CSS Text Module Level 3
+
+${helpers.predefined_type(
+ "text-transform",
+ "TextTransform",
+ "computed::TextTransform::none()",
+ engines="gecko servo-2013",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#propdef-text-transform",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "hyphens",
+ "manual none auto",
+ engines="gecko",
+ gecko_enum_prefix="StyleHyphens",
+ animation_value_type="discrete",
+ extra_prefixes="moz",
+ spec="https://drafts.csswg.org/css-text/#propdef-hyphens",
+)}
+
+// TODO: Support <percentage>
+${helpers.single_keyword(
+ "-moz-text-size-adjust",
+ "auto none",
+ engines="gecko",
+ gecko_enum_prefix="StyleTextSizeAdjust",
+ gecko_ffi_name="mTextSizeAdjust",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-size-adjust/#adjustment-control",
+ aliases="-webkit-text-size-adjust",
+)}
+
+${helpers.predefined_type(
+ "text-indent",
+ "LengthPercentage",
+ "computed::LengthPercentage::zero()",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-text/#propdef-text-indent",
+ allow_quirks="Yes",
+ servo_restyle_damage = "reflow",
+)}
+
+// Also known as "word-wrap" (which is more popular because of IE), but this is
+// the preferred name per CSS-TEXT 6.2.
+${helpers.predefined_type(
+ "overflow-wrap",
+ "OverflowWrap",
+ "computed::OverflowWrap::Normal",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#propdef-overflow-wrap",
+ aliases="word-wrap",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "word-break",
+ "WordBreak",
+ "computed::WordBreak::Normal",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#propdef-word-break",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "text-justify",
+ "TextJustify",
+ "computed::TextJustify::Auto",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#propdef-text-justify",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "text-align-last",
+ "TextAlignLast",
+ "computed::text::TextAlignLast::Auto",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#propdef-text-align-last",
+)}
+
+// TODO make this a shorthand and implement text-align-last/text-align-all
+${helpers.predefined_type(
+ "text-align",
+ "TextAlign",
+ "computed::TextAlign::Start",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#propdef-text-align",
+ servo_restyle_damage = "reflow",
+)}
+
+${helpers.predefined_type(
+ "letter-spacing",
+ "LetterSpacing",
+ "computed::LetterSpacing::normal()",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-text/#propdef-letter-spacing",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "word-spacing",
+ "WordSpacing",
+ "computed::WordSpacing::zero()",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-text/#propdef-word-spacing",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+<%helpers:single_keyword
+ name="white-space"
+ values="normal pre nowrap pre-wrap pre-line"
+ engines="gecko servo-2013 servo-2020",
+ extra_gecko_values="break-spaces -moz-pre-space"
+ gecko_enum_prefix="StyleWhiteSpace"
+ needs_conversion="True"
+ animation_value_type="discrete"
+ spec="https://drafts.csswg.org/css-text/#propdef-white-space"
+ servo_restyle_damage="rebuild_and_reflow"
+>
+ % if engine in ["servo-2013", "servo-2020"]:
+ impl SpecifiedValue {
+ pub fn allow_wrap(&self) -> bool {
+ match *self {
+ SpecifiedValue::Nowrap |
+ SpecifiedValue::Pre => false,
+ SpecifiedValue::Normal |
+ SpecifiedValue::PreWrap |
+ SpecifiedValue::PreLine => true,
+ }
+ }
+
+ pub fn preserve_newlines(&self) -> bool {
+ match *self {
+ SpecifiedValue::Normal |
+ SpecifiedValue::Nowrap => false,
+ SpecifiedValue::Pre |
+ SpecifiedValue::PreWrap |
+ SpecifiedValue::PreLine => true,
+ }
+ }
+
+ pub fn preserve_spaces(&self) -> bool {
+ match *self {
+ SpecifiedValue::Normal |
+ SpecifiedValue::Nowrap |
+ SpecifiedValue::PreLine => false,
+ SpecifiedValue::Pre |
+ SpecifiedValue::PreWrap => true,
+ }
+ }
+ }
+ % endif
+</%helpers:single_keyword>
+
+${helpers.predefined_type(
+ "text-shadow",
+ "SimpleShadow",
+ None,
+ engines="gecko servo-2013",
+ vector=True,
+ vector_animation_type="with_zero",
+ animation_value_type="AnimatedTextShadowList",
+ ignored_when_colors_disabled=True,
+ simple_vector_bindings=True,
+ spec="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property",
+)}
+
+${helpers.predefined_type(
+ "text-emphasis-style",
+ "TextEmphasisStyle",
+ "computed::TextEmphasisStyle::None",
+ engines="gecko",
+ initial_specified_value="SpecifiedValue::None",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-style",
+)}
+
+${helpers.predefined_type(
+ "text-emphasis-position",
+ "TextEmphasisPosition",
+ "computed::TextEmphasisPosition::OVER",
+ engines="gecko",
+ initial_specified_value="specified::TextEmphasisPosition::OVER",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-position",
+)}
+
+${helpers.predefined_type(
+ "text-emphasis-color",
+ "Color",
+ "computed_value::T::currentcolor()",
+ engines="gecko",
+ initial_specified_value="specified::Color::currentcolor()",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-color",
+)}
+
+${helpers.predefined_type(
+ "tab-size",
+ "NonNegativeLengthOrNumber",
+ "generics::length::LengthOrNumber::Number(From::from(8.0))",
+ engines="gecko",
+ animation_value_type="LengthOrNumber",
+ spec="https://drafts.csswg.org/css-text-3/#tab-size-property",
+ aliases="-moz-tab-size",
+)}
+
+${helpers.predefined_type(
+ "line-break",
+ "LineBreak",
+ "computed::LineBreak::Auto",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-3/#line-break-property",
+)}
+
+// CSS Compatibility
+// https://compat.spec.whatwg.org
+${helpers.predefined_type(
+ "-webkit-text-fill-color",
+ "Color",
+ "computed_value::T::currentcolor()",
+ engines="gecko",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ spec="https://compat.spec.whatwg.org/#the-webkit-text-fill-color",
+)}
+
+${helpers.predefined_type(
+ "-webkit-text-stroke-color",
+ "Color",
+ "computed_value::T::currentcolor()",
+ initial_specified_value="specified::Color::currentcolor()",
+ engines="gecko",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke-color",
+)}
+
+${helpers.predefined_type(
+ "-webkit-text-stroke-width",
+ "LineWidth",
+ "app_units::Au(0)",
+ engines="gecko",
+ initial_specified_value="specified::LineWidth::zero()",
+ spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke-width",
+ animation_value_type="discrete",
+)}
+
+// CSS Ruby Layout Module Level 1
+// https://drafts.csswg.org/css-ruby/
+${helpers.single_keyword(
+ "ruby-align",
+ "space-around start center space-between",
+ engines="gecko",
+ animation_value_type="discrete",
+ gecko_enum_prefix="StyleRubyAlign",
+ spec="https://drafts.csswg.org/css-ruby/#ruby-align-property",
+)}
+
+${helpers.predefined_type(
+ "ruby-position",
+ "RubyPosition",
+ "computed::RubyPosition::AlternateOver",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-ruby/#ruby-position-property",
+ animation_value_type="discrete",
+)}
+
+// CSS Writing Modes Module Level 3
+// https://drafts.csswg.org/css-writing-modes-3/
+
+${helpers.single_keyword(
+ "text-combine-upright",
+ "none all",
+ engines="gecko",
+ gecko_enum_prefix="StyleTextCombineUpright",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-writing-modes-3/#text-combine-upright",
+)}
+
+// SVG 1.1: Section 11 - Painting: Filling, Stroking and Marker Symbols
+${helpers.single_keyword(
+ "text-rendering",
+ "auto optimizespeed optimizelegibility geometricprecision",
+ engines="gecko servo-2013 servo-2020",
+ gecko_enum_prefix="StyleTextRendering",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVG11/painting.html#TextRenderingProperty",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "-moz-control-character-visibility",
+ "text::MozControlCharacterVisibility",
+ "Default::default()",
+ engines="gecko",
+ enabled_in="chrome",
+ gecko_pref="layout.css.moz-control-character-visibility.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ animation_value_type="none",
+ spec="Nonstandard"
+)}
+
+// text underline offset
+${helpers.predefined_type(
+ "text-underline-offset",
+ "LengthPercentageOrAuto",
+ "computed::LengthPercentageOrAuto::auto()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-text-decor-4/#underline-offset",
+)}
+
+// text underline position
+${helpers.predefined_type(
+ "text-underline-position",
+ "TextUnderlinePosition",
+ "computed::TextUnderlinePosition::AUTO",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-decor-3/#text-underline-position-property",
+)}
+
+// text decoration skip ink
+${helpers.predefined_type(
+ "text-decoration-skip-ink",
+ "TextDecorationSkipInk",
+ "computed::TextDecorationSkipInk::Auto",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-decor-4/#text-decoration-skip-ink-property",
+)}
+
+// hyphenation character
+${helpers.predefined_type(
+ "hyphenate-character",
+ "HyphenateCharacter",
+ "computed::HyphenateCharacter::Auto",
+ engines="gecko",
+ gecko_pref="layout.css.hyphenate-character.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/css-text-4/#hyphenate-character",
+)}
+
+${helpers.predefined_type(
+ "forced-color-adjust",
+ "ForcedColorAdjust",
+ "computed::ForcedColorAdjust::Auto",
+ engines="gecko",
+ gecko_pref="layout.css.forced-color-adjust.enabled",
+ has_effect_on_gecko_scrollbars=False,
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-color-adjust-1/#forced-color-adjust-prop",
+)}
+
+${helpers.single_keyword(
+ "-webkit-text-security",
+ "none circle disc square",
+ engines="gecko",
+ gecko_enum_prefix="StyleTextSecurity",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text/#MISSING",
+)}
diff --git a/servo/components/style/properties/longhands/inherited_ui.mako.rs b/servo/components/style/properties/longhands/inherited_ui.mako.rs
new file mode 100644
index 0000000000..b58bde355e
--- /dev/null
+++ b/servo/components/style/properties/longhands/inherited_ui.mako.rs
@@ -0,0 +1,118 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("InheritedUI", inherited=True, gecko_name="UI") %>
+
+${helpers.predefined_type(
+ "cursor",
+ "Cursor",
+ "computed::Cursor::auto()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Cursor::auto()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-ui/#cursor",
+)}
+
+// NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact)
+// is nonstandard, slated for CSS4-UI.
+// TODO(pcwalton): SVG-only values.
+${helpers.single_keyword(
+ "pointer-events",
+ "auto none",
+ engines="gecko servo-2013 servo-2020",
+ animation_value_type="discrete",
+ extra_gecko_values="visiblepainted visiblefill visiblestroke visible painted fill stroke all",
+ spec="https://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty",
+ gecko_enum_prefix="StylePointerEvents",
+)}
+
+${helpers.single_keyword(
+ "-moz-inert",
+ "none inert",
+ engines="gecko",
+ gecko_ffi_name="mInert",
+ gecko_enum_prefix="StyleInert",
+ animation_value_type="discrete",
+ enabled_in="ua",
+ spec="Nonstandard (https://html.spec.whatwg.org/multipage/#inert-subtrees)",
+)}
+
+${helpers.single_keyword(
+ "-moz-user-input",
+ "auto none",
+ engines="gecko",
+ gecko_ffi_name="mUserInput",
+ gecko_enum_prefix="StyleUserInput",
+ animation_value_type="discrete",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-input)",
+)}
+
+${helpers.single_keyword(
+ "-moz-user-modify",
+ "read-only read-write write-only",
+ engines="gecko",
+ gecko_ffi_name="mUserModify",
+ gecko_enum_prefix="StyleUserModify",
+ needs_conversion=True,
+ animation_value_type="discrete",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-modify)",
+)}
+
+${helpers.single_keyword(
+ "-moz-user-focus",
+ "none ignore normal select-after select-before select-menu select-same select-all",
+ engines="gecko",
+ gecko_ffi_name="mUserFocus",
+ gecko_enum_prefix="StyleUserFocus",
+ animation_value_type="discrete",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-focus)",
+)}
+
+${helpers.predefined_type(
+ "caret-color",
+ "color::CaretColor",
+ "generics::color::CaretColor::auto()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-ui/#caret-color",
+ animation_value_type="CaretColor",
+ ignored_when_colors_disabled=True,
+)}
+
+${helpers.predefined_type(
+ "accent-color",
+ "ColorOrAuto",
+ "generics::color::ColorOrAuto::Auto",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-ui-4/#widget-accent",
+ gecko_pref="layout.css.accent-color.enabled",
+ animation_value_type="ColorOrAuto",
+ ignored_when_colors_disabled=True,
+ has_effect_on_gecko_scrollbars=False,
+)}
+
+${helpers.predefined_type(
+ "color-scheme",
+ "ColorScheme",
+ "specified::color::ColorScheme::normal()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-color-adjust/#color-scheme-prop",
+ gecko_pref="layout.css.color-scheme.enabled",
+ animation_value_type="discrete",
+ has_effect_on_gecko_scrollbars=False,
+ ignored_when_colors_disabled=True,
+ enabled_in="chrome",
+)}
+
+${helpers.predefined_type(
+ "scrollbar-color",
+ "ui::ScrollbarColor",
+ "Default::default()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-scrollbars-1/#scrollbar-color",
+ animation_value_type="ScrollbarColor",
+ boxed=True,
+ ignored_when_colors_disabled=True,
+)}
diff --git a/servo/components/style/properties/longhands/list.mako.rs b/servo/components/style/properties/longhands/list.mako.rs
new file mode 100644
index 0000000000..51f5bf1192
--- /dev/null
+++ b/servo/components/style/properties/longhands/list.mako.rs
@@ -0,0 +1,75 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("List", inherited=True) %>
+
+${helpers.single_keyword(
+ "list-style-position",
+ "outside inside",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ gecko_enum_prefix="StyleListStylePosition",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-lists/#propdef-list-style-position",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+// TODO(pcwalton): Implement the full set of counter styles per CSS-COUNTER-STYLES [1] 6.1:
+//
+// decimal-leading-zero, armenian, upper-armenian, lower-armenian, georgian, lower-roman,
+// upper-roman
+//
+// [1]: http://dev.w3.org/csswg/css-counter-styles/
+% if engine in ["servo-2013", "servo-2020"]:
+ ${helpers.single_keyword(
+ "list-style-type",
+ "disc none circle square disclosure-open disclosure-closed",
+ extra_servo_2013_values="""
+ decimal lower-alpha upper-alpha arabic-indic bengali cambodian cjk-decimal devanagari
+ gujarati gurmukhi kannada khmer lao malayalam mongolian myanmar oriya persian telugu
+ thai tibetan cjk-earthly-branch cjk-heavenly-stem lower-greek hiragana hiragana-iroha
+ katakana katakana-iroha
+ """,
+ engines="servo-2013 servo-2020",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type",
+ servo_restyle_damage="rebuild_and_reflow",
+ )}
+% endif
+% if engine == "gecko":
+ ${helpers.predefined_type(
+ "list-style-type",
+ "ListStyleType",
+ "computed::ListStyleType::disc()",
+ engines="gecko",
+ initial_specified_value="specified::ListStyleType::disc()",
+ animation_value_type="discrete",
+ boxed=True,
+ spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type",
+ servo_restyle_damage="rebuild_and_reflow",
+ )}
+% endif
+
+${helpers.predefined_type(
+ "list-style-image",
+ "Image",
+ engines="gecko servo-2013 servo-2020",
+ initial_value="computed::Image::None",
+ initial_specified_value="specified::Image::None",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "quotes",
+ "Quotes",
+ "computed::Quotes::get_initial_value()",
+ engines="gecko servo-2013",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-content/#propdef-quotes",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
diff --git a/servo/components/style/properties/longhands/margin.mako.rs b/servo/components/style/properties/longhands/margin.mako.rs
new file mode 100644
index 0000000000..5c46cebdf2
--- /dev/null
+++ b/servo/components/style/properties/longhands/margin.mako.rs
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import ALL_SIDES, DEFAULT_RULES_AND_PAGE, maybe_moz_logical_alias %>
+<% data.new_style_struct("Margin", inherited=False) %>
+
+% for side in ALL_SIDES:
+ <%
+ spec = "https://drafts.csswg.org/css-box/#propdef-margin-%s" % side[0]
+ if side[1]:
+ spec = "https://drafts.csswg.org/css-logical-props/#propdef-margin-%s" % side[1]
+ %>
+ ${helpers.predefined_type(
+ "margin-%s" % side[0],
+ "LengthPercentageOrAuto",
+ "computed::LengthPercentageOrAuto::zero()",
+ engines="gecko servo-2013 servo-2020",
+ aliases=maybe_moz_logical_alias(engine, side, "-moz-margin-%s"),
+ allow_quirks="No" if side[1] else "Yes",
+ animation_value_type="ComputedValue",
+ logical=side[1],
+ logical_group="margin",
+ spec=spec,
+ rule_types_allowed=DEFAULT_RULES_AND_PAGE,
+ servo_restyle_damage="reflow"
+ )}
+% endfor
+
+${helpers.predefined_type(
+ "overflow-clip-margin",
+ "Length",
+ "computed::Length::zero()",
+ parse_method="parse_non_negative",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-overflow/#propdef-overflow-clip-margin",
+ animation_value_type="ComputedValue",
+)}
+
+% for side in ALL_SIDES:
+ ${helpers.predefined_type(
+ "scroll-margin-%s" % side[0],
+ "Length",
+ "computed::Length::zero()",
+ engines="gecko",
+ logical=side[1],
+ logical_group="scroll-margin",
+ spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0],
+ animation_value_type="ComputedValue",
+ )}
+% endfor
diff --git a/servo/components/style/properties/longhands/outline.mako.rs b/servo/components/style/properties/longhands/outline.mako.rs
new file mode 100644
index 0000000000..e5ae1810b4
--- /dev/null
+++ b/servo/components/style/properties/longhands/outline.mako.rs
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import Method %>
+
+<% data.new_style_struct("Outline",
+ inherited=False,
+ additional_methods=[Method("outline_has_nonzero_width", "bool")]) %>
+
+// TODO(pcwalton): `invert`
+${helpers.predefined_type(
+ "outline-color",
+ "Color",
+ "computed_value::T::currentcolor()",
+ engines="gecko servo-2013",
+ initial_specified_value="specified::Color::currentcolor()",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ spec="https://drafts.csswg.org/css-ui/#propdef-outline-color",
+)}
+
+${helpers.predefined_type(
+ "outline-style",
+ "OutlineStyle",
+ "computed::OutlineStyle::none()",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ initial_specified_value="specified::OutlineStyle::none()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-ui/#propdef-outline-style",
+)}
+
+${helpers.predefined_type(
+ "outline-width",
+ "BorderSideWidth",
+ "app_units::Au::from_px(3)",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.2020.unimplemented",
+ initial_specified_value="specified::BorderSideWidth::medium()",
+ animation_value_type="NonNegativeLength",
+ spec="https://drafts.csswg.org/css-ui/#propdef-outline-width",
+)}
+
+${helpers.predefined_type(
+ "outline-offset",
+ "Length",
+ "crate::values::computed::Length::new(0.)",
+ engines="gecko servo-2013",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-ui/#propdef-outline-offset",
+)}
diff --git a/servo/components/style/properties/longhands/padding.mako.rs b/servo/components/style/properties/longhands/padding.mako.rs
new file mode 100644
index 0000000000..84683412f2
--- /dev/null
+++ b/servo/components/style/properties/longhands/padding.mako.rs
@@ -0,0 +1,41 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import ALL_SIDES, maybe_moz_logical_alias %>
+<% data.new_style_struct("Padding", inherited=False) %>
+
+% for side in ALL_SIDES:
+ <%
+ spec = "https://drafts.csswg.org/css-box/#propdef-padding-%s" % side[0]
+ if side[1]:
+ spec = "https://drafts.csswg.org/css-logical-props/#propdef-padding-%s" % side[1]
+ %>
+ ${helpers.predefined_type(
+ "padding-%s" % side[0],
+ "NonNegativeLengthPercentage",
+ "computed::NonNegativeLengthPercentage::zero()",
+ engines="gecko servo-2013 servo-2020",
+ aliases=maybe_moz_logical_alias(engine, side, "-moz-padding-%s"),
+ animation_value_type="NonNegativeLengthPercentage",
+ logical=side[1],
+ logical_group="padding",
+ spec=spec,
+ allow_quirks="No" if side[1] else "Yes",
+ servo_restyle_damage="reflow rebuild_and_reflow_inline"
+ )}
+% endfor
+
+% for side in ALL_SIDES:
+ ${helpers.predefined_type(
+ "scroll-padding-%s" % side[0],
+ "NonNegativeLengthPercentageOrAuto",
+ "computed::NonNegativeLengthPercentageOrAuto::auto()",
+ engines="gecko",
+ logical=side[1],
+ logical_group="scroll-padding",
+ spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0],
+ animation_value_type="NonNegativeLengthPercentageOrAuto",
+ )}
+% endfor
diff --git a/servo/components/style/properties/longhands/page.mako.rs b/servo/components/style/properties/longhands/page.mako.rs
new file mode 100644
index 0000000000..b857ce0ca3
--- /dev/null
+++ b/servo/components/style/properties/longhands/page.mako.rs
@@ -0,0 +1,42 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import PAGE_RULE %>
+
+<% data.new_style_struct("Page", inherited=False) %>
+
+${helpers.predefined_type(
+ "size",
+ "PageSize",
+ "computed::PageSize::auto()",
+ engines="gecko",
+ gecko_pref="layout.css.page-size.enabled",
+ initial_specified_value="specified::PageSize::auto()",
+ spec="https://drafts.csswg.org/css-page-3/#page-size-prop",
+ boxed=True,
+ animation_value_type="none",
+ rule_types_allowed=PAGE_RULE,
+)}
+
+${helpers.predefined_type(
+ "page",
+ "PageName",
+ "computed::PageName::auto()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-page-3/#using-named-pages",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "page-orientation",
+ "PageOrientation",
+ "computed::PageOrientation::Upright",
+ engines="gecko",
+ gecko_pref="layout.css.page-orientation.enabled",
+ initial_specified_value="specified::PageOrientation::Upright",
+ spec="https://drafts.csswg.org/css-page-3/#page-orientation-prop",
+ animation_value_type="none",
+ rule_types_allowed=PAGE_RULE,
+)}
diff --git a/servo/components/style/properties/longhands/position.mako.rs b/servo/components/style/properties/longhands/position.mako.rs
new file mode 100644
index 0000000000..4c974ef9dc
--- /dev/null
+++ b/servo/components/style/properties/longhands/position.mako.rs
@@ -0,0 +1,448 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%! from data import to_rust_ident %>
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import ALL_SIZES, PHYSICAL_SIDES, LOGICAL_SIDES %>
+
+<% data.new_style_struct("Position", inherited=False) %>
+
+// "top" / "left" / "bottom" / "right"
+% for side in PHYSICAL_SIDES:
+ ${helpers.predefined_type(
+ side,
+ "LengthPercentageOrAuto",
+ "computed::LengthPercentageOrAuto::auto()",
+ engines="gecko servo-2013 servo-2020",
+ spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
+ animation_value_type="ComputedValue",
+ allow_quirks="Yes",
+ servo_restyle_damage="reflow_out_of_flow",
+ logical_group="inset",
+ )}
+% endfor
+// inset-* logical properties, map to "top" / "left" / "bottom" / "right"
+% for side in LOGICAL_SIDES:
+ ${helpers.predefined_type(
+ "inset-%s" % side,
+ "LengthPercentageOrAuto",
+ "computed::LengthPercentageOrAuto::auto()",
+ engines="gecko servo-2013 servo-2020",
+ spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side,
+ animation_value_type="ComputedValue",
+ logical=True,
+ logical_group="inset",
+ )}
+% endfor
+
+${helpers.predefined_type(
+ "z-index",
+ "ZIndex",
+ "computed::ZIndex::auto()",
+ engines="gecko servo-2013 servo-2020",
+ spec="https://www.w3.org/TR/CSS2/visuren.html#z-index",
+ animation_value_type="ComputedValue",
+)}
+
+// 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",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ spec="https://drafts.csswg.org/css-flexbox/#flex-direction-property",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ servo_restyle_damage = "reflow",
+ gecko_enum_prefix = "StyleFlexDirection",
+)}
+
+${helpers.single_keyword(
+ "flex-wrap",
+ "nowrap wrap wrap-reverse",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ spec="https://drafts.csswg.org/css-flexbox/#flex-wrap-property",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ servo_restyle_damage = "reflow",
+ gecko_enum_prefix = "StyleFlexWrap",
+)}
+
+% if engine == "servo-2013":
+ // 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",
+ engines="servo-2013",
+ extra_prefixes="webkit",
+ spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
+ animation_value_type="discrete",
+ servo_restyle_damage = "reflow",
+ )}
+% endif
+% if engine == "gecko":
+ ${helpers.predefined_type(
+ "justify-content",
+ "JustifyContent",
+ "specified::JustifyContent(specified::ContentDistribution::normal())",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ )}
+
+ ${helpers.predefined_type(
+ "justify-tracks",
+ "JustifyTracks",
+ "specified::JustifyTracks::default()",
+ engines="gecko",
+ gecko_pref="layout.css.grid-template-masonry-value.enabled",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ spec="https://github.com/w3c/csswg-drafts/issues/4650",
+ )}
+% endif
+
+% if engine in ["servo-2013", "servo-2020"]:
+ // FIXME: Update Servo to support the same Syntax as Gecko.
+ ${helpers.single_keyword(
+ "align-content",
+ "stretch flex-start flex-end center space-between space-around",
+ engines="servo-2013",
+ extra_prefixes="webkit",
+ spec="https://drafts.csswg.org/css-align/#propdef-align-content",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ )}
+
+ ${helpers.single_keyword(
+ "align-items",
+ "stretch flex-start flex-end center baseline",
+ engines="servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ extra_prefixes="webkit",
+ spec="https://drafts.csswg.org/css-flexbox/#align-items-property",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ )}
+% endif
+% if engine == "gecko":
+ ${helpers.predefined_type(
+ "align-content",
+ "AlignContent",
+ "specified::AlignContent(specified::ContentDistribution::normal())",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-align/#propdef-align-content",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ )}
+
+ ${helpers.predefined_type(
+ "align-tracks",
+ "AlignTracks",
+ "specified::AlignTracks::default()",
+ engines="gecko",
+ gecko_pref="layout.css.grid-template-masonry-value.enabled",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ spec="https://github.com/w3c/csswg-drafts/issues/4650",
+ )}
+
+ ${helpers.predefined_type(
+ "align-items",
+ "AlignItems",
+ "specified::AlignItems::normal()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-align/#propdef-align-items",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ servo_restyle_damage="reflow",
+ )}
+
+ ${helpers.predefined_type(
+ "justify-items",
+ "JustifyItems",
+ "computed::JustifyItems::legacy()",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-align/#propdef-justify-items",
+ animation_value_type="discrete",
+ )}
+% endif
+
+// Flex item properties
+${helpers.predefined_type(
+ "flex-grow",
+ "NonNegativeNumber",
+ "From::from(0.0)",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ spec="https://drafts.csswg.org/css-flexbox/#flex-grow-property",
+ extra_prefixes="webkit",
+ animation_value_type="NonNegativeNumber",
+ servo_restyle_damage="reflow",
+)}
+
+${helpers.predefined_type(
+ "flex-shrink",
+ "NonNegativeNumber",
+ "From::from(1.0)",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ spec="https://drafts.csswg.org/css-flexbox/#flex-shrink-property",
+ extra_prefixes="webkit",
+ animation_value_type="NonNegativeNumber",
+ servo_restyle_damage = "reflow",
+)}
+
+// https://drafts.csswg.org/css-align/#align-self-property
+% if engine in ["servo-2013", "servo-2020"]:
+ // FIXME: Update Servo to support the same syntax as Gecko.
+ ${helpers.single_keyword(
+ "align-self",
+ "auto stretch flex-start flex-end center baseline",
+ engines="servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ extra_prefixes="webkit",
+ spec="https://drafts.csswg.org/css-flexbox/#propdef-align-self",
+ animation_value_type="discrete",
+ servo_restyle_damage = "reflow",
+ )}
+% endif
+% if engine == "gecko":
+ ${helpers.predefined_type(
+ "align-self",
+ "AlignSelf",
+ "specified::AlignSelf(specified::SelfAlignment::auto())",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-align/#align-self-property",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ )}
+
+ ${helpers.predefined_type(
+ "justify-self",
+ "JustifySelf",
+ "specified::JustifySelf(specified::SelfAlignment::auto())",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-align/#justify-self-property",
+ animation_value_type="discrete",
+ )}
+% endif
+
+// https://drafts.csswg.org/css-flexbox/#propdef-order
+${helpers.predefined_type(
+ "order",
+ "Integer",
+ "0",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ extra_prefixes="webkit",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-flexbox/#order-property",
+ servo_restyle_damage="reflow",
+)}
+
+${helpers.predefined_type(
+ "flex-basis",
+ "FlexBasis",
+ "computed::FlexBasis::auto()",
+ engines="gecko servo-2013 servo-2020",
+ servo_2020_pref="layout.flexbox.enabled",
+ spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
+ extra_prefixes="webkit",
+ animation_value_type="FlexBasis",
+ servo_restyle_damage="reflow",
+ boxed=True,
+)}
+
+% for (size, logical) in ALL_SIZES:
+ <%
+ spec = "https://drafts.csswg.org/css-box/#propdef-%s"
+ if logical:
+ spec = "https://drafts.csswg.org/css-logical-props/#propdef-%s"
+ %>
+ // width, height, block-size, inline-size
+ ${helpers.predefined_type(
+ size,
+ "Size",
+ "computed::Size::auto()",
+ engines="gecko servo-2013 servo-2020",
+ logical=logical,
+ logical_group="size",
+ allow_quirks="No" if logical else "Yes",
+ spec=spec % size,
+ animation_value_type="Size",
+ servo_restyle_damage="reflow",
+ )}
+ // min-width, min-height, min-block-size, min-inline-size
+ ${helpers.predefined_type(
+ "min-%s" % size,
+ "Size",
+ "computed::Size::auto()",
+ engines="gecko servo-2013 servo-2020",
+ logical=logical,
+ logical_group="min-size",
+ allow_quirks="No" if logical else "Yes",
+ spec=spec % size,
+ animation_value_type="Size",
+ servo_restyle_damage="reflow",
+ )}
+ ${helpers.predefined_type(
+ "max-%s" % size,
+ "MaxSize",
+ "computed::MaxSize::none()",
+ engines="gecko servo-2013 servo-2020",
+ logical=logical,
+ logical_group="max-size",
+ allow_quirks="No" if logical else "Yes",
+ spec=spec % size,
+ animation_value_type="MaxSize",
+ servo_restyle_damage="reflow",
+ )}
+% endfor
+
+${helpers.single_keyword(
+ "box-sizing",
+ "content-box border-box",
+ engines="gecko servo-2013 servo-2020",
+ 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",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-images/#propdef-object-fit",
+ gecko_enum_prefix = "StyleObjectFit",
+)}
+
+${helpers.predefined_type(
+ "object-position",
+ "Position",
+ "computed::Position::center()",
+ engines="gecko",
+ boxed=True,
+ spec="https://drafts.csswg.org/css-images-3/#the-object-position",
+ animation_value_type="ComputedValue",
+)}
+
+% for kind in ["row", "column"]:
+ % for range in ["start", "end"]:
+ ${helpers.predefined_type(
+ "grid-%s-%s" % (kind, range),
+ "GridLine",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-%s" % (kind, range),
+ )}
+ % endfor
+
+ ${helpers.predefined_type(
+ "grid-auto-%ss" % kind,
+ "ImplicitGridTracks",
+ "Default::default()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-%ss" % kind,
+ )}
+
+ ${helpers.predefined_type(
+ "grid-template-%ss" % kind,
+ "GridTemplateComponent",
+ "specified::GenericGridTemplateComponent::None",
+ engines="gecko",
+ spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind,
+ animation_value_type="ComputedValue",
+ )}
+
+% endfor
+
+${helpers.predefined_type(
+ "masonry-auto-flow",
+ "MasonryAutoFlow",
+ "computed::MasonryAutoFlow::initial()",
+ engines="gecko",
+ gecko_pref="layout.css.grid-template-masonry-value.enabled",
+ animation_value_type="discrete",
+ spec="https://github.com/w3c/csswg-drafts/issues/4650",
+)}
+
+${helpers.predefined_type(
+ "grid-auto-flow",
+ "GridAutoFlow",
+ "computed::GridAutoFlow::ROW",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-grid/#propdef-grid-auto-flow",
+)}
+
+${helpers.predefined_type(
+ "grid-template-areas",
+ "GridTemplateAreas",
+ "computed::GridTemplateAreas::none()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas",
+)}
+
+${helpers.predefined_type(
+ "column-gap",
+ "length::NonNegativeLengthPercentageOrNormal",
+ "computed::length::NonNegativeLengthPercentageOrNormal::normal()",
+ engines="gecko servo-2013",
+ aliases="grid-column-gap" if engine == "gecko" else "",
+ servo_2013_pref="layout.columns.enabled",
+ spec="https://drafts.csswg.org/css-align-3/#propdef-column-gap",
+ animation_value_type="NonNegativeLengthPercentageOrNormal",
+ servo_restyle_damage="reflow",
+)}
+
+// no need for -moz- prefixed alias for this property
+${helpers.predefined_type(
+ "row-gap",
+ "length::NonNegativeLengthPercentageOrNormal",
+ "computed::length::NonNegativeLengthPercentageOrNormal::normal()",
+ engines="gecko",
+ aliases="grid-row-gap",
+ spec="https://drafts.csswg.org/css-align-3/#propdef-row-gap",
+ animation_value_type="NonNegativeLengthPercentageOrNormal",
+ servo_restyle_damage="reflow",
+)}
+
+${helpers.predefined_type(
+ "aspect-ratio",
+ "AspectRatio",
+ "computed::AspectRatio::auto()",
+ engines="gecko servo-2013",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-sizing-4/#aspect-ratio",
+ servo_restyle_damage="reflow",
+)}
+
+% for (size, logical) in ALL_SIZES:
+ ${helpers.predefined_type(
+ "contain-intrinsic-" + size,
+ "ContainIntrinsicSize",
+ "computed::ContainIntrinsicSize::None",
+ engines="gecko",
+ logical_group="contain-intrinsic-size",
+ logical=logical,
+ gecko_pref="layout.css.contain-intrinsic-size.enabled",
+ spec="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override",
+ animation_value_type="NonNegativeLength",
+ )}
+% endfor
diff --git a/servo/components/style/properties/longhands/svg.mako.rs b/servo/components/style/properties/longhands/svg.mako.rs
new file mode 100644
index 0000000000..d579473a02
--- /dev/null
+++ b/servo/components/style/properties/longhands/svg.mako.rs
@@ -0,0 +1,258 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("SVG", inherited=False, gecko_name="SVGReset") %>
+
+${helpers.single_keyword(
+ "vector-effect",
+ "none non-scaling-stroke",
+ engines="gecko",
+ gecko_enum_prefix="StyleVectorEffect",
+ animation_value_type="discrete",
+ spec="https://www.w3.org/TR/SVGTiny12/painting.html#VectorEffectProperty",
+)}
+
+// Section 13 - Gradients and Patterns
+
+${helpers.predefined_type(
+ "stop-color",
+ "Color",
+ "computed::Color::black()",
+ engines="gecko",
+ animation_value_type="AnimatedRGBA",
+ spec="https://www.w3.org/TR/SVGTiny12/painting.html#StopColorProperty",
+)}
+
+${helpers.predefined_type(
+ "stop-opacity",
+ "Opacity",
+ "1.0",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/pservers.html#StopOpacityProperty",
+)}
+
+// Section 15 - Filter Effects
+
+${helpers.predefined_type(
+ "flood-color",
+ "Color",
+ "computed::Color::black()",
+ engines="gecko",
+ animation_value_type="AnimatedColor",
+ spec="https://www.w3.org/TR/SVG/filters.html#FloodColorProperty",
+)}
+
+${helpers.predefined_type(
+ "flood-opacity",
+ "Opacity",
+ "1.0",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.fxtf.org/filter-effects/#FloodOpacityProperty",
+)}
+
+${helpers.predefined_type(
+ "lighting-color",
+ "Color",
+ "computed::Color::white()",
+ engines="gecko",
+ animation_value_type="AnimatedColor",
+ spec="https://www.w3.org/TR/SVG/filters.html#LightingColorProperty",
+)}
+
+// CSS Masking Module Level 1
+// https://drafts.fxtf.org/css-masking
+${helpers.single_keyword(
+ "mask-type",
+ "luminance alpha",
+ engines="gecko",
+ gecko_enum_prefix="StyleMaskType",
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-type",
+)}
+
+${helpers.predefined_type(
+ "clip-path",
+ "basic_shape::ClipPath",
+ "generics::basic_shape::ClipPath::None",
+ engines="gecko",
+ extra_prefixes="webkit",
+ animation_value_type="basic_shape::ClipPath",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-clip-path",
+)}
+
+${helpers.single_keyword(
+ "mask-mode",
+ "match-source alpha luminance",
+ engines="gecko",
+ gecko_enum_prefix="StyleMaskMode",
+ vector=True,
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-mode",
+)}
+
+${helpers.predefined_type(
+ "mask-repeat",
+ "BackgroundRepeat",
+ "computed::BackgroundRepeat::repeat()",
+ engines="gecko",
+ initial_specified_value="specified::BackgroundRepeat::repeat()",
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-repeat",
+ vector=True,
+)}
+
+% for (axis, direction) in [("x", "Horizontal"), ("y", "Vertical")]:
+ ${helpers.predefined_type(
+ "mask-position-" + axis,
+ "position::" + direction + "Position",
+ "computed::LengthPercentage::zero_percent()",
+ engines="gecko",
+ extra_prefixes="webkit",
+ initial_specified_value="specified::PositionComponent::Center",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-position",
+ animation_value_type="ComputedValue",
+ vector_animation_type="repeatable_list",
+ vector=True,
+ )}
+% endfor
+
+${helpers.single_keyword(
+ "mask-clip",
+ "border-box content-box padding-box",
+ engines="gecko",
+ extra_gecko_values="fill-box stroke-box view-box no-clip",
+ vector=True,
+ extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
+ gecko_inexhaustive=True,
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-clip",
+)}
+
+${helpers.single_keyword(
+ "mask-origin",
+ "border-box content-box padding-box",
+ engines="gecko",
+ extra_gecko_values="fill-box stroke-box view-box",
+ vector=True,
+ extra_prefixes="webkit",
+ gecko_enum_prefix="StyleGeometryBox",
+ gecko_inexhaustive=True,
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-origin",
+)}
+
+${helpers.predefined_type(
+ "mask-size",
+ "background::BackgroundSize",
+ "computed::BackgroundSize::auto()",
+ engines="gecko",
+ initial_specified_value="specified::BackgroundSize::auto()",
+ extra_prefixes="webkit",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-size",
+ animation_value_type="MaskSizeList",
+ vector=True,
+ vector_animation_type="repeatable_list",
+)}
+
+${helpers.single_keyword(
+ "mask-composite",
+ "add subtract intersect exclude",
+ engines="gecko",
+ gecko_enum_prefix="StyleMaskComposite",
+ vector=True,
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-composite",
+)}
+
+${helpers.predefined_type(
+ "mask-image",
+ "Image",
+ engines="gecko",
+ initial_value="computed::Image::None",
+ initial_specified_value="specified::Image::None",
+ parse_method="parse_with_cors_anonymous",
+ spec="https://drafts.fxtf.org/css-masking/#propdef-mask-image",
+ vector=True,
+ extra_prefixes="webkit",
+ animation_value_type="discrete",
+)}
+
+${helpers.predefined_type(
+ "x",
+ "LengthPercentage",
+ "computed::LengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/geometry.html#X",
+)}
+
+${helpers.predefined_type(
+ "y",
+ "LengthPercentage",
+ "computed::LengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/geometry.html#Y",
+)}
+
+${helpers.predefined_type(
+ "cx",
+ "LengthPercentage",
+ "computed::LengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/geometry.html#CX",
+)}
+
+${helpers.predefined_type(
+ "cy",
+ "LengthPercentage",
+ "computed::LengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/geometry.html#CY",
+)}
+
+${helpers.predefined_type(
+ "rx",
+ "NonNegativeLengthPercentageOrAuto",
+ "computed::NonNegativeLengthPercentageOrAuto::auto()",
+ engines="gecko",
+ animation_value_type="LengthPercentageOrAuto",
+ spec="https://svgwg.org/svg2-draft/geometry.html#RX",
+)}
+
+${helpers.predefined_type(
+ "ry",
+ "NonNegativeLengthPercentageOrAuto",
+ "computed::NonNegativeLengthPercentageOrAuto::auto()",
+ engines="gecko",
+ animation_value_type="LengthPercentageOrAuto",
+ spec="https://svgwg.org/svg2-draft/geometry.html#RY",
+)}
+
+${helpers.predefined_type(
+ "r",
+ "NonNegativeLengthPercentage",
+ "computed::NonNegativeLengthPercentage::zero()",
+ engines="gecko",
+ animation_value_type="LengthPercentage",
+ spec="https://svgwg.org/svg2-draft/geometry.html#R",
+)}
+
+${helpers.predefined_type(
+ "d",
+ "DProperty",
+ "specified::DProperty::none()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="https://svgwg.org/svg2-draft/paths.html#TheDProperty",
+)}
diff --git a/servo/components/style/properties/longhands/table.mako.rs b/servo/components/style/properties/longhands/table.mako.rs
new file mode 100644
index 0000000000..104c28b8e0
--- /dev/null
+++ b/servo/components/style/properties/longhands/table.mako.rs
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+
+<% data.new_style_struct("Table", inherited=False) %>
+
+${helpers.single_keyword(
+ "table-layout",
+ "auto fixed",
+ engines="gecko servo-2013",
+ gecko_ffi_name="mLayoutStrategy",
+ animation_value_type="discrete",
+ gecko_enum_prefix="StyleTableLayout",
+ spec="https://drafts.csswg.org/css-tables/#propdef-table-layout",
+ servo_restyle_damage="reflow",
+)}
+
+${helpers.predefined_type(
+ "-x-span",
+ "Integer",
+ "1",
+ engines="gecko",
+ spec="Internal-only (for `<col span>` pres attr)",
+ animation_value_type="none",
+ enabled_in="",
+)}
diff --git a/servo/components/style/properties/longhands/text.mako.rs b/servo/components/style/properties/longhands/text.mako.rs
new file mode 100644
index 0000000000..71fe83b729
--- /dev/null
+++ b/servo/components/style/properties/longhands/text.mako.rs
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import Method %>
+
+<% data.new_style_struct("Text", inherited=False, gecko_name="TextReset") %>
+
+${helpers.predefined_type(
+ "text-overflow",
+ "TextOverflow",
+ "computed::TextOverflow::get_initial_value()",
+ engines="gecko servo-2013",
+ animation_value_type="discrete",
+ boxed=True,
+ spec="https://drafts.csswg.org/css-ui/#propdef-text-overflow",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "unicode-bidi",
+ "normal embed isolate bidi-override isolate-override plaintext",
+ engines="gecko servo-2013",
+ gecko_enum_prefix="StyleUnicodeBidi",
+ animation_value_type="none",
+ spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.predefined_type(
+ "text-decoration-line",
+ "TextDecorationLine",
+ "specified::TextDecorationLine::none()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::TextDecorationLine::none()",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line",
+ servo_restyle_damage="rebuild_and_reflow",
+)}
+
+${helpers.single_keyword(
+ "text-decoration-style",
+ "solid double dotted dashed wavy -moz-none",
+ engines="gecko servo-2020",
+ gecko_enum_prefix="StyleTextDecorationStyle",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-style",
+)}
+
+${helpers.predefined_type(
+ "text-decoration-color",
+ "Color",
+ "computed_value::T::currentcolor()",
+ engines="gecko servo-2020",
+ initial_specified_value="specified::Color::currentcolor()",
+ animation_value_type="AnimatedColor",
+ ignored_when_colors_disabled=True,
+ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-color",
+)}
+
+${helpers.predefined_type(
+ "initial-letter",
+ "InitialLetter",
+ "computed::InitialLetter::normal()",
+ engines="gecko",
+ initial_specified_value="specified::InitialLetter::normal()",
+ animation_value_type="discrete",
+ gecko_pref="layout.css.initial-letter.enabled",
+ spec="https://drafts.csswg.org/css-inline/#sizing-drop-initials",
+)}
+
+${helpers.predefined_type(
+ "text-decoration-thickness",
+ "TextDecorationLength",
+ "generics::text::GenericTextDecorationLength::Auto",
+ engines="gecko",
+ initial_specified_value="generics::text::GenericTextDecorationLength::Auto",
+ animation_value_type="ComputedValue",
+ spec="https://drafts.csswg.org/css-text-decor-4/#text-decoration-width-property"
+)}
diff --git a/servo/components/style/properties/longhands/ui.mako.rs b/servo/components/style/properties/longhands/ui.mako.rs
new file mode 100644
index 0000000000..3ece832fef
--- /dev/null
+++ b/servo/components/style/properties/longhands/ui.mako.rs
@@ -0,0 +1,395 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import DEFAULT_RULES_EXCEPT_KEYFRAME, Method %>
+
+// CSS Basic User Interface Module Level 1
+// https://drafts.csswg.org/css-ui-3/
+<% data.new_style_struct("UI", inherited=False, gecko_name="UIReset") %>
+
+// TODO spec says that UAs should not support this
+// we should probably remove from gecko (https://bugzilla.mozilla.org/show_bug.cgi?id=1328331)
+${helpers.single_keyword(
+ "ime-mode",
+ "auto normal active disabled inactive",
+ engines="gecko",
+ gecko_enum_prefix="StyleImeMode",
+ gecko_ffi_name="mIMEMode",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-ui/#input-method-editor",
+)}
+
+${helpers.single_keyword(
+ "scrollbar-width",
+ "auto thin none",
+ engines="gecko",
+ gecko_enum_prefix="StyleScrollbarWidth",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-scrollbars-1/#scrollbar-width"
+)}
+
+${helpers.predefined_type(
+ "user-select",
+ "UserSelect",
+ "computed::UserSelect::Auto",
+ engines="gecko",
+ extra_prefixes="moz webkit",
+ animation_value_type="discrete",
+ spec="https://drafts.csswg.org/css-ui-4/#propdef-user-select",
+)}
+
+// TODO(emilio): This probably should be hidden from content.
+${helpers.single_keyword(
+ "-moz-window-dragging",
+ "default drag no-drag",
+ engines="gecko",
+ gecko_ffi_name="mWindowDragging",
+ gecko_enum_prefix="StyleWindowDragging",
+ animation_value_type="discrete",
+ spec="None (Nonstandard Firefox-only property)",
+)}
+
+// TODO(emilio): Maybe make shadow behavior on macOS match Linux / Windows, and remove this
+// property.
+${helpers.single_keyword(
+ "-moz-window-shadow",
+ "default none",
+ engines="gecko",
+ gecko_ffi_name="mWindowShadow",
+ gecko_enum_prefix="StyleWindowShadow",
+ gecko_inexhaustive=True,
+ animation_value_type="discrete",
+ enabled_in="chrome",
+ spec="None (Nonstandard internal property)",
+)}
+
+${helpers.predefined_type(
+ "-moz-window-opacity",
+ "Opacity",
+ "1.0",
+ engines="gecko",
+ gecko_ffi_name="mWindowOpacity",
+ animation_value_type="ComputedValue",
+ spec="None (Nonstandard internal property)",
+ enabled_in="chrome",
+)}
+
+${helpers.predefined_type(
+ "-moz-window-transform",
+ "Transform",
+ "generics::transform::Transform::none()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="None (Nonstandard internal property)",
+ enabled_in="chrome",
+)}
+
+${helpers.predefined_type(
+ "-moz-window-transform-origin",
+ "TransformOrigin",
+ "computed::TransformOrigin::initial_value()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ gecko_ffi_name="mWindowTransformOrigin",
+ boxed=True,
+ spec="None (Nonstandard internal property)",
+ enabled_in="chrome",
+)}
+
+${helpers.predefined_type(
+ "-moz-window-input-region-margin",
+ "Length",
+ "computed::Length::zero()",
+ engines="gecko",
+ animation_value_type="ComputedValue",
+ spec="None (Nonstandard internal property)",
+ enabled_in="chrome",
+)}
+
+// Hack to allow chrome to hide stuff only visually (without hiding it from
+// a11y).
+${helpers.predefined_type(
+ "-moz-subtree-hidden-only-visually",
+ "BoolInteger",
+ "computed::BoolInteger::zero()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="None (Nonstandard internal property)",
+ enabled_in="chrome",
+)}
+
+// TODO(emilio): Probably also should be hidden from content.
+${helpers.predefined_type(
+ "-moz-force-broken-image-icon",
+ "BoolInteger",
+ "computed::BoolInteger::zero()",
+ engines="gecko",
+ animation_value_type="discrete",
+ spec="None (Nonstandard Firefox-only property)",
+)}
+
+<% transition_extra_prefixes = "moz:layout.css.prefixes.transitions webkit" %>
+
+${helpers.predefined_type(
+ "transition-duration",
+ "Time",
+ "computed::Time::zero()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Time::zero()",
+ parse_method="parse_non_negative",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ 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()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::TimingFunction::ease()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ 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()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::TransitionProperty::all()",
+ vector=True,
+ allow_empty="NotInitial",
+ need_index=True,
+ animation_value_type="none",
+ extra_prefixes=transition_extra_prefixes,
+ spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property",
+)}
+
+${helpers.predefined_type(
+ "transition-delay",
+ "Time",
+ "computed::Time::zero()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Time::zero()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ 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()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::AnimationName::none()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ extra_prefixes=animation_extra_prefixes,
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+ spec="https://drafts.csswg.org/css-animations/#propdef-animation-name",
+)}
+
+${helpers.predefined_type(
+ "animation-duration",
+ "Time",
+ "computed::Time::zero()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Time::zero()",
+ parse_method="parse_non_negative",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ 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()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::TimingFunction::ease()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ extra_prefixes=animation_extra_prefixes,
+ spec="https://drafts.csswg.org/css-transitions/#propdef-animation-timing-function",
+)}
+
+${helpers.predefined_type(
+ "animation-iteration-count",
+ "AnimationIterationCount",
+ "computed::AnimationIterationCount::one()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::AnimationIterationCount::one()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ extra_prefixes=animation_extra_prefixes,
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+ 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",
+ engines="gecko servo-2013 servo-2020",
+ need_index=True,
+ animation_value_type="none",
+ vector=True,
+ gecko_enum_prefix="PlaybackDirection",
+ custom_consts=animation_direction_custom_consts,
+ extra_prefixes=animation_extra_prefixes,
+ gecko_inexhaustive=True,
+ spec="https://drafts.csswg.org/css-animations/#propdef-animation-direction",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.single_keyword(
+ "animation-play-state",
+ "running paused",
+ engines="gecko servo-2013 servo-2020",
+ need_index=True,
+ animation_value_type="none",
+ vector=True,
+ extra_prefixes=animation_extra_prefixes,
+ gecko_enum_prefix="StyleAnimationPlayState",
+ spec="https://drafts.csswg.org/css-animations/#propdef-animation-play-state",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.single_keyword(
+ "animation-fill-mode",
+ "none forwards backwards both",
+ engines="gecko servo-2013 servo-2020",
+ need_index=True,
+ animation_value_type="none",
+ vector=True,
+ gecko_enum_prefix="FillMode",
+ extra_prefixes=animation_extra_prefixes,
+ gecko_inexhaustive=True,
+ spec="https://drafts.csswg.org/css-animations/#propdef-animation-fill-mode",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.single_keyword(
+ "animation-composition",
+ "replace add accumulate",
+ engines="gecko",
+ need_index=True,
+ animation_value_type="none",
+ vector=True,
+ gecko_enum_prefix="CompositeOperation",
+ gecko_inexhaustive=True,
+ gecko_pref="layout.css.animation-composition.enabled",
+ spec="https://drafts.csswg.org/css-animations-2/#animation-composition",
+)}
+
+${helpers.predefined_type(
+ "animation-delay",
+ "Time",
+ "computed::Time::zero()",
+ engines="gecko servo-2013 servo-2020",
+ initial_specified_value="specified::Time::zero()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ extra_prefixes=animation_extra_prefixes,
+ spec="https://drafts.csswg.org/css-animations/#propdef-animation-delay",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.predefined_type(
+ "animation-timeline",
+ "AnimationTimeline",
+ "computed::AnimationTimeline::auto()",
+ engines="gecko",
+ initial_specified_value="specified::AnimationTimeline::auto()",
+ vector=True,
+ need_index=True,
+ animation_value_type="none",
+ gecko_pref="layout.css.scroll-driven-animations.enabled",
+ spec="https://drafts.csswg.org/css-animations-2/#propdef-animation-timeline",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.predefined_type(
+ "scroll-timeline-name",
+ "ScrollTimelineName",
+ "computed::ScrollTimelineName::none()",
+ vector=True,
+ need_index=True,
+ engines="gecko",
+ animation_value_type="none",
+ gecko_pref="layout.css.scroll-driven-animations.enabled",
+ spec="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-name",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.predefined_type(
+ "scroll-timeline-axis",
+ "ScrollAxis",
+ "computed::ScrollAxis::default()",
+ vector=True,
+ need_index=True,
+ engines="gecko",
+ animation_value_type="none",
+ gecko_pref="layout.css.scroll-driven-animations.enabled",
+ spec="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-axis",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.predefined_type(
+ "view-timeline-name",
+ "ScrollTimelineName",
+ "computed::ScrollTimelineName::none()",
+ vector=True,
+ need_index=True,
+ engines="gecko",
+ animation_value_type="none",
+ gecko_pref="layout.css.scroll-driven-animations.enabled",
+ spec="https://drafts.csswg.org/scroll-animations-1/#view-timeline-name",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.predefined_type(
+ "view-timeline-axis",
+ "ScrollAxis",
+ "computed::ScrollAxis::default()",
+ vector=True,
+ need_index=True,
+ engines="gecko",
+ animation_value_type="none",
+ gecko_pref="layout.css.scroll-driven-animations.enabled",
+ spec="https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
+
+${helpers.predefined_type(
+ "view-timeline-inset",
+ "ViewTimelineInset",
+ "computed::ViewTimelineInset::default()",
+ vector=True,
+ need_index=True,
+ engines="gecko",
+ animation_value_type="none",
+ gecko_pref="layout.css.scroll-driven-animations.enabled",
+ spec="https://drafts.csswg.org/scroll-animations-1/#view-timeline-axis",
+ rule_types_allowed=DEFAULT_RULES_EXCEPT_KEYFRAME,
+)}
diff --git a/servo/components/style/properties/longhands/xul.mako.rs b/servo/components/style/properties/longhands/xul.mako.rs
new file mode 100644
index 0000000000..a939b01892
--- /dev/null
+++ b/servo/components/style/properties/longhands/xul.mako.rs
@@ -0,0 +1,79 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import Method %>
+
+// Non-standard properties that Gecko uses for XUL elements.
+<% data.new_style_struct("XUL", inherited=False) %>
+
+${helpers.single_keyword(
+ "-moz-box-align",
+ "stretch start center baseline end",
+ engines="gecko",
+ gecko_ffi_name="mBoxAlign",
+ gecko_enum_prefix="StyleBoxAlign",
+ animation_value_type="discrete",
+ aliases="-webkit-box-align",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-align)",
+)}
+
+${helpers.single_keyword(
+ "-moz-box-direction",
+ "normal reverse",
+ engines="gecko",
+ gecko_ffi_name="mBoxDirection",
+ gecko_enum_prefix="StyleBoxDirection",
+ animation_value_type="discrete",
+ aliases="-webkit-box-direction",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-direction)",
+)}
+
+${helpers.predefined_type(
+ "-moz-box-flex",
+ "NonNegativeNumber",
+ "From::from(0.)",
+ engines="gecko",
+ gecko_ffi_name="mBoxFlex",
+ animation_value_type="NonNegativeNumber",
+ aliases="-webkit-box-flex",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-flex)",
+)}
+
+${helpers.single_keyword(
+ "-moz-box-orient",
+ "horizontal vertical",
+ engines="gecko",
+ gecko_ffi_name="mBoxOrient",
+ gecko_aliases="inline-axis=horizontal block-axis=vertical",
+ gecko_enum_prefix="StyleBoxOrient",
+ animation_value_type="discrete",
+ aliases="-webkit-box-orient",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-orient)",
+)}
+
+${helpers.single_keyword(
+ "-moz-box-pack",
+ "start center end justify",
+ engines="gecko",
+ gecko_ffi_name="mBoxPack",
+ gecko_enum_prefix="StyleBoxPack",
+ animation_value_type="discrete",
+ aliases="-webkit-box-pack",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-pack)",
+)}
+
+// NOTE(heycam): Odd that the initial value is 1 yet 0 is a valid value. There
+// are uses of `-moz-box-ordinal-group: 0` in the tree, too.
+${helpers.predefined_type(
+ "-moz-box-ordinal-group",
+ "Integer",
+ "1",
+ engines="gecko",
+ parse_method="parse_non_negative",
+ aliases="-webkit-box-ordinal-group",
+ gecko_ffi_name="mBoxOrdinal",
+ animation_value_type="discrete",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-box-ordinal-group)",
+)}