Extract some Python code from properties.mako.rs into a separate file.

This commit is contained in:
Simon Sapin 2016-04-18 17:55:58 +02:00
parent ff5478cba9
commit 2d8c17e600
6 changed files with 330 additions and 305 deletions

View file

@ -35,7 +35,7 @@ fn main() {
let status = Command::new(python) let status = Command::new(python)
.arg(&script) .arg(&script)
.arg(product) .arg(product)
.arg("rust") .arg("style-crate")
.status() .status()
.unwrap(); .unwrap();
if !status.success() { if !status.success() {

View file

@ -13,21 +13,28 @@ sys.path.insert(0, os.path.join(BASE, "Mako-0.9.1.zip"))
from mako import exceptions from mako import exceptions
from mako.template import Template from mako.template import Template
import data
def main(): def main():
usage = "Usage: %s [ servo | gecko ] [ rust | html ]" % sys.argv[0] usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib | html ]" % sys.argv[0]
if len(sys.argv) < 3: if len(sys.argv) < 3:
abort(usage) abort(usage)
product = sys.argv[1] product = sys.argv[1]
output = sys.argv[2] output = sys.argv[2]
if product not in ["servo", "gecko"] or output not in ["rust", "html"]: if product not in ["servo", "gecko"] or output not in ["style-crate", "geckolib", "html"]:
abort(usage) abort(usage)
template, rust = render("properties.mako.rs", PRODUCT=product) properties = data.PropertiesData(product=product)
if output == "rust": rust = render(os.path.join(BASE, "properties.mako.rs"), product=product, data=properties)
if output == "style-crate":
write(os.environ["OUT_DIR"], "properties.rs", rust)
if output == "geckolib":
template = os.path.join(BASE, "..", "..", "..", "ports", "geckolib", "properties.mako.rs")
rust = render(template, data=properties)
write(os.environ["OUT_DIR"], "properties.rs", rust) write(os.environ["OUT_DIR"], "properties.rs", rust)
elif output == "html": elif output == "html":
write_html(template) write_html(properties)
def abort(message): def abort(message):
@ -35,11 +42,18 @@ def abort(message):
sys.exit(1) sys.exit(1)
def render(name, **context): def render(filename, **context):
try: try:
template = Template(open(os.path.join(BASE, name), "rb").read(), input_encoding="utf8") template = Template(open(filename, "rb").read(),
return template, template.render(**context).encode("utf8") input_encoding="utf8",
strict_undefined=True,
filename=filename)
# Uncomment to debug generated Python code:
#write("/tmp", "mako_%s.py" % os.path.basename(filename), template.code)
return template.render(**context).encode("utf8")
except: except:
# Uncomment to see a traceback in generated Python code:
#raise
abort(exceptions.text_error_template().render().encode("utf8")) abort(exceptions.text_error_template().render().encode("utf8"))
@ -49,19 +63,18 @@ def write(directory, filename, content):
open(os.path.join(directory, filename), "wb").write(content) open(os.path.join(directory, filename), "wb").write(content)
def write_html(template): def write_html(properties):
properties = dict( properties = dict(
(p.name, { (p.name, {
"flag": p.experimental, "flag": p.experimental,
"shorthand": hasattr(p, "sub_properties") "shorthand": hasattr(p, "sub_properties")
}) })
for p in template.module.LONGHANDS + template.module.SHORTHANDS for p in properties.longhands + properties.shorthands
) )
_, html = render("properties.html.mako", properties=properties)
doc_servo = os.path.join(BASE, "..", "..", "..", "target", "doc", "servo") doc_servo = os.path.join(BASE, "..", "..", "..", "target", "doc", "servo")
write(doc_servo, "css-properties.json", json.dumps(properties, indent=4)) html = render(os.path.join(BASE, "properties.html.mako"), properties=properties)
write(doc_servo, "css-properties.html", html) write(doc_servo, "css-properties.html", html)
write(doc_servo, "css-properties.json", json.dumps(properties, indent=4))
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -0,0 +1,158 @@
# 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/.
import re
def to_rust_ident(name):
name = name.replace("-", "_")
if name in ["static", "super", "box", "move"]: # Rust keywords
name += "_"
return name
def to_camel_case(ident):
return re.sub("_([a-z])", lambda m: m.group(1).upper(), ident.strip("_").capitalize())
class Keyword(object):
def __init__(self, name, values, gecko_constant_prefix=None,
extra_gecko_values=None, extra_servo_values=None):
self.name = name
self.values = values
self.gecko_constant_prefix = gecko_constant_prefix or \
"NS_STYLE_" + self.name.upper().replace("-", "_")
self.extra_gecko_values = (extra_gecko_values or "").split()
self.extra_servo_values = (extra_servo_values or "").split()
def gecko_values(self):
return self.values + self.extra_gecko_values
def servo_values(self):
return self.values + self.extra_servo_values
def values_for(self, product):
if product == "gecko":
return self.gecko_values()
elif product == "servo":
return self.servo_values()
else:
raise Exception("Bad product: " + product)
def gecko_constant(self, value):
return self.gecko_constant_prefix + "_" + value.upper().replace("-", "_")
class Longhand(object):
def __init__(self, style_struct, name, derived_from=None, keyword=None,
custom_cascade=False, experimental=False, internal=False,
gecko_ffi_name=None):
self.name = name
self.keyword = keyword
self.ident = to_rust_ident(name)
self.camel_case = to_camel_case(self.ident)
self.style_struct = style_struct
self.experimental = ("layout.%s.enabled" % name) if experimental else None
self.custom_cascade = custom_cascade
self.internal = internal
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
self.derived_from = (derived_from or "").split()
class Shorthand(object):
def __init__(self, name, sub_properties, experimental=False, internal=False):
self.name = name
self.ident = to_rust_ident(name)
self.camel_case = to_camel_case(self.ident)
self.derived_from = None
self.experimental = ("layout.%s.enabled" % name) if experimental else None
self.sub_properties = sub_properties
self.internal = internal
class Method(object):
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):
self.name = name
self.return_type = return_type
self.arg_types = arg_types or []
self.is_mut = is_mut
def arg_list(self):
args = ["_: " + x for x in self.arg_types]
args = ["&mut self" if self.is_mut else "&self"] + args
return ", ".join(args)
def signature(self):
sig = "fn %s(%s)" % (self.name, self.arg_list())
if self.return_type:
sig = sig + " -> " + self.return_type
return sig
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):
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.additional_methods = additional_methods or []
class PropertiesData(object):
def __init__(self, product):
self.product = product
self.style_structs = []
self.current_style_struct = None
self.longhands = []
self.longhands_by_name = {}
self.derived_longhands = {}
self.shorthands = []
def new_style_struct(self, *args, **kwargs):
style_struct = StyleStruct(*args, **kwargs)
self.style_structs.append(style_struct)
self.current_style_struct = style_struct
def active_style_structs(self):
return [s for s in self.style_structs if s.additional_methods or s.longhands]
def switch_to_style_struct(self, name):
for style_struct in self.style_structs:
if style_struct.trait_name == name:
self.current_style_struct = style_struct
return
raise Exception("Failed to find the struct named " + name)
def declare_longhand(self, name, products="gecko servo", **kwargs):
products = products.split()
if not self.product in products:
return
longand = Longhand(self.current_style_struct, name, **kwargs)
self.current_style_struct.longhands.append(longand)
self.longhands.append(longand)
self.longhands_by_name[name] = longand
for name in longand.derived_from:
self.derived_longhands.setdefault(name, []).append(longand)
return longand
def declare_shorthand(self, name, sub_properties, *args, **kwargs):
sub_properties = [self.longhands_by_name[s] for s in sub_properties]
shorthand = Shorthand(name, sub_properties, *args, **kwargs)
self.shorthands.append(shorthand)
return shorthand

View file

@ -37,160 +37,19 @@ use values::specified::BorderStyle;
use self::property_bit_field::PropertyBitField; use self::property_bit_field::PropertyBitField;
<%! <%!
from data import Method, Keyword, to_rust_ident
import re
def to_rust_ident(name):
name = name.replace("-", "_")
if name in ["static", "super", "box", "move"]: # Rust keywords
name += "_"
return name
def to_camel_case(ident):
return re.sub("_([a-z])", lambda m: m.group(1).upper(), ident.strip("_").capitalize())
class Keyword(object):
def __init__(self, name, values, gecko_constant_prefix=None,
extra_gecko_values=None, extra_servo_values=None, **kwargs):
self.name = name
self.values = values
self.gecko_constant_prefix = gecko_constant_prefix or "NS_STYLE_" + self.name.upper().replace("-", "_")
self.extra_gecko_values = (extra_gecko_values or "").split()
self.extra_servo_values = (extra_servo_values or "").split()
def gecko_values(self):
return self.values + self.extra_gecko_values
def servo_values(self):
return self.values + self.extra_servo_values
def values_for(self, product):
if product == "gecko":
return self.gecko_values()
elif product == "servo":
return self.servo_values()
else:
raise Exception("Bad product: " + product)
def gecko_constant(self, value):
return self.gecko_constant_prefix + "_" + value.upper().replace("-", "_")
class Longhand(object):
def __init__(self, name, derived_from=None, keyword=None,
custom_cascade=False, experimental=False, internal=False,
gecko_ffi_name=None, **kwargs):
self.name = name
self.keyword = keyword
self.ident = to_rust_ident(name)
self.camel_case = to_camel_case(self.ident)
self.style_struct = THIS_STYLE_STRUCT
self.experimental = ("layout.%s.enabled" % name) if experimental else None
self.custom_cascade = custom_cascade
self.internal = internal
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
self.derived_from = (derived_from or "").split()
class Shorthand(object):
def __init__(self, name, sub_properties, experimental=False, internal=False):
self.name = name
self.ident = to_rust_ident(name)
self.camel_case = to_camel_case(self.ident)
self.derived_from = None
self.experimental = ("layout.%s.enabled" % name) if experimental else None
self.sub_properties = [LONGHANDS_BY_NAME[s] for s in sub_properties]
self.internal = internal
class Method(object):
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):
self.name = name
self.return_type = return_type
self.arg_types = arg_types or []
self.is_mut = is_mut
def arg_list(self):
args = ["_: " + x for x in self.arg_types]
args = ["&mut self" if self.is_mut else "&self"] + args
return ", ".join(args)
def signature(self):
sig = "fn %s(%s)" % (self.name, self.arg_list())
if self.return_type:
sig = sig + " -> " + self.return_type
return sig
def declare(self):
return self.signature() + ";"
def stub(self):
return self.signature() + "{ unimplemented!() }"
class StyleStruct(object):
def __init__(self, name, inherited, gecko_ffi_name, additional_methods):
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.additional_methods = additional_methods or []
STYLE_STRUCTS = []
THIS_STYLE_STRUCT = None
LONGHANDS = []
LONGHANDS_BY_NAME = {}
DERIVED_LONGHANDS = {}
SHORTHANDS = []
CONFIG = {}
def set_product(p):
global CONFIG
CONFIG['product'] = p
def new_style_struct(name, is_inherited, gecko_name=None, additional_methods=None):
global THIS_STYLE_STRUCT
style_struct = StyleStruct(name, is_inherited, gecko_name, additional_methods)
STYLE_STRUCTS.append(style_struct)
THIS_STYLE_STRUCT = style_struct
return ""
def active_style_structs():
return filter(lambda s: s.additional_methods or s.longhands, STYLE_STRUCTS)
def switch_to_style_struct(name):
global THIS_STYLE_STRUCT
for style_struct in STYLE_STRUCTS:
if style_struct.trait_name == name:
THIS_STYLE_STRUCT = style_struct
return ""
raise Exception("Failed to find the struct named " + name)
%> %>
// Work around Mako's really annoying namespacing setup.
//
// The above code runs when the template is loaded, rather than when it's
// rendered, so it can create global variables, doesn't have access to
// arguments passed to render(). On the flip side, there are various situations,
// such as code in the body of a def-used-as-tag, where our python code has
// access to global variables but not to render() arguments. Hack around this
// by stashing render arguments in a global.
<% CONFIG['product'] = PRODUCT %>
pub mod longhands { pub mod longhands {
use cssparser::Parser; use cssparser::Parser;
use parser::ParserContext; use parser::ParserContext;
use values::specified; use values::specified;
<%def name="raw_longhand(name, **kwargs)"> <%def name="raw_longhand(*args, **kwargs)">
<% <%
products = kwargs.pop("products", "gecko servo").split() property = data.declare_longhand(*args, **kwargs)
if not CONFIG["product"] in products: if property is None:
return "" return ""
property = Longhand(name, **kwargs)
property.style_struct = THIS_STYLE_STRUCT
THIS_STYLE_STRUCT.longhands.append(property)
LONGHANDS.append(property)
LONGHANDS_BY_NAME[name] = property
for derived in property.derived_from:
DERIVED_LONGHANDS.setdefault(derived, []).append(property)
%> %>
pub mod ${property.ident} { pub mod ${property.ident} {
#![allow(unused_imports)] #![allow(unused_imports)]
@ -203,7 +62,7 @@ pub mod longhands {
use properties::longhands; use properties::longhands;
use properties::property_bit_field::PropertyBitField; use properties::property_bit_field::PropertyBitField;
use properties::{ComputedValues, ServoComputedValues, PropertyDeclaration}; use properties::{ComputedValues, ServoComputedValues, PropertyDeclaration};
use properties::style_struct_traits::${THIS_STYLE_STRUCT.trait_name}; use properties::style_struct_traits::${data.current_style_struct.trait_name};
use properties::style_structs; use properties::style_structs;
use std::boxed::Box as StdBox; use std::boxed::Box as StdBox;
use std::collections::HashMap; use std::collections::HashMap;
@ -237,7 +96,7 @@ pub mod longhands {
declared_value, &custom_props, |value| match *value { declared_value, &custom_props, |value| match *value {
DeclaredValue::Value(ref specified_value) => { DeclaredValue::Value(ref specified_value) => {
let computed = specified_value.to_computed_value(context); let computed = specified_value.to_computed_value(context);
context.mutate_style().mutate_${THIS_STYLE_STRUCT.trait_name_lower}() context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
.set_${property.ident}(computed); .set_${property.ident}(computed);
} }
DeclaredValue::WithVariables { .. } => unreachable!(), DeclaredValue::WithVariables { .. } => unreachable!(),
@ -245,8 +104,8 @@ pub mod longhands {
// We assume that it's faster to use copy_*_from rather than // We assume that it's faster to use copy_*_from rather than
// set_*(get_initial_value()); // set_*(get_initial_value());
let initial_struct = C::initial_values() let initial_struct = C::initial_values()
.get_${THIS_STYLE_STRUCT.trait_name_lower}(); .get_${data.current_style_struct.trait_name_lower}();
context.mutate_style().mutate_${THIS_STYLE_STRUCT.trait_name_lower}() context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
.copy_${property.ident}_from(initial_struct); .copy_${property.ident}_from(initial_struct);
}, },
DeclaredValue::Inherit => { DeclaredValue::Inherit => {
@ -255,8 +114,8 @@ pub mod longhands {
// //
// FIXME: is it still? // FIXME: is it still?
*cacheable = false; *cacheable = false;
let inherited_struct = inherited_style.get_${THIS_STYLE_STRUCT.trait_name_lower}(); let inherited_struct = inherited_style.get_${data.current_style_struct.trait_name_lower}();
context.mutate_style().mutate_${THIS_STYLE_STRUCT.trait_name_lower}() context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
.copy_${property.ident}_from(inherited_struct); .copy_${property.ident}_from(inherited_struct);
} }
}, error_reporter }, error_reporter
@ -282,7 +141,7 @@ pub mod longhands {
Ok(CSSWideKeyword::InheritKeyword) => Ok(DeclaredValue::Inherit), Ok(CSSWideKeyword::InheritKeyword) => Ok(DeclaredValue::Inherit),
Ok(CSSWideKeyword::InitialKeyword) => Ok(DeclaredValue::Initial), Ok(CSSWideKeyword::InitialKeyword) => Ok(DeclaredValue::Initial),
Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::${ Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::${
"Inherit" if THIS_STYLE_STRUCT.inherited else "Initial"}), "Inherit" if data.current_style_struct.inherited else "Initial"}),
Err(()) => { Err(()) => {
input.look_for_var_functions(); input.look_for_var_functions();
let start = input.position(); let start = input.position();
@ -313,7 +172,7 @@ pub mod longhands {
<%def name="longhand(name, **kwargs)"> <%def name="longhand(name, **kwargs)">
<%call expr="raw_longhand(name, **kwargs)"> <%call expr="raw_longhand(name, **kwargs)">
${caller.body()} ${caller.body()}
% if not LONGHANDS_BY_NAME[name].derived_from: % if not data.longhands_by_name[name].derived_from:
pub fn parse_specified(context: &ParserContext, input: &mut Parser) pub fn parse_specified(context: &ParserContext, input: &mut Parser)
-> Result<DeclaredValue<SpecifiedValue>, ()> { -> Result<DeclaredValue<SpecifiedValue>, ()> {
parse(context, input).map(DeclaredValue::Value) parse(context, input).map(DeclaredValue::Value)
@ -323,12 +182,17 @@ pub mod longhands {
</%def> </%def>
<%def name="single_keyword_computed(name, values, **kwargs)"> <%def name="single_keyword_computed(name, values, **kwargs)">
<%call expr="longhand(name, keyword=Keyword(name, values.split(), **kwargs), **kwargs)"> <%
keyword_kwargs = {a: kwargs.pop(a, None) for a in [
'gecko_constant_prefix', 'extra_gecko_values', 'extra_servo_values'
]}
%>
<%call expr="longhand(name, keyword=Keyword(name, values.split(), **keyword_kwargs), **kwargs)">
pub use self::computed_value::T as SpecifiedValue; pub use self::computed_value::T as SpecifiedValue;
${caller.body()} ${caller.body()}
pub mod computed_value { pub mod computed_value {
define_css_keyword_enum! { T: define_css_keyword_enum! { T:
% for value in LONGHANDS_BY_NAME[name].keyword.values_for(CONFIG['product']): % for value in data.longhands_by_name[name].keyword.values_for(product):
"${value}" => ${to_rust_ident(value)}, "${value}" => ${to_rust_ident(value)},
% endfor % endfor
} }
@ -369,14 +233,14 @@ pub mod longhands {
// CSS 2.1, Section 8 - Box model // CSS 2.1, Section 8 - Box model
${new_style_struct("Margin", is_inherited=False, gecko_name="nsStyleMargin")} <% data.new_style_struct("Margin", inherited=False, gecko_ffi_name="nsStyleMargin") %>
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
${predefined_type("margin-" + side, "LengthOrPercentageOrAuto", ${predefined_type("margin-" + side, "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Length(Au(0))")} "computed::LengthOrPercentageOrAuto::Length(Au(0))")}
% endfor % endfor
${new_style_struct("Padding", is_inherited=False, gecko_name="nsStylePadding")} <% data.new_style_struct("Padding", inherited=False, gecko_ffi_name="nsStylePadding") %>
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
${predefined_type("padding-" + side, "LengthOrPercentage", ${predefined_type("padding-" + side, "LengthOrPercentage",
@ -384,9 +248,9 @@ pub mod longhands {
"parse_non_negative")} "parse_non_negative")}
% endfor % endfor
${new_style_struct("Border", is_inherited=False, gecko_name="nsStyleBorder", <% data.new_style_struct("Border", inherited=False, gecko_ffi_name="nsStyleBorder",
additional_methods=[Method("border_" + side + "_is_none_or_hidden_and_has_nonzero_width", additional_methods=[Method("border_" + side + "_is_none_or_hidden_and_has_nonzero_width",
"bool") for side in ["top", "right", "bottom", "left"]])} "bool") for side in ["top", "right", "bottom", "left"]]) %>
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
${predefined_type("border-%s-color" % side, "CSSColor", "::cssparser::Color::CurrentColor")} ${predefined_type("border-%s-color" % side, "CSSColor", "::cssparser::Color::CurrentColor")}
@ -441,8 +305,8 @@ pub mod longhands {
"parse")} "parse")}
% endfor % endfor
${new_style_struct("Outline", is_inherited=False, gecko_name="nsStyleOutline", <% data.new_style_struct("Outline", inherited=False, gecko_ffi_name="nsStyleOutline",
additional_methods=[Method("outline_is_none_or_hidden_and_has_nonzero_width", "bool")])} additional_methods=[Method("outline_is_none_or_hidden_and_has_nonzero_width", "bool")]) %>
// TODO(pcwalton): `invert` // TODO(pcwalton): `invert`
${predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor")} ${predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor")}
@ -495,7 +359,7 @@ pub mod longhands {
${predefined_type("outline-offset", "Length", "Au(0)")} ${predefined_type("outline-offset", "Length", "Au(0)")}
${new_style_struct("Position", is_inherited=False, gecko_name="nsStylePosition")} <% data.new_style_struct("Position", inherited=False, gecko_ffi_name="nsStylePosition") %>
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
${predefined_type(side, "LengthOrPercentageOrAuto", ${predefined_type(side, "LengthOrPercentageOrAuto",
@ -504,7 +368,7 @@ pub mod longhands {
// CSS 2.1, Section 9 - Visual formatting model // CSS 2.1, Section 9 - Visual formatting model
${new_style_struct("Box", is_inherited=False, gecko_name="nsStyleDisplay", <% data.new_style_struct("Box", inherited=False, gecko_ffi_name="nsStyleDisplay",
additional_methods=[Method("clone_display", additional_methods=[Method("clone_display",
"longhands::display::computed_value::T"), "longhands::display::computed_value::T"),
Method("clone_position", Method("clone_position",
@ -512,10 +376,10 @@ pub mod longhands {
Method("is_floated", "bool"), Method("is_floated", "bool"),
Method("overflow_x_is_visible", "bool"), Method("overflow_x_is_visible", "bool"),
Method("overflow_y_is_visible", "bool"), Method("overflow_y_is_visible", "bool"),
Method("transition_count", "usize")])} Method("transition_count", "usize")]) %>
// TODO(SimonSapin): don't parse `inline-table`, since we don't support it // TODO(SimonSapin): don't parse `inline-table`, since we don't support it
<%self:longhand name="display" custom_cascade="${CONFIG['product'] == 'servo'}"> <%self:longhand name="display" custom_cascade="${product == 'servo'}">
<% <%
values = """inline block inline-block values = """inline block inline-block
table inline-table table-row-group table-header-group table-footer-group table inline-table table-row-group table-header-group table-footer-group
@ -572,7 +436,7 @@ pub mod longhands {
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
% if CONFIG["product"] == "servo": % if product == "servo":
fn cascade_property_custom<C: ComputedValues>( fn cascade_property_custom<C: ComputedValues>(
_declaration: &PropertyDeclaration, _declaration: &PropertyDeclaration,
_inherited_style: &C, _inherited_style: &C,
@ -626,7 +490,7 @@ pub mod longhands {
</%self:longhand> </%self:longhand>
${switch_to_style_struct("Position")} <% data.switch_to_style_struct("Position") %>
<%self:longhand name="z-index"> <%self:longhand name="z-index">
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
@ -674,19 +538,19 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${new_style_struct("InheritedBox", is_inherited=True, gecko_name="nsStyleVisibility", <% data.new_style_struct("InheritedBox", inherited=True, gecko_ffi_name="nsStyleVisibility",
additional_methods=[Method("clone_direction", additional_methods=[Method("clone_direction",
"longhands::direction::computed_value::T"), "longhands::direction::computed_value::T"),
Method("clone_writing_mode", Method("clone_writing_mode",
"longhands::writing_mode::computed_value::T"), "longhands::writing_mode::computed_value::T"),
Method("clone_text_orientation", Method("clone_text_orientation",
"longhands::text_orientation::computed_value::T")])} "longhands::text_orientation::computed_value::T")]) %>
${single_keyword("direction", "ltr rtl")} ${single_keyword("direction", "ltr rtl")}
// CSS 2.1, Section 10 - Visual formatting model details // CSS 2.1, Section 10 - Visual formatting model details
${switch_to_style_struct("Box")} <% data.switch_to_style_struct("Box") %>
${predefined_type("width", "LengthOrPercentageOrAuto", ${predefined_type("width", "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Auto", "computed::LengthOrPercentageOrAuto::Auto",
@ -696,7 +560,7 @@ pub mod longhands {
"computed::LengthOrPercentageOrAuto::Auto", "computed::LengthOrPercentageOrAuto::Auto",
"parse_non_negative")} "parse_non_negative")}
${switch_to_style_struct("Position")} <% data.switch_to_style_struct("Position") %>
${predefined_type("min-width", "LengthOrPercentage", ${predefined_type("min-width", "LengthOrPercentage",
"computed::LengthOrPercentage::Length(Au(0))", "computed::LengthOrPercentage::Length(Au(0))",
@ -712,10 +576,10 @@ pub mod longhands {
"computed::LengthOrPercentageOrNone::None", "computed::LengthOrPercentageOrNone::None",
"parse_non_negative")} "parse_non_negative")}
${new_style_struct("InheritedText", is_inherited=True, gecko_name="nsStyleText", <% data.new_style_struct("InheritedText", inherited=True, gecko_ffi_name="nsStyleText",
additional_methods=([Method("clone__servo_text_decorations_in_effect", additional_methods=([Method("clone__servo_text_decorations_in_effect",
"longhands::_servo_text_decorations_in_effect::computed_value::T")] "longhands::_servo_text_decorations_in_effect::computed_value::T")]
if CONFIG["product"] == "servo" else []))} if product == "servo" else [])) %>
<%self:longhand name="line-height"> <%self:longhand name="line-height">
use cssparser::ToCss; use cssparser::ToCss;
@ -809,7 +673,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${switch_to_style_struct("Box")} <% data.switch_to_style_struct("Box") %>
<%self:longhand name="vertical-align"> <%self:longhand name="vertical-align">
use cssparser::ToCss; use cssparser::ToCss;
@ -962,7 +826,7 @@ pub mod longhands {
// http://www.w3.org/TR/compositing-1/ // http://www.w3.org/TR/compositing-1/
${single_keyword("isolation", "auto isolate", products="gecko")} ${single_keyword("isolation", "auto isolate", products="gecko")}
${switch_to_style_struct("InheritedBox")} <% data.switch_to_style_struct("InheritedBox") %>
// TODO: collapse. Well, do tables first. // TODO: collapse. Well, do tables first.
${single_keyword("visibility", "visible hidden", extra_gecko_values="collapse", ${single_keyword("visibility", "visible hidden", extra_gecko_values="collapse",
@ -970,7 +834,7 @@ pub mod longhands {
// CSS 2.1, Section 12 - Generated content, automatic numbering, and lists // CSS 2.1, Section 12 - Generated content, automatic numbering, and lists
${new_style_struct("Counters", is_inherited=False, gecko_name="nsStyleContent")} <% data.new_style_struct("Counters", inherited=False, gecko_ffi_name="nsStyleContent") %>
<%self:longhand name="content"> <%self:longhand name="content">
use cssparser::Token; use cssparser::Token;
@ -1135,7 +999,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${new_style_struct("List", is_inherited=True, gecko_name="nsStyleList")} <% data.new_style_struct("List", inherited=True, gecko_ffi_name="nsStyleList") %>
${single_keyword("list-style-position", "outside inside")} ${single_keyword("list-style-position", "outside inside")}
@ -1283,7 +1147,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${switch_to_style_struct("Counters")} <% data.switch_to_style_struct("Counters") %>
<%self:longhand name="counter-increment"> <%self:longhand name="counter-increment">
use std::fmt; use std::fmt;
@ -1365,7 +1229,7 @@ pub mod longhands {
// CSS 2.1, Section 13 - Paged media // CSS 2.1, Section 13 - Paged media
${switch_to_style_struct("Box")} <% data.switch_to_style_struct("Box") %>
${single_keyword("page-break-after", "auto always avoid left right", products="gecko")} ${single_keyword("page-break-after", "auto always avoid left right", products="gecko")}
${single_keyword("page-break-before", "auto always avoid left right", products="gecko")} ${single_keyword("page-break-before", "auto always avoid left right", products="gecko")}
@ -1374,7 +1238,7 @@ pub mod longhands {
// CSS 2.1, Section 14 - Colors and Backgrounds // CSS 2.1, Section 14 - Colors and Backgrounds
${new_style_struct("Background", is_inherited=False, gecko_name="nsStyleBackground")} <% data.new_style_struct("Background", inherited=False, gecko_ffi_name="nsStyleBackground") %>
${predefined_type( ${predefined_type(
"background-color", "CSSColor", "background-color", "CSSColor",
"::cssparser::Color::RGBA(::cssparser::RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")} "::cssparser::Color::RGBA(::cssparser::RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")}
@ -1696,9 +1560,9 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${new_style_struct("Color", is_inherited=True, gecko_name="nsStyleColor", <% data.new_style_struct("Color", inherited=True, gecko_ffi_name="nsStyleColor",
additional_methods=[Method("clone_color", additional_methods=[Method("clone_color",
"longhands::color::computed_value::T")])} "longhands::color::computed_value::T")]) %>
<%self:raw_longhand name="color"> <%self:raw_longhand name="color">
use cssparser::Color as CSSParserColor; use cssparser::Color as CSSParserColor;
@ -1738,12 +1602,12 @@ pub mod longhands {
// CSS 2.1, Section 15 - Fonts // CSS 2.1, Section 15 - Fonts
${new_style_struct("Font", is_inherited=True, gecko_name="nsStyleFont", <% data.new_style_struct("Font", inherited=True, gecko_ffi_name="nsStyleFont",
additional_methods=[Method("clone_font_size", additional_methods=[Method("clone_font_size",
"longhands::font_size::computed_value::T"), "longhands::font_size::computed_value::T"),
Method("clone_font_weight", Method("clone_font_weight",
"longhands::font_weight::computed_value::T"), "longhands::font_weight::computed_value::T"),
Method("compute_font_hash", is_mut=True)])} Method("compute_font_hash", is_mut=True)]) %>
<%self:longhand name="font-family"> <%self:longhand name="font-family">
use self::computed_value::FontFamily; use self::computed_value::FontFamily;
@ -2049,7 +1913,7 @@ pub mod longhands {
// CSS 2.1, Section 16 - Text // CSS 2.1, Section 16 - Text
${switch_to_style_struct("InheritedText")} <% data.switch_to_style_struct("InheritedText") %>
<%self:longhand name="text-align"> <%self:longhand name="text-align">
pub use self::computed_value::T as SpecifiedValue; pub use self::computed_value::T as SpecifiedValue;
@ -2241,16 +2105,16 @@ pub mod longhands {
// TODO(pcwalton): Support `text-justify: distribute`. // TODO(pcwalton): Support `text-justify: distribute`.
${single_keyword("text-justify", "auto none inter-word", products="servo")} ${single_keyword("text-justify", "auto none inter-word", products="servo")}
${new_style_struct("Text", is_inherited=False, gecko_name="nsStyleTextReset", <% data.new_style_struct("Text", inherited=False, gecko_ffi_name="nsStyleTextReset",
additional_methods=[Method("has_underline", "bool"), additional_methods=[Method("has_underline", "bool"),
Method("has_overline", "bool"), Method("has_overline", "bool"),
Method("has_line_through", "bool")])} Method("has_line_through", "bool")]) %>
${single_keyword("text-overflow", "clip ellipsis")} ${single_keyword("text-overflow", "clip ellipsis")}
${single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext")} ${single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext")}
<%self:longhand name="text-decoration" custom_cascade="${CONFIG['product'] == 'servo'}"> <%self:longhand name="text-decoration" custom_cascade="${product == 'servo'}">
use cssparser::ToCss; use cssparser::ToCss;
use std::fmt; use std::fmt;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
@ -2325,7 +2189,7 @@ pub mod longhands {
if !empty { Ok(result) } else { Err(()) } if !empty { Ok(result) } else { Err(()) }
} }
% if CONFIG["product"] == "servo": % if product == "servo":
fn cascade_property_custom<C: ComputedValues>( fn cascade_property_custom<C: ComputedValues>(
_declaration: &PropertyDeclaration, _declaration: &PropertyDeclaration,
_inherited_style: &C, _inherited_style: &C,
@ -2341,7 +2205,7 @@ pub mod longhands {
${single_keyword("text-decoration-style", "-moz-none solid double dotted dashed wavy", ${single_keyword("text-decoration-style", "-moz-none solid double dotted dashed wavy",
products="gecko")} products="gecko")}
${switch_to_style_struct("InheritedText")} <% data.switch_to_style_struct("InheritedText") %>
<%self:longhand name="-servo-text-decorations-in-effect" <%self:longhand name="-servo-text-decorations-in-effect"
derived_from="display text-decoration" products="servo"> derived_from="display text-decoration" products="servo">
@ -2479,11 +2343,11 @@ pub mod longhands {
${single_keyword("ruby-position", "over under", products="gecko")} ${single_keyword("ruby-position", "over under", products="gecko")}
// CSS 2.1, Section 17 - Tables // CSS 2.1, Section 17 - Tables
${new_style_struct("Table", is_inherited=False, gecko_name="nsStyleTable")} <% data.new_style_struct("Table", inherited=False, gecko_ffi_name="nsStyleTable") %>
${single_keyword("table-layout", "auto fixed", gecko_ffi_name="mLayoutStrategy")} ${single_keyword("table-layout", "auto fixed", gecko_ffi_name="mLayoutStrategy")}
${new_style_struct("InheritedTable", is_inherited=True, gecko_name="nsStyleTableBorder")} <% data.new_style_struct("InheritedTable", inherited=True, gecko_ffi_name="nsStyleTableBorder") %>
${single_keyword("border-collapse", "separate collapse", gecko_constant_prefix="NS_STYLE_BORDER")} ${single_keyword("border-collapse", "separate collapse", gecko_constant_prefix="NS_STYLE_BORDER")}
@ -2582,13 +2446,13 @@ pub mod longhands {
// CSS Fragmentation Module Level 3 // CSS Fragmentation Module Level 3
// https://www.w3.org/TR/css-break-3/ // https://www.w3.org/TR/css-break-3/
${switch_to_style_struct("Border")} <% data.switch_to_style_struct("Border") %>
${single_keyword("box-decoration-break", "slice clone", products="gecko")} ${single_keyword("box-decoration-break", "slice clone", products="gecko")}
// CSS Writing Modes Level 3 // CSS Writing Modes Level 3
// http://dev.w3.org/csswg/css-writing-modes/ // http://dev.w3.org/csswg/css-writing-modes/
${switch_to_style_struct("InheritedBox")} <% data.switch_to_style_struct("InheritedBox") %>
${single_keyword("writing-mode", "horizontal-tb vertical-rl vertical-lr", experimental=True)} ${single_keyword("writing-mode", "horizontal-tb vertical-rl vertical-lr", experimental=True)}
@ -2602,15 +2466,15 @@ pub mod longhands {
// CSS Basic User Interface Module Level 3 // CSS Basic User Interface Module Level 3
// http://dev.w3.org/csswg/css-ui/ // http://dev.w3.org/csswg/css-ui/
${switch_to_style_struct("Box")} <% data.switch_to_style_struct("Box") %>
${single_keyword("resize", "none both horizontal vertical", products="gecko")} ${single_keyword("resize", "none both horizontal vertical", products="gecko")}
${switch_to_style_struct("Position")} <% data.switch_to_style_struct("Position") %>
${single_keyword("box-sizing", "content-box border-box")} ${single_keyword("box-sizing", "content-box border-box")}
${new_style_struct("Pointing", is_inherited=True, gecko_name="nsStyleUserInterface")} <% data.new_style_struct("Pointing", inherited=True, gecko_ffi_name="nsStyleUserInterface") %>
<%self:longhand name="cursor"> <%self:longhand name="cursor">
pub use self::computed_value::T as SpecifiedValue; pub use self::computed_value::T as SpecifiedValue;
@ -2662,7 +2526,7 @@ pub mod longhands {
${single_keyword("pointer-events", "auto none")} ${single_keyword("pointer-events", "auto none")}
${new_style_struct("Column", is_inherited=False, gecko_name="nsStyleColumn")} <% data.new_style_struct("Column", inherited=False, gecko_ffi_name="nsStyleColumn") %>
<%self:longhand name="column-width" experimental="True"> <%self:longhand name="column-width" experimental="True">
use cssparser::ToCss; use cssparser::ToCss;
@ -2854,7 +2718,7 @@ pub mod longhands {
</%self:longhand> </%self:longhand>
// Box-shadow, etc. // Box-shadow, etc.
${new_style_struct("Effects", is_inherited=False, gecko_name="nsStyleEffects")} <% data.new_style_struct("Effects", inherited=False, gecko_ffi_name="nsStyleEffects") %>
<%self:longhand name="opacity"> <%self:longhand name="opacity">
use cssparser::ToCss; use cssparser::ToCss;
@ -3258,7 +3122,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${switch_to_style_struct("InheritedText")} <% data.switch_to_style_struct("InheritedText") %>
<%self:longhand name="text-shadow"> <%self:longhand name="text-shadow">
use cssparser::{self, ToCss}; use cssparser::{self, ToCss};
@ -3438,7 +3302,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${switch_to_style_struct("Effects")} <% data.switch_to_style_struct("Effects") %>
<%self:longhand name="filter"> <%self:longhand name="filter">
//pub use self::computed_value::T as SpecifiedValue; //pub use self::computed_value::T as SpecifiedValue;
@ -4376,11 +4240,11 @@ pub mod longhands {
// CSS Image Values and Replaced Content Module Level 3 // CSS Image Values and Replaced Content Module Level 3
// https://drafts.csswg.org/css-images-3/ // https://drafts.csswg.org/css-images-3/
${switch_to_style_struct("Position")} <% data.switch_to_style_struct("Position") %>
${single_keyword("object-fit", "fill contain cover none scale-down", products="gecko")} ${single_keyword("object-fit", "fill contain cover none scale-down", products="gecko")}
${switch_to_style_struct("InheritedBox")} <% data.switch_to_style_struct("InheritedBox") %>
<%self:longhand name="image-rendering"> <%self:longhand name="image-rendering">
@ -4437,7 +4301,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${switch_to_style_struct("Box")} <% data.switch_to_style_struct("Box") %>
// TODO(pcwalton): Multiple transitions. // TODO(pcwalton): Multiple transitions.
<%self:longhand name="transition-duration"> <%self:longhand name="transition-duration">
@ -4963,7 +4827,7 @@ pub mod longhands {
// CSS Flexible Box Layout Module Level 1 // CSS Flexible Box Layout Module Level 1
// http://www.w3.org/TR/css3-flexbox/ // http://www.w3.org/TR/css3-flexbox/
${switch_to_style_struct("Position")} <% data.switch_to_style_struct("Position") %>
// Flex container properties // Flex container properties
${single_keyword("flex-direction", "row row-reverse column column-reverse", experimental=True)} ${single_keyword("flex-direction", "row row-reverse column column-reverse", experimental=True)}
@ -4994,7 +4858,7 @@ pub mod longhands {
// SVG 1.1 (Second Edition) // SVG 1.1 (Second Edition)
// https://www.w3.org/TR/SVG/ // https://www.w3.org/TR/SVG/
${new_style_struct("SVGInherited", is_inherited=True, gecko_name="nsStyleSVG")} <% data.new_style_struct("SVGInherited", inherited=True, gecko_ffi_name="nsStyleSVG") %>
// Section 10 - Text // Section 10 - Text
@ -5019,7 +4883,7 @@ pub mod longhands {
${single_keyword("clip-rule", "nonzero evenodd", ${single_keyword("clip-rule", "nonzero evenodd",
products="gecko", gecko_constant_prefix="NS_STYLE_FILL_RULE")} products="gecko", gecko_constant_prefix="NS_STYLE_FILL_RULE")}
${new_style_struct("SVG", is_inherited=False, gecko_name="nsStyleSVGReset")} <% data.new_style_struct("SVG", inherited=False, gecko_ffi_name="nsStyleSVGReset") %>
${single_keyword("dominant-baseline", ${single_keyword("dominant-baseline",
"""auto use-script no-change reset-size ideographic alphabetic hanging """auto use-script no-change reset-size ideographic alphabetic hanging
@ -5041,8 +4905,7 @@ pub mod shorthands {
<%def name="shorthand(name, sub_properties, experimental=False)"> <%def name="shorthand(name, sub_properties, experimental=False)">
<% <%
shorthand = Shorthand(name, sub_properties.split(), experimental=experimental) shorthand = data.declare_shorthand(name, sub_properties.split(), experimental=experimental)
SHORTHANDS.append(shorthand)
%> %>
pub mod ${shorthand.ident} { pub mod ${shorthand.ident} {
use cssparser::Parser; use cssparser::Parser;
@ -5754,13 +5617,13 @@ pub mod shorthands {
mod property_bit_field { mod property_bit_field {
pub struct PropertyBitField { pub struct PropertyBitField {
storage: [u32; (${len(LONGHANDS)} - 1 + 32) / 32] storage: [u32; (${len(data.longhands)} - 1 + 32) / 32]
} }
impl PropertyBitField { impl PropertyBitField {
#[inline] #[inline]
pub fn new() -> PropertyBitField { pub fn new() -> PropertyBitField {
PropertyBitField { storage: [0; (${len(LONGHANDS)} - 1 + 32) / 32] } PropertyBitField { storage: [0; (${len(data.longhands)} - 1 + 32) / 32] }
} }
#[inline] #[inline]
@ -5771,7 +5634,7 @@ mod property_bit_field {
fn set(&mut self, bit: usize) { fn set(&mut self, bit: usize) {
self.storage[bit / 32] |= 1 << (bit % 32) self.storage[bit / 32] |= 1 << (bit % 32)
} }
% for i, property in enumerate(LONGHANDS): % for i, property in enumerate(data.longhands):
% if not property.derived_from: % if not property.derived_from:
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[inline] #[inline]
@ -5788,7 +5651,7 @@ mod property_bit_field {
} }
} }
% for property in LONGHANDS: % for property in data.longhands:
% if not property.derived_from: % if not property.derived_from:
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn substitute_variables_${property.ident}<F>( fn substitute_variables_${property.ident}<F>(
@ -5838,7 +5701,7 @@ mod property_bit_field {
None => { None => {
longhands::${property.ident}::parse_specified(&context, input) longhands::${property.ident}::parse_specified(&context, input)
} }
% for shorthand in SHORTHANDS: % for shorthand in data.shorthands:
% if property in shorthand.sub_properties: % if property in shorthand.sub_properties:
Some(Shorthand::${shorthand.camel_case}) => { Some(Shorthand::${shorthand.camel_case}) => {
shorthands::${shorthand.ident}::parse_value(&context, input) shorthands::${shorthand.ident}::parse_value(&context, input)
@ -5958,7 +5821,7 @@ fn deduplicate_property_declarations(declarations: Vec<PropertyDeclaration>)
let mut seen_custom = Vec::new(); let mut seen_custom = Vec::new();
for declaration in declarations.into_iter().rev() { for declaration in declarations.into_iter().rev() {
match declaration { match declaration {
% for property in LONGHANDS: % for property in data.longhands:
PropertyDeclaration::${property.camel_case}(..) => { PropertyDeclaration::${property.camel_case}(..) => {
% if not property.derived_from: % if not property.derived_from:
if seen.get_${property.ident}() { if seen.get_${property.ident}() {
@ -6003,7 +5866,7 @@ impl CSSWideKeyword {
#[derive(Clone, Copy, Eq, PartialEq, Debug, HeapSizeOf)] #[derive(Clone, Copy, Eq, PartialEq, Debug, HeapSizeOf)]
pub enum Shorthand { pub enum Shorthand {
% for property in SHORTHANDS: % for property in data.shorthands:
${property.camel_case}, ${property.camel_case},
% endfor % endfor
} }
@ -6011,7 +5874,7 @@ pub enum Shorthand {
impl Shorthand { impl Shorthand {
pub fn from_name(name: &str) -> Option<Shorthand> { pub fn from_name(name: &str) -> Option<Shorthand> {
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
% for property in SHORTHANDS: % for property in data.shorthands:
"${property.name}" => Some(Shorthand::${property.camel_case}), "${property.name}" => Some(Shorthand::${property.camel_case}),
% endfor % endfor
_ => None _ => None
@ -6019,7 +5882,7 @@ impl Shorthand {
} }
pub fn longhands(&self) -> &'static [&'static str] { pub fn longhands(&self) -> &'static [&'static str] {
% for property in SHORTHANDS: % for property in data.shorthands:
static ${property.ident.upper()}: &'static [&'static str] = &[ static ${property.ident.upper()}: &'static [&'static str] = &[
% for sub in property.sub_properties: % for sub in property.sub_properties:
"${sub.name}", "${sub.name}",
@ -6027,7 +5890,7 @@ impl Shorthand {
]; ];
% endfor % endfor
match *self { match *self {
% for property in SHORTHANDS: % for property in data.shorthands:
Shorthand::${property.camel_case} => ${property.ident.upper()}, Shorthand::${property.camel_case} => ${property.ident.upper()},
% endfor % endfor
} }
@ -6067,7 +5930,7 @@ impl<T: ToCss> ToCss for DeclaredValue<T> {
#[derive(PartialEq, Clone, Debug, HeapSizeOf)] #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
pub enum PropertyDeclaration { pub enum PropertyDeclaration {
% for property in LONGHANDS: % for property in data.longhands:
${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>), ${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
% endfor % endfor
Custom(::custom_properties::Name, DeclaredValue<::custom_properties::SpecifiedValue>), Custom(::custom_properties::Name, DeclaredValue<::custom_properties::SpecifiedValue>),
@ -6117,7 +5980,7 @@ impl fmt::Display for PropertyDeclarationName {
impl PropertyDeclaration { impl PropertyDeclaration {
pub fn name(&self) -> PropertyDeclarationName { pub fn name(&self) -> PropertyDeclarationName {
match *self { match *self {
% for property in LONGHANDS: % for property in data.longhands:
PropertyDeclaration::${property.camel_case}(..) => PropertyDeclaration::${property.camel_case}(..) =>
% if not property.derived_from: % if not property.derived_from:
PropertyDeclarationName::Longhand("${property.name}"), PropertyDeclarationName::Longhand("${property.name}"),
@ -6133,7 +5996,7 @@ impl PropertyDeclaration {
pub fn value(&self) -> String { pub fn value(&self) -> String {
match *self { match *self {
% for property in LONGHANDS: % for property in data.longhands:
PropertyDeclaration::${property.camel_case} PropertyDeclaration::${property.camel_case}
% if not property.derived_from: % if not property.derived_from:
(ref value) => value.to_css_string(), (ref value) => value.to_css_string(),
@ -6150,7 +6013,7 @@ impl PropertyDeclaration {
// ↓ // ↓
pub fn with_variables_from_shorthand(&self, shorthand: Shorthand) -> Option< &str> { pub fn with_variables_from_shorthand(&self, shorthand: Shorthand) -> Option< &str> {
match *self { match *self {
% for property in LONGHANDS: % for property in data.longhands:
PropertyDeclaration::${property.camel_case}(ref value) => match *value { PropertyDeclaration::${property.camel_case}(ref value) => match *value {
DeclaredValue::WithVariables { ref css, from_shorthand: Some(s), .. } DeclaredValue::WithVariables { ref css, from_shorthand: Some(s), .. }
if s == shorthand => { if s == shorthand => {
@ -6167,7 +6030,7 @@ impl PropertyDeclaration {
/// https://drafts.csswg.org/css-variables/#variables-in-shorthands /// https://drafts.csswg.org/css-variables/#variables-in-shorthands
pub fn with_variables(&self) -> bool { pub fn with_variables(&self) -> bool {
match *self { match *self {
% for property in LONGHANDS: % for property in data.longhands:
PropertyDeclaration::${property.camel_case}(ref value) => match *value { PropertyDeclaration::${property.camel_case}(ref value) => match *value {
DeclaredValue::WithVariables { .. } => true, DeclaredValue::WithVariables { .. } => true,
_ => false, _ => false,
@ -6182,7 +6045,7 @@ impl PropertyDeclaration {
pub fn matches(&self, name: &str) -> bool { pub fn matches(&self, name: &str) -> bool {
match *self { match *self {
% for property in LONGHANDS: % for property in data.longhands:
PropertyDeclaration::${property.camel_case}(..) => PropertyDeclaration::${property.camel_case}(..) =>
% if not property.derived_from: % if not property.derived_from:
name.eq_ignore_ascii_case("${property.name}"), name.eq_ignore_ascii_case("${property.name}"),
@ -6212,7 +6075,7 @@ impl PropertyDeclaration {
return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration; return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration;
} }
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
% for property in LONGHANDS: % for property in data.longhands:
% if not property.derived_from: % if not property.derived_from:
"${property.name}" => { "${property.name}" => {
% if property.internal: % if property.internal:
@ -6238,7 +6101,7 @@ impl PropertyDeclaration {
"${property.name}" => PropertyDeclarationParseResult::UnknownProperty, "${property.name}" => PropertyDeclarationParseResult::UnknownProperty,
% endif % endif
% endfor % endfor
% for shorthand in SHORTHANDS: % for shorthand in data.shorthands:
"${shorthand.name}" => { "${shorthand.name}" => {
% if shorthand.internal: % if shorthand.internal:
if context.stylesheet_origin != Origin::UserAgent { if context.stylesheet_origin != Origin::UserAgent {
@ -6292,7 +6155,7 @@ impl PropertyDeclaration {
pub mod style_struct_traits { pub mod style_struct_traits {
use super::longhands; use super::longhands;
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
pub trait ${style_struct.trait_name}: Clone { pub trait ${style_struct.trait_name}: Clone {
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -6313,7 +6176,7 @@ pub mod style_structs {
use super::longhands; use super::longhands;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
% if style_struct.trait_name == "Font": % if style_struct.trait_name == "Font":
#[derive(Clone, HeapSizeOf, Debug)] #[derive(Clone, HeapSizeOf, Debug)]
% else: % else:
@ -6403,7 +6266,7 @@ pub mod style_structs {
fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T { fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T {
self.text_orientation.clone() self.text_orientation.clone()
} }
% elif style_struct.trait_name == "InheritedText" and CONFIG["product"] == "servo": % elif style_struct.trait_name == "InheritedText" and product == "servo":
fn clone__servo_text_decorations_in_effect(&self) -> fn clone__servo_text_decorations_in_effect(&self) ->
longhands::_servo_text_decorations_in_effect::computed_value::T { longhands::_servo_text_decorations_in_effect::computed_value::T {
self._servo_text_decorations_in_effect.clone() self._servo_text_decorations_in_effect.clone()
@ -6429,7 +6292,7 @@ pub mod style_structs {
} }
pub trait ComputedValues : Clone + Send + Sync + 'static { pub trait ComputedValues : Clone + Send + Sync + 'static {
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
type Concrete${style_struct.trait_name}: style_struct_traits::${style_struct.trait_name}; type Concrete${style_struct.trait_name}: style_struct_traits::${style_struct.trait_name};
% endfor % endfor
@ -6444,7 +6307,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
shareable: bool, shareable: bool,
writing_mode: WritingMode, writing_mode: WritingMode,
root_font_size: Au, root_font_size: Au,
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<Self::Concrete${style_struct.trait_name}>, ${style_struct.ident}: Arc<Self::Concrete${style_struct.trait_name}>,
% endfor % endfor
) -> Self; ) -> Self;
@ -6453,7 +6316,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F); fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F);
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
fn clone_${style_struct.trait_name_lower}(&self) -> fn clone_${style_struct.trait_name_lower}(&self) ->
Arc<Self::Concrete${style_struct.trait_name}>; Arc<Self::Concrete${style_struct.trait_name}>;
fn get_${style_struct.trait_name_lower}<'a>(&'a self) -> fn get_${style_struct.trait_name_lower}<'a>(&'a self) ->
@ -6471,7 +6334,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
#[derive(Clone, HeapSizeOf)] #[derive(Clone, HeapSizeOf)]
pub struct ServoComputedValues { pub struct ServoComputedValues {
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
% endfor % endfor
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>, custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
@ -6481,7 +6344,7 @@ pub struct ServoComputedValues {
} }
impl ComputedValues for ServoComputedValues { impl ComputedValues for ServoComputedValues {
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_name}; type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_name};
% endfor % endfor
@ -6492,7 +6355,7 @@ impl ComputedValues for ServoComputedValues {
shareable: bool, shareable: bool,
writing_mode: WritingMode, writing_mode: WritingMode,
root_font_size: Au, root_font_size: Au,
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
% endfor % endfor
) -> Self { ) -> Self {
@ -6501,7 +6364,7 @@ impl ComputedValues for ServoComputedValues {
shareable: shareable, shareable: shareable,
writing_mode: writing_mode, writing_mode: writing_mode,
root_font_size: root_font_size, root_font_size: root_font_size,
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: ${style_struct.ident}, ${style_struct.ident}: ${style_struct.ident},
% endfor % endfor
} }
@ -6513,7 +6376,7 @@ impl ComputedValues for ServoComputedValues {
CASCADE_PROPERTY.with(|x| f(x)); CASCADE_PROPERTY.with(|x| f(x));
} }
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
#[inline] #[inline]
fn clone_${style_struct.trait_name_lower}(&self) -> fn clone_${style_struct.trait_name_lower}(&self) ->
Arc<Self::Concrete${style_struct.trait_name}> { Arc<Self::Concrete${style_struct.trait_name}> {
@ -6715,7 +6578,7 @@ impl ServoComputedValues {
pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> { pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> {
match name { match name {
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
"${longhand.name}" => Ok(self.${style_struct.ident}.${longhand.ident}.to_css_string()), "${longhand.name}" => Ok(self.${style_struct.ident}.${longhand.ident}.to_css_string()),
% endfor % endfor
@ -6769,7 +6632,7 @@ pub fn get_writing_mode<S: style_struct_traits::InheritedBox>(inheritedbox_style
/// The initial values for all style structs as defined by the specification. /// The initial values for all style structs as defined by the specification.
lazy_static! { lazy_static! {
pub static ref INITIAL_SERVO_VALUES: ServoComputedValues = ServoComputedValues { pub static ref INITIAL_SERVO_VALUES: ServoComputedValues = ServoComputedValues {
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: Arc::new(style_structs::${style_struct.servo_struct_name} { ${style_struct.ident}: Arc::new(style_structs::${style_struct.servo_struct_name} {
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
@ -6807,7 +6670,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
shareable, shareable,
WritingMode::empty(), WritingMode::empty(),
parent_style.root_font_size(), parent_style.root_font_size(),
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
% if style_struct.inherited: % if style_struct.inherited:
parent_style parent_style
% else: % else:
@ -6824,7 +6687,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
// Declarations are already stored in reverse order. // Declarations are already stored in reverse order.
for declaration in sub_list.declarations.iter() { for declaration in sub_list.declarations.iter() {
match *declaration { match *declaration {
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
% for property in style_struct.longhands: % for property in style_struct.longhands:
% if not property.derived_from: % if not property.derived_from:
PropertyDeclaration::${property.camel_case}(ref PropertyDeclaration::${property.camel_case}(ref
@ -6867,8 +6730,8 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
); );
% endif % endif
% if property.name in DERIVED_LONGHANDS: % if property.name in data.derived_longhands:
% for derived in DERIVED_LONGHANDS[property.name]: % for derived in data.derived_longhands[property.name]:
longhands::${derived.ident} longhands::${derived.ident}
::derive_from_${property.ident}(&mut context); ::derive_from_${property.ident}(&mut context);
% endfor % endfor
@ -6905,7 +6768,7 @@ pub type CascadePropertyFn<C /*: ComputedValues */> =
pub fn make_cascade_vec<C: ComputedValues>() -> Vec<Option<CascadePropertyFn<C>>> { pub fn make_cascade_vec<C: ComputedValues>() -> Vec<Option<CascadePropertyFn<C>>> {
let mut result: Vec<Option<CascadePropertyFn<C>>> = Vec::new(); let mut result: Vec<Option<CascadePropertyFn<C>>> = Vec::new();
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
% for property in style_struct.longhands: % for property in style_struct.longhands:
let discriminant; let discriminant;
unsafe { unsafe {
@ -7000,7 +6863,7 @@ pub fn cascade<C: ComputedValues>(
shareable, shareable,
WritingMode::empty(), WritingMode::empty(),
inherited_style.root_font_size(), inherited_style.root_font_size(),
% for style_struct in active_style_structs(): % for style_struct in data.active_style_structs():
% if style_struct.inherited: % if style_struct.inherited:
inherited_style inherited_style
% else: % else:
@ -7090,7 +6953,7 @@ pub fn cascade<C: ComputedValues>(
if let Some(computed_display) = computed_display { if let Some(computed_display) = computed_display {
let box_ = style.mutate_box(); let box_ = style.mutate_box();
box_.set_display(computed_display); box_.set_display(computed_display);
% if CONFIG["product"] == "servo": % if product == "servo":
box_.set__servo_display_for_hypothetical_box(if is_root_element { box_.set__servo_display_for_hypothetical_box(if is_root_element {
computed_display computed_display
} else { } else {
@ -7320,7 +7183,7 @@ pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<Se
pub fn is_supported_property(property: &str) -> bool { pub fn is_supported_property(property: &str) -> bool {
match_ignore_ascii_case! { property, match_ignore_ascii_case! { property,
% for property in SHORTHANDS + LONGHANDS: % for property in data.shorthands + data.longhands:
"${property.name}" => true, "${property.name}" => true,
% endfor % endfor
_ => property.starts_with("--") _ => property.starts_with("--")
@ -7331,12 +7194,12 @@ pub fn is_supported_property(property: &str) -> bool {
macro_rules! css_properties_accessors { macro_rules! css_properties_accessors {
($macro_name: ident) => { ($macro_name: ident) => {
$macro_name! { $macro_name! {
% for property in SHORTHANDS + LONGHANDS: % for property in data.shorthands + data.longhands:
% if not property.derived_from and not property.internal: % if not property.derived_from and not property.internal:
% if '-' in property.name: % if '-' in property.name:
[${property.ident.capitalize()}, Set${property.ident.capitalize()}, "${property.name}"], [${property.ident.capitalize()}, Set${property.ident.capitalize()}, "${property.name}"],
% endif % endif
% if property != LONGHANDS[-1]: % if property != data.longhands[-1]:
[${property.camel_case}, Set${property.camel_case}, "${property.name}"], [${property.camel_case}, Set${property.camel_case}, "${property.name}"],
% else: % else:
[${property.camel_case}, Set${property.camel_case}, "${property.name}"] [${property.camel_case}, Set${property.camel_case}, "${property.name}"]
@ -7351,7 +7214,7 @@ macro_rules! css_properties_accessors {
macro_rules! longhand_properties_idents { macro_rules! longhand_properties_idents {
($macro_name: ident) => { ($macro_name: ident) => {
$macro_name! { $macro_name! {
% for property in LONGHANDS: % for property in data.longhands:
${property.ident} ${property.ident}
% endfor % endfor
} }

View file

@ -3,10 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::env; use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path; use std::path::Path;
use std::process::{Command, Stdio, exit}; use std::process::{Command, exit};
#[cfg(windows)] #[cfg(windows)]
fn find_python() -> String { fn find_python() -> String {
@ -31,36 +29,25 @@ fn find_python() -> String {
} }
fn main() { fn main() {
let python = match env::var("PYTHON") { let python = env::var("PYTHON").ok().unwrap_or_else(find_python);
Ok(python_path) => python_path,
Err(_) => find_python(),
};
// Mako refuses to load templates outside the scope of the current working directory, // Mako refuses to load templates outside the scope of the current working directory,
// so we need to run it from the top source directory. // so we need to run it from the top source directory.
let geckolib_dir = Path::new(file!()).parent().unwrap(); let geckolib_dir = Path::new(file!()).parent().unwrap();
let top_dir = geckolib_dir.join("..").join(".."); let top_dir = geckolib_dir.join("..").join("..");
let properties_dir = top_dir.join("components").join("style").join("properties"); let properties_dir = Path::new("components").join("style").join("properties");
println!("cargo:rerun-if-changed={}", properties_dir.to_str().unwrap()); println!("cargo:rerun-if-changed={}", top_dir.join(&properties_dir).to_str().unwrap());
println!("cargo:rerun-if-changed={}", geckolib_dir.join("properties.mako.rs").to_str().unwrap()); println!("cargo:rerun-if-changed={}", geckolib_dir.join("properties.mako.rs").to_str().unwrap());
let style_template = Path::new("components/style/properties/properties.mako.rs"); let status = Command::new(python)
let geckolib_template = Path::new("ports/geckolib/properties.mako.rs"); .current_dir(&top_dir)
let mako = Path::new("components/style/properties/Mako-0.9.1.zip"); .arg(&properties_dir.join("build.py"))
.arg("gecko")
let result = Command::new(python) .arg("geckolib")
.current_dir(top_dir) .status()
.env("PYTHONPATH", &mako)
.env("STYLE_TEMPLATE", &style_template)
.env("GECKOLIB_TEMPLATE", &geckolib_template)
.arg("ports/geckolib/generate_properties_rs.py")
.stderr(Stdio::inherit())
.output()
.unwrap(); .unwrap();
if !result.status.success() { if !status.success() {
exit(1) exit(1)
} }
let out = env::var("OUT_DIR").unwrap();
File::create(&Path::new(&out).join("properties.rs")).unwrap().write_all(&result.stdout).unwrap();
} }

View file

@ -2,10 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// STYLE_STRUCTS comes from components/style/properties.mako.rs; see build.rs for more details. // `data` comes from components/style/properties.mako.rs; see build.rs for more details.
<%!
from data import to_rust_ident
%>
use app_units::Au; use app_units::Au;
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
%if style_struct.gecko_ffi_name: %if style_struct.gecko_ffi_name:
use gecko_style_structs::${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_Construct_${style_struct.gecko_ffi_name};
@ -27,7 +31,7 @@ use style::properties::style_struct_traits::*;
#[derive(Clone)] #[derive(Clone)]
pub struct GeckoComputedValues { pub struct GeckoComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
${style_struct.ident}: Arc<${style_struct.gecko_struct_name}>, ${style_struct.ident}: Arc<${style_struct.gecko_struct_name}>,
% endfor % endfor
@ -38,7 +42,7 @@ pub struct GeckoComputedValues {
} }
impl ComputedValues for GeckoComputedValues { impl ComputedValues for GeckoComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
type Concrete${style_struct.trait_name} = ${style_struct.gecko_struct_name}; type Concrete${style_struct.trait_name} = ${style_struct.gecko_struct_name};
% endfor % endfor
@ -50,7 +54,7 @@ impl ComputedValues for GeckoComputedValues {
shareable: bool, shareable: bool,
writing_mode: WritingMode, writing_mode: WritingMode,
root_font_size: Au, root_font_size: Au,
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
${style_struct.ident}: Arc<${style_struct.gecko_struct_name}>, ${style_struct.ident}: Arc<${style_struct.gecko_struct_name}>,
% endfor % endfor
) -> Self { ) -> Self {
@ -59,7 +63,7 @@ impl ComputedValues for GeckoComputedValues {
shareable: shareable, shareable: shareable,
writing_mode: writing_mode, writing_mode: writing_mode,
root_font_size: root_font_size, root_font_size: root_font_size,
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
${style_struct.ident}: ${style_struct.ident}, ${style_struct.ident}: ${style_struct.ident},
% endfor % endfor
} }
@ -71,7 +75,7 @@ impl ComputedValues for GeckoComputedValues {
CASCADE_PROPERTY.with(|x| f(x)); CASCADE_PROPERTY.with(|x| f(x));
} }
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
#[inline] #[inline]
fn clone_${style_struct.trait_name_lower}(&self) -> Arc<Self::Concrete${style_struct.trait_name}> { fn clone_${style_struct.trait_name_lower}(&self) -> Arc<Self::Concrete${style_struct.trait_name}> {
self.${style_struct.ident}.clone() self.${style_struct.ident}.clone()
@ -237,13 +241,13 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
} }
</%def> </%def>
<%! MANUAL_STYLE_STRUCTS = [] %> <% data.manual_style_structs = [] %>
<%def name="impl_trait(style_struct_name, skip_longhands=None, skip_additionals=None)"> <%def name="impl_trait(style_struct_name, skip_longhands=None, skip_additionals=None)">
<%self:raw_impl_trait style_struct="${next(x for x in STYLE_STRUCTS if x.trait_name == style_struct_name)}" <%self:raw_impl_trait style_struct="${next(x for x in data.style_structs if x.trait_name == style_struct_name)}"
skip_longhands="${skip_longhands}" skip_additionals="${skip_additionals}"> skip_longhands="${skip_longhands}" skip_additionals="${skip_additionals}">
${caller.body()} ${caller.body()}
</%self:raw_impl_trait> </%self:raw_impl_trait>
<% MANUAL_STYLE_STRUCTS.append(style_struct_name) %> <% data.manual_style_structs.append(style_struct_name) %>
</%def> </%def>
// Proof-of-concept for a style struct with some manually-implemented methods. We add // Proof-of-concept for a style struct with some manually-implemented methods. We add
@ -270,17 +274,17 @@ ${caller.body()}
} }
</%self:impl_trait> </%self:impl_trait>
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
${declare_style_struct(style_struct)} ${declare_style_struct(style_struct)}
${impl_style_struct(style_struct)} ${impl_style_struct(style_struct)}
% if not style_struct.trait_name in MANUAL_STYLE_STRUCTS: % if not style_struct.trait_name in data.manual_style_structs:
<%self:raw_impl_trait style_struct="${style_struct}"></%self:raw_impl_trait> <%self:raw_impl_trait style_struct="${style_struct}"></%self:raw_impl_trait>
% endif % endif
% endfor % endfor
lazy_static! { lazy_static! {
pub static ref INITIAL_GECKO_VALUES: GeckoComputedValues = GeckoComputedValues { pub static ref INITIAL_GECKO_VALUES: GeckoComputedValues = GeckoComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in data.style_structs:
${style_struct.ident}: ${style_struct.gecko_struct_name}::initial(), ${style_struct.ident}: ${style_struct.gecko_struct_name}::initial(),
% endfor % endfor
custom_properties: None, custom_properties: None,