servo: Merge #10848 - Add Servo_GetStyleFoo functions to get style structs from GeckoComputedValues (from heycam:struct-accessor); r=bholley
authorCameron McCormack <cam@mcc.id.au>
Wed, 27 Apr 2016 02:20:17 -0700
changeset 338641 f9e07407a68c9a523c6cf27dcc10aa93a45ff73a
parent 338640 b087ea82eba19cfc2a1ff519565aa965b256716e
child 338642 a4369f189a605a539c51065396ee0e99942bf262
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
servo: Merge #10848 - Add Servo_GetStyleFoo functions to get style structs from GeckoComputedValues (from heycam:struct-accessor); r=bholley r?@bholley Source-Repo: https://github.com/servo/servo Source-Revision: e079e01320cf4b0f80c7d6307cf6d53fe7703ec4
servo/components/style/properties/data.py
servo/components/style/properties/longhand/background.mako.rs
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/properties/longhand/box.mako.rs
servo/components/style/properties/longhand/color.mako.rs
servo/components/style/properties/longhand/column.mako.rs
servo/components/style/properties/longhand/counters.mako.rs
servo/components/style/properties/longhand/effects.mako.rs
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/properties/longhand/inherited_box.mako.rs
servo/components/style/properties/longhand/inherited_table.mako.rs
servo/components/style/properties/longhand/inherited_text.mako.rs
servo/components/style/properties/longhand/list.mako.rs
servo/components/style/properties/longhand/margin.mako.rs
servo/components/style/properties/longhand/outline.mako.rs
servo/components/style/properties/longhand/padding.mako.rs
servo/components/style/properties/longhand/pointing.mako.rs
servo/components/style/properties/longhand/position.mako.rs
servo/components/style/properties/longhand/svg.mako.rs
servo/components/style/properties/longhand/svg_inherited.mako.rs
servo/components/style/properties/longhand/table.mako.rs
servo/components/style/properties/longhand/text.mako.rs
servo/components/style/properties/longhand/ui.mako.rs
servo/components/style/properties/longhand/xul.mako.rs
servo/components/style/properties/properties.mako.rs
servo/ports/geckolib/glue.rs
servo/ports/geckolib/properties.mako.rs
--- a/servo/components/style/properties/data.py
+++ b/servo/components/style/properties/data.py
@@ -93,25 +93,26 @@ class Method(object):
     def declare(self):
         return self.signature() + ";"
 
     def stub(self):
         return self.signature() + "{ unimplemented!() }"
 
 
 class StyleStruct(object):
-    def __init__(self, name, inherited, gecko_ffi_name=None, additional_methods=None):
+    def __init__(self, name, inherited, gecko_name=None, additional_methods=None):
         self.servo_struct_name = "Servo" + name
         self.gecko_struct_name = "Gecko" + name
         self.trait_name = name
         self.trait_name_lower = name.lower()
         self.ident = to_rust_ident(self.trait_name_lower)
         self.longhands = []
         self.inherited = inherited
-        self.gecko_ffi_name = gecko_ffi_name
+        self.gecko_name = gecko_name or name
+        self.gecko_ffi_name = "nsStyle" + self.gecko_name
         self.additional_methods = additional_methods or []
 
 
 class PropertiesData(object):
     def __init__(self, product):
         self.product = product
         self.style_structs = []
         self.current_style_struct = None
--- a/servo/components/style/properties/longhand/background.mako.rs
+++ b/servo/components/style/properties/longhand/background.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Background", inherited=False, gecko_ffi_name="nsStyleBackground") %>
+<% data.new_style_struct("Background", inherited=False) %>
 ${helpers.predefined_type(
     "background-color", "CSSColor",
     "::cssparser::Color::RGBA(::cssparser::RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")}
 
 <%helpers:longhand name="background-image">
     use cssparser::ToCss;
     use std::fmt;
     use values::specified::Image;
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -1,16 +1,16 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Method %>
 
-<% data.new_style_struct("Border", inherited=False, gecko_ffi_name="nsStyleBorder",
+<% data.new_style_struct("Border", inherited=False,
                    additional_methods=[Method("border_" + side + "_has_nonzero_width",
                                               "bool") for side in ["top", "right", "bottom", "left"]]) %>
 
 % for side in ["top", "right", "bottom", "left"]:
     ${helpers.predefined_type("border-%s-color" % side, "CSSColor", "::cssparser::Color::CurrentColor")}
 % endfor
 
 % for side in ["top", "right", "bottom", "left"]:
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Method, to_rust_ident %>
 
 <% data.new_style_struct("Box",
                          inherited=False,
-                         gecko_ffi_name="nsStyleDisplay",
+                         gecko_name="Display",
                          additional_methods=[Method("transition_count", "usize")]) %>
 
 // TODO(SimonSapin): don't parse `inline-table`, since we don't support it
 <%helpers:longhand name="display" need_clone="True" custom_cascade="${product == 'servo'}">
     <%
         values = """inline block inline-block
             table inline-table table-row-group table-header-group table-footer-group
             table-row table-column-group table-column table-cell table-caption
--- a/servo/components/style/properties/longhand/color.mako.rs
+++ b/servo/components/style/properties/longhand/color.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Color", inherited=True, gecko_ffi_name="nsStyleColor") %>
+<% data.new_style_struct("Color", inherited=True) %>
 
 <%helpers:raw_longhand name="color" need_clone="True">
     use cssparser::Color as CSSParserColor;
     use cssparser::RGBA;
     use values::specified::{CSSColor, CSSRGBA};
 
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
--- a/servo/components/style/properties/longhand/column.mako.rs
+++ b/servo/components/style/properties/longhand/column.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Column", inherited=False, gecko_ffi_name="nsStyleColumn") %>
+<% data.new_style_struct("Column", inherited=False) %>
 
 <%helpers:longhand name="column-width" experimental="True">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
 
     #[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
     pub enum SpecifiedValue {
--- a/servo/components/style/properties/longhand/counters.mako.rs
+++ b/servo/components/style/properties/longhand/counters.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Counters", inherited=False, gecko_ffi_name="nsStyleContent") %>
+<% data.new_style_struct("Counters", inherited=False, gecko_name="Content") %>
 
 <%helpers:longhand name="content">
     use cssparser::Token;
     use std::ascii::AsciiExt;
     use values::computed::ComputedValueAsSpecified;
 
     use super::list_style_type;
 
--- a/servo/components/style/properties/longhand/effects.mako.rs
+++ b/servo/components/style/properties/longhand/effects.mako.rs
@@ -1,16 +1,16 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
 // Box-shadow, etc.
-<% data.new_style_struct("Effects", inherited=False, gecko_ffi_name="nsStyleEffects") %>
+<% data.new_style_struct("Effects", inherited=False) %>
 
 <%helpers:longhand name="opacity">
     use cssparser::ToCss;
     use std::fmt;
     use values::CSSFloat;
 
     impl ToCss for SpecifiedValue {
         fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -2,17 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Method %>
 
 <% data.new_style_struct("Font",
                          inherited=True,
-                         gecko_ffi_name="nsStyleFont",
                          additional_methods=[Method("compute_font_hash", is_mut=True)]) %>
 <%helpers:longhand name="font-family">
     use self::computed_value::FontFamily;
     use values::computed::ComputedValueAsSpecified;
     pub use self::computed_value::T as SpecifiedValue;
 
     const SERIF: &'static str = "serif";
     const SANS_SERIF: &'static str = "sans-serif";
--- a/servo/components/style/properties/longhand/inherited_box.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_box.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("InheritedBox", inherited=True, gecko_ffi_name="nsStyleVisibility") %>
+<% data.new_style_struct("InheritedBox", inherited=True, gecko_name="Visibility") %>
 
 ${helpers.single_keyword("direction", "ltr rtl", need_clone=True)}
 
 // TODO: collapse. Well, do tables first.
 ${helpers.single_keyword("visibility",
                          "visible hidden",
                          extra_gecko_values="collapse",
                          gecko_ffi_name="mVisible")}
--- a/servo/components/style/properties/longhand/inherited_table.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_table.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
  <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("InheritedTable", inherited=True, gecko_ffi_name="nsStyleTableBorder") %>
+<% data.new_style_struct("InheritedTable", inherited=True, gecko_name="TableBorder") %>
 
 ${helpers.single_keyword("border-collapse", "separate collapse", gecko_constant_prefix="NS_STYLE_BORDER")}
 ${helpers.single_keyword("empty-cells", "show hide", gecko_constant_prefix="NS_STYLE_TABLE_EMPTY_CELLS")}
 ${helpers.single_keyword("caption-side", "top bottom", extra_gecko_values="right left top-outside bottom-outside")}
 
 <%helpers:longhand name="border-spacing">
     use app_units::Au;
     use values::AuExtensionMethods;
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("InheritedText", inherited=True, gecko_ffi_name="nsStyleText") %>
+<% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
 
 <%helpers:longhand name="line-height">
     use cssparser::ToCss;
     use std::fmt;
     use values::AuExtensionMethods;
     use values::CSSFloat;
 
     #[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
--- a/servo/components/style/properties/longhand/list.mako.rs
+++ b/servo/components/style/properties/longhand/list.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("List", inherited=True, gecko_ffi_name="nsStyleList") %>
+<% data.new_style_struct("List", inherited=True) %>
 
 ${helpers.single_keyword("list-style-position", "outside inside")}
 
 // 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
 //
--- a/servo/components/style/properties/longhand/margin.mako.rs
+++ b/servo/components/style/properties/longhand/margin.mako.rs
@@ -1,12 +1,12 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Margin", inherited=False, gecko_ffi_name="nsStyleMargin") %>
+<% data.new_style_struct("Margin", inherited=False) %>
 
 % for side in ["top", "right", "bottom", "left"]:
     ${helpers.predefined_type("margin-" + side, "LengthOrPercentageOrAuto",
                               "computed::LengthOrPercentageOrAuto::Length(Au(0))")}
 % endfor
--- a/servo/components/style/properties/longhand/outline.mako.rs
+++ b/servo/components/style/properties/longhand/outline.mako.rs
@@ -2,17 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Method %>
 
 <% data.new_style_struct("Outline",
                          inherited=False,
-                         gecko_ffi_name="nsStyleOutline",
                          additional_methods=[Method("outline_has_nonzero_width", "bool")]) %>
 
 // TODO(pcwalton): `invert`
 ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor")}
 
 <%helpers:longhand name="outline-style" need_clone="True">
     pub use values::specified::BorderStyle as SpecifiedValue;
     pub fn get_initial_value() -> SpecifiedValue { SpecifiedValue::none }
--- a/servo/components/style/properties/longhand/padding.mako.rs
+++ b/servo/components/style/properties/longhand/padding.mako.rs
@@ -1,13 +1,13 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Padding", inherited=False, gecko_ffi_name="nsStylePadding") %>
+<% data.new_style_struct("Padding", inherited=False) %>
 
 % for side in ["top", "right", "bottom", "left"]:
     ${helpers.predefined_type("padding-" + side, "LengthOrPercentage",
                                "computed::LengthOrPercentage::Length(Au(0))",
                                "parse_non_negative")}
 % endfor
--- a/servo/components/style/properties/longhand/pointing.mako.rs
+++ b/servo/components/style/properties/longhand/pointing.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Pointing", inherited=True, gecko_ffi_name="nsStyleUserInterface") %>
+<% data.new_style_struct("Pointing", inherited=True, gecko_name="UserInterface") %>
 
 <%helpers:longhand name="cursor">
     pub use self::computed_value::T as SpecifiedValue;
     use values::computed::ComputedValueAsSpecified;
 
     impl ComputedValueAsSpecified for SpecifiedValue {}
 
     pub mod computed_value {
--- a/servo/components/style/properties/longhand/position.mako.rs
+++ b/servo/components/style/properties/longhand/position.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Position", inherited=False, gecko_ffi_name="nsStylePosition") %>
+<% data.new_style_struct("Position", inherited=False) %>
 
 % for side in ["top", "right", "bottom", "left"]:
     ${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
                               "computed::LengthOrPercentageOrAuto::Auto")}
 % endfor
 
 <%helpers:longhand name="z-index">
     use values::computed::ComputedValueAsSpecified;
--- a/servo/components/style/properties/longhand/svg.mako.rs
+++ b/servo/components/style/properties/longhand/svg.mako.rs
@@ -1,15 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("SVG", inherited=False, gecko_ffi_name="nsStyleSVGReset") %>
+<% data.new_style_struct("SVG", inherited=False, gecko_name="SVGReset") %>
 
 ${helpers.single_keyword("dominant-baseline",
                  """auto use-script no-change reset-size ideographic alphabetic hanging
                     mathematical central middle text-after-edge text-before-edge""",
                  products="gecko")}
 
 ${helpers.single_keyword("vector-effect", "none non-scaling-stroke", products="gecko")}
 
--- a/servo/components/style/properties/longhand/svg_inherited.mako.rs
+++ b/servo/components/style/properties/longhand/svg_inherited.mako.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://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("SVGInherited",
                          inherited=True,
-                         gecko_ffi_name="nsStyleSVG") %>
+                         gecko_name="SVG") %>
 
 // Section 10 - Text
 
 ${helpers.single_keyword("text-anchor", "start middle end", products="gecko")}
 
 // Section 11 - Painting: Filling, Stroking and Marker Symbols
 ${helpers.single_keyword("color-interpolation", "auto sRGB linearRGB", products="gecko")}
 
--- a/servo/components/style/properties/longhand/table.mako.rs
+++ b/servo/components/style/properties/longhand/table.mako.rs
@@ -1,9 +1,9 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
-<% data.new_style_struct("Table", inherited=False, gecko_ffi_name="nsStyleTable") %>
+<% data.new_style_struct("Table", inherited=False) %>
 
 ${helpers.single_keyword("table-layout", "auto fixed", gecko_ffi_name="mLayoutStrategy")}
--- a/servo/components/style/properties/longhand/text.mako.rs
+++ b/servo/components/style/properties/longhand/text.mako.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Method %>
 
 <% data.new_style_struct("Text",
                          inherited=False,
-                         gecko_ffi_name="nsStyleTextReset",
+                         gecko_name="TextReset",
                          additional_methods=[Method("has_underline", "bool"),
                                              Method("has_overline", "bool"),
                                              Method("has_line_through", "bool")]) %>
 
 ${helpers.single_keyword("text-overflow", "clip ellipsis")}
 
 ${helpers.single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext")}
 
new file mode 100644
--- /dev/null
+++ b/servo/components/style/properties/longhand/ui.mako.rs
@@ -0,0 +1,13 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+<%namespace name="helpers" file="/helpers.mako.rs" />
+<% from data import 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") %>
+
+${helpers.single_keyword("ime-mode", "normal auto active disabled inactive", products="gecko",
+                         gecko_ffi_name="mIMEMode")}
new file mode 100644
--- /dev/null
+++ b/servo/components/style/properties/longhand/xul.mako.rs
@@ -0,0 +1,12 @@
+/* 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 http://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", products="gecko",
+                         gecko_ffi_name="mBoxAlign", gecko_constant_prefix="NS_STYLE_BOX_ALIGN")}
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -61,18 +61,20 @@ pub mod longhands {
     <%include file="/longhand/list.mako.rs" />
     <%include file="/longhand/margin.mako.rs" />
     <%include file="/longhand/outline.mako.rs" />
     <%include file="/longhand/padding.mako.rs" />
     <%include file="/longhand/pointing.mako.rs" />
     <%include file="/longhand/position.mako.rs" />
     <%include file="/longhand/table.mako.rs" />
     <%include file="/longhand/text.mako.rs" />
+    <%include file="/longhand/ui.mako.rs" />
     <%include file="/longhand/svg_inherited.mako.rs" />
     <%include file="/longhand/svg.mako.rs" />
+    <%include file="/longhand/xul.mako.rs" />
 }
 
 
 pub mod shorthands {
     use cssparser::Parser;
     use parser::ParserContext;
     use values::specified;
 
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -87,39 +87,39 @@ pub extern "C" fn Servo_StylesheetFromUT
     // FIXME(heycam): Pass in the real base URL and sheet origin to use.
     let url = Url::parse("about:none").unwrap();
     let sheet = Arc::new(Stylesheet::from_str(input, url, Origin::Author, Box::new(StdoutErrorReporter)));
     unsafe {
         transmute(sheet)
     }
 }
 
-struct ArcHelpers<GeckoType, ServoType> {
+pub struct ArcHelpers<GeckoType, ServoType> {
     phantom1: PhantomData<GeckoType>,
     phantom2: PhantomData<ServoType>,
 }
 
 impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
-    fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
-                       where F: FnOnce(&Arc<ServoType>) -> Output {
+    pub fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
+                           where F: FnOnce(&Arc<ServoType>) -> Output {
         let owned = unsafe { Self::into(raw) };
         let result = cb(&owned);
         forget(owned);
         result
     }
 
-    unsafe fn into(ptr: *mut GeckoType) -> Arc<ServoType> {
+    pub unsafe fn into(ptr: *mut GeckoType) -> Arc<ServoType> {
         transmute(ptr)
     }
 
-    unsafe fn addref(ptr: *mut GeckoType) {
+    pub unsafe fn addref(ptr: *mut GeckoType) {
         Self::with(ptr, |arc| forget(arc.clone()));
     }
 
-    unsafe fn release(ptr: *mut GeckoType) {
+    pub unsafe fn release(ptr: *mut GeckoType) {
         let _ = Self::into(ptr);
     }
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet,
                                          raw_data: *mut RawServoStyleSet) {
     type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
--- a/servo/ports/geckolib/properties.mako.rs
+++ b/servo/ports/geckolib/properties.mako.rs
@@ -6,24 +6,23 @@
 
 <%!
     from data import to_rust_ident
     from data import Keyword
 %>
 
 use app_units::Au;
 % for style_struct in data.style_structs:
-%if style_struct.gecko_ffi_name:
 use gecko_style_structs::${style_struct.gecko_ffi_name};
 use bindings::Gecko_Construct_${style_struct.gecko_ffi_name};
 use bindings::Gecko_CopyConstruct_${style_struct.gecko_ffi_name};
 use bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
-% endif
 % endfor
 use gecko_style_structs;
+use glue::ArcHelpers;
 use heapsize::HeapSizeOf;
 use std::fmt::{self, Debug};
 use std::mem::{transmute, zeroed};
 use std::sync::Arc;
 use style::custom_properties::ComputedValuesMap;
 use style::logical_geometry::WritingMode;
 use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
 use style::properties::longhands;
@@ -98,23 +97,19 @@ impl ComputedValues for GeckoComputedVal
 
     // FIXME(bholley): Implement this properly.
     #[inline]
     fn is_multicol(&self) -> bool { false }
 }
 
 <%def name="declare_style_struct(style_struct)">
 #[derive(Clone, HeapSizeOf, Debug)]
-% if style_struct.gecko_ffi_name:
 pub struct ${style_struct.gecko_struct_name} {
     gecko: ${style_struct.gecko_ffi_name},
 }
-% else:
-pub struct ${style_struct.gecko_struct_name};
-% endif
 </%def>
 
 <%def name="impl_simple_copy(ident, gecko_ffi_name)">
     fn copy_${ident}_from(&mut self, other: &Self) {
         self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
     }
 </%def>
 
@@ -187,18 +182,20 @@ impl ${style_struct.gecko_struct_name} {
     #[allow(dead_code, unused_variables)]
     fn initial() -> Arc<Self> {
         let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: unsafe { zeroed() } });
         unsafe {
             Gecko_Construct_${style_struct.gecko_ffi_name}(&mut Arc::make_mut(&mut result).gecko);
         }
         result
     }
+    pub fn get_gecko(&self) -> &${style_struct.gecko_ffi_name} {
+        &self.gecko
+    }
 }
-%if style_struct.gecko_ffi_name:
 impl Drop for ${style_struct.gecko_struct_name} {
     fn drop(&mut self) {
         unsafe {
             Gecko_Destroy_${style_struct.gecko_ffi_name}(&mut self.gecko);
         }
     }
 }
 impl Clone for ${style_struct.gecko_ffi_name} {
@@ -222,17 +219,16 @@ impl HeapSizeOf for ${style_struct.gecko
                                     "nsStyleFont nsStyleEffects nsStyleSVGReset".split():
 impl Debug for ${style_struct.gecko_ffi_name} {
     // FIXME(bholley): Generate this.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "GECKO STYLE STRUCT")
     }
 }
 %endif
-%endif
 </%def>
 
 <%def name="raw_impl_trait(style_struct, skip_longhands='', skip_additionals='')">
 <%
    longhands = [x for x in style_struct.longhands if not x.name in skip_longhands.split()]
 
    #
    # Make a list of types we can't auto-generate.
@@ -401,22 +397,34 @@ for side in SIDES:
             gss::${overflow_x.keyword.gecko_constant(value)} => NewType(BaseType::${to_rust_ident(value)}),
             % endfor
             x => panic!("Found unexpected value in style struct for overflow_y property: {}", x),
         }
     }
 
 </%self:impl_trait>
 
+<%def name="define_ffi_struct_accessor(style_struct)">
+#[no_mangle]
+#[allow(non_snake_case, unused_variables)]
+pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: *mut ServoComputedValues)
+  -> *const ${style_struct.gecko_ffi_name} {
+    type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
+    Helpers::with(computed_values, |values| values.get_${style_struct.trait_name_lower}().get_gecko()
+                                                as *const ${style_struct.gecko_ffi_name})
+}
+</%def>
+
 % for style_struct in data.style_structs:
 ${declare_style_struct(style_struct)}
 ${impl_style_struct(style_struct)}
 % if not style_struct.trait_name in data.manual_style_structs:
 <%self:raw_impl_trait style_struct="${style_struct}"></%self:raw_impl_trait>
 % endif
+${define_ffi_struct_accessor(style_struct)}
 % endfor
 
 lazy_static! {
     pub static ref INITIAL_GECKO_VALUES: GeckoComputedValues = GeckoComputedValues {
         % for style_struct in data.style_structs:
            ${style_struct.ident}: ${style_struct.gecko_struct_name}::initial(),
         % endfor
         custom_properties: None,