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)
.arg(&script)
.arg(product)
.arg("rust")
.arg("style-crate")
.status()
.unwrap();
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.template import Template
import data
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:
abort(usage)
product = sys.argv[1]
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)
template, rust = render("properties.mako.rs", PRODUCT=product)
if output == "rust":
properties = data.PropertiesData(product=product)
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)
elif output == "html":
write_html(template)
write_html(properties)
def abort(message):
@ -35,11 +42,18 @@ def abort(message):
sys.exit(1)
def render(name, **context):
def render(filename, **context):
try:
template = Template(open(os.path.join(BASE, name), "rb").read(), input_encoding="utf8")
return template, template.render(**context).encode("utf8")
template = Template(open(filename, "rb").read(),
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:
# Uncomment to see a traceback in generated Python code:
#raise
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)
def write_html(template):
def write_html(properties):
properties = dict(
(p.name, {
"flag": p.experimental,
"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")
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.json", json.dumps(properties, indent=4))
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,161 +37,20 @@ use values::specified::BorderStyle;
use self::property_bit_field::PropertyBitField;
<%!
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)
from data import Method, Keyword, to_rust_ident
%>
// 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 {
use cssparser::Parser;
use parser::ParserContext;
use values::specified;
<%def name="raw_longhand(name, **kwargs)">
<%
products = kwargs.pop("products", "gecko servo").split()
if not CONFIG["product"] in products:
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)
%>
<%def name="raw_longhand(*args, **kwargs)">
<%
property = data.declare_longhand(*args, **kwargs)
if property is None:
return ""
%>
pub mod ${property.ident} {
#![allow(unused_imports)]
% if not property.derived_from:
@ -203,7 +62,7 @@ pub mod longhands {
use properties::longhands;
use properties::property_bit_field::PropertyBitField;
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 std::boxed::Box as StdBox;
use std::collections::HashMap;
@ -237,7 +96,7 @@ pub mod longhands {
declared_value, &custom_props, |value| match *value {
DeclaredValue::Value(ref specified_value) => {
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);
}
DeclaredValue::WithVariables { .. } => unreachable!(),
@ -245,8 +104,8 @@ pub mod longhands {
// We assume that it's faster to use copy_*_from rather than
// set_*(get_initial_value());
let initial_struct = C::initial_values()
.get_${THIS_STYLE_STRUCT.trait_name_lower}();
context.mutate_style().mutate_${THIS_STYLE_STRUCT.trait_name_lower}()
.get_${data.current_style_struct.trait_name_lower}();
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
.copy_${property.ident}_from(initial_struct);
},
DeclaredValue::Inherit => {
@ -255,8 +114,8 @@ pub mod longhands {
//
// FIXME: is it still?
*cacheable = false;
let inherited_struct = inherited_style.get_${THIS_STYLE_STRUCT.trait_name_lower}();
context.mutate_style().mutate_${THIS_STYLE_STRUCT.trait_name_lower}()
let inherited_struct = inherited_style.get_${data.current_style_struct.trait_name_lower}();
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
.copy_${property.ident}_from(inherited_struct);
}
}, error_reporter
@ -282,7 +141,7 @@ pub mod longhands {
Ok(CSSWideKeyword::InheritKeyword) => Ok(DeclaredValue::Inherit),
Ok(CSSWideKeyword::InitialKeyword) => Ok(DeclaredValue::Initial),
Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::${
"Inherit" if THIS_STYLE_STRUCT.inherited else "Initial"}),
"Inherit" if data.current_style_struct.inherited else "Initial"}),
Err(()) => {
input.look_for_var_functions();
let start = input.position();
@ -313,7 +172,7 @@ pub mod longhands {
<%def name="longhand(name, **kwargs)">
<%call expr="raw_longhand(name, **kwargs)">
${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)
-> Result<DeclaredValue<SpecifiedValue>, ()> {
parse(context, input).map(DeclaredValue::Value)
@ -323,12 +182,17 @@ pub mod longhands {
</%def>
<%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;
${caller.body()}
pub mod computed_value {
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)},
% endfor
}
@ -369,14 +233,14 @@ pub mod longhands {
// 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"]:
${predefined_type("margin-" + side, "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Length(Au(0))")}
% 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"]:
${predefined_type("padding-" + side, "LengthOrPercentage",
@ -384,9 +248,9 @@ pub mod longhands {
"parse_non_negative")}
% 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",
"bool") for side in ["top", "right", "bottom", "left"]])}
"bool") for side in ["top", "right", "bottom", "left"]]) %>
% for side in ["top", "right", "bottom", "left"]:
${predefined_type("border-%s-color" % side, "CSSColor", "::cssparser::Color::CurrentColor")}
@ -441,8 +305,8 @@ pub mod longhands {
"parse")}
% endfor
${new_style_struct("Outline", is_inherited=False, gecko_name="nsStyleOutline",
additional_methods=[Method("outline_is_none_or_hidden_and_has_nonzero_width", "bool")])}
<% data.new_style_struct("Outline", inherited=False, gecko_ffi_name="nsStyleOutline",
additional_methods=[Method("outline_is_none_or_hidden_and_has_nonzero_width", "bool")]) %>
// TODO(pcwalton): `invert`
${predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor")}
@ -495,7 +359,7 @@ pub mod longhands {
${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"]:
${predefined_type(side, "LengthOrPercentageOrAuto",
@ -504,7 +368,7 @@ pub mod longhands {
// 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",
"longhands::display::computed_value::T"),
Method("clone_position",
@ -512,10 +376,10 @@ pub mod longhands {
Method("is_floated", "bool"),
Method("overflow_x_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
<%self:longhand name="display" custom_cascade="${CONFIG['product'] == 'servo'}">
<%self:longhand name="display" custom_cascade="${product == 'servo'}">
<%
values = """inline block inline-block
table inline-table table-row-group table-header-group table-footer-group
@ -572,7 +436,7 @@ pub mod longhands {
impl ComputedValueAsSpecified for SpecifiedValue {}
% if CONFIG["product"] == "servo":
% if product == "servo":
fn cascade_property_custom<C: ComputedValues>(
_declaration: &PropertyDeclaration,
_inherited_style: &C,
@ -626,7 +490,7 @@ pub mod longhands {
</%self:longhand>
${switch_to_style_struct("Position")}
<% data.switch_to_style_struct("Position") %>
<%self:longhand name="z-index">
use values::computed::ComputedValueAsSpecified;
@ -674,19 +538,19 @@ pub mod longhands {
}
</%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",
"longhands::direction::computed_value::T"),
Method("clone_writing_mode",
"longhands::writing_mode::computed_value::T"),
Method("clone_text_orientation",
"longhands::text_orientation::computed_value::T")])}
"longhands::text_orientation::computed_value::T")]) %>
${single_keyword("direction", "ltr rtl")}
// CSS 2.1, Section 10 - Visual formatting model details
${switch_to_style_struct("Box")}
<% data.switch_to_style_struct("Box") %>
${predefined_type("width", "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Auto",
@ -696,7 +560,7 @@ pub mod longhands {
"computed::LengthOrPercentageOrAuto::Auto",
"parse_non_negative")}
${switch_to_style_struct("Position")}
<% data.switch_to_style_struct("Position") %>
${predefined_type("min-width", "LengthOrPercentage",
"computed::LengthOrPercentage::Length(Au(0))",
@ -712,10 +576,10 @@ pub mod longhands {
"computed::LengthOrPercentageOrNone::None",
"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",
"longhands::_servo_text_decorations_in_effect::computed_value::T")]
if CONFIG["product"] == "servo" else []))}
if product == "servo" else [])) %>
<%self:longhand name="line-height">
use cssparser::ToCss;
@ -809,7 +673,7 @@ pub mod longhands {
}
</%self:longhand>
${switch_to_style_struct("Box")}
<% data.switch_to_style_struct("Box") %>
<%self:longhand name="vertical-align">
use cssparser::ToCss;
@ -962,7 +826,7 @@ pub mod longhands {
// http://www.w3.org/TR/compositing-1/
${single_keyword("isolation", "auto isolate", products="gecko")}
${switch_to_style_struct("InheritedBox")}
<% data.switch_to_style_struct("InheritedBox") %>
// TODO: collapse. Well, do tables first.
${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
${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">
use cssparser::Token;
@ -1135,7 +999,7 @@ pub mod longhands {
}
</%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")}
@ -1283,7 +1147,7 @@ pub mod longhands {
}
</%self:longhand>
${switch_to_style_struct("Counters")}
<% data.switch_to_style_struct("Counters") %>
<%self:longhand name="counter-increment">
use std::fmt;
@ -1365,7 +1229,7 @@ pub mod longhands {
// 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-before", "auto always avoid left right", products="gecko")}
@ -1374,7 +1238,7 @@ pub mod longhands {
// 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(
"background-color", "CSSColor",
"::cssparser::Color::RGBA(::cssparser::RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")}
@ -1696,9 +1560,9 @@ pub mod longhands {
}
</%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",
"longhands::color::computed_value::T")])}
"longhands::color::computed_value::T")]) %>
<%self:raw_longhand name="color">
use cssparser::Color as CSSParserColor;
@ -1738,12 +1602,12 @@ pub mod longhands {
// 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",
"longhands::font_size::computed_value::T"),
Method("clone_font_weight",
"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">
use self::computed_value::FontFamily;
@ -2049,7 +1913,7 @@ pub mod longhands {
// CSS 2.1, Section 16 - Text
${switch_to_style_struct("InheritedText")}
<% data.switch_to_style_struct("InheritedText") %>
<%self:longhand name="text-align">
pub use self::computed_value::T as SpecifiedValue;
@ -2241,16 +2105,16 @@ pub mod longhands {
// TODO(pcwalton): Support `text-justify: distribute`.
${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"),
Method("has_overline", "bool"),
Method("has_line_through", "bool")])}
Method("has_line_through", "bool")]) %>
${single_keyword("text-overflow", "clip ellipsis")}
${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 std::fmt;
use values::computed::ComputedValueAsSpecified;
@ -2325,7 +2189,7 @@ pub mod longhands {
if !empty { Ok(result) } else { Err(()) }
}
% if CONFIG["product"] == "servo":
% if product == "servo":
fn cascade_property_custom<C: ComputedValues>(
_declaration: &PropertyDeclaration,
_inherited_style: &C,
@ -2341,7 +2205,7 @@ pub mod longhands {
${single_keyword("text-decoration-style", "-moz-none solid double dotted dashed wavy",
products="gecko")}
${switch_to_style_struct("InheritedText")}
<% data.switch_to_style_struct("InheritedText") %>
<%self:longhand name="-servo-text-decorations-in-effect"
derived_from="display text-decoration" products="servo">
@ -2479,11 +2343,11 @@ pub mod longhands {
${single_keyword("ruby-position", "over under", products="gecko")}
// 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")}
${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")}
@ -2582,13 +2446,13 @@ pub mod longhands {
// CSS Fragmentation Module Level 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")}
// CSS Writing Modes Level 3
// 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)}
@ -2602,15 +2466,15 @@ pub mod longhands {
// CSS Basic User Interface Module Level 3
// 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")}
${switch_to_style_struct("Position")}
<% data.switch_to_style_struct("Position") %>
${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">
pub use self::computed_value::T as SpecifiedValue;
@ -2662,7 +2526,7 @@ pub mod longhands {
${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">
use cssparser::ToCss;
@ -2854,7 +2718,7 @@ pub mod longhands {
</%self:longhand>
// 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">
use cssparser::ToCss;
@ -3258,7 +3122,7 @@ pub mod longhands {
}
</%self:longhand>
${switch_to_style_struct("InheritedText")}
<% data.switch_to_style_struct("InheritedText") %>
<%self:longhand name="text-shadow">
use cssparser::{self, ToCss};
@ -3438,7 +3302,7 @@ pub mod longhands {
}
</%self:longhand>
${switch_to_style_struct("Effects")}
<% data.switch_to_style_struct("Effects") %>
<%self:longhand name="filter">
//pub use self::computed_value::T as SpecifiedValue;
@ -4376,11 +4240,11 @@ pub mod longhands {
// CSS Image Values and Replaced Content Module Level 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")}
${switch_to_style_struct("InheritedBox")}
<% data.switch_to_style_struct("InheritedBox") %>
<%self:longhand name="image-rendering">
@ -4437,7 +4301,7 @@ pub mod longhands {
}
</%self:longhand>
${switch_to_style_struct("Box")}
<% data.switch_to_style_struct("Box") %>
// TODO(pcwalton): Multiple transitions.
<%self:longhand name="transition-duration">
@ -4963,7 +4827,7 @@ pub mod longhands {
// CSS Flexible Box Layout Module Level 1
// http://www.w3.org/TR/css3-flexbox/
${switch_to_style_struct("Position")}
<% data.switch_to_style_struct("Position") %>
// Flex container properties
${single_keyword("flex-direction", "row row-reverse column column-reverse", experimental=True)}
@ -4994,7 +4858,7 @@ pub mod longhands {
// SVG 1.1 (Second Edition)
// 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
@ -5019,7 +4883,7 @@ pub mod longhands {
${single_keyword("clip-rule", "nonzero evenodd",
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",
"""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)">
<%
shorthand = Shorthand(name, sub_properties.split(), experimental=experimental)
SHORTHANDS.append(shorthand)
shorthand = data.declare_shorthand(name, sub_properties.split(), experimental=experimental)
%>
pub mod ${shorthand.ident} {
use cssparser::Parser;
@ -5754,13 +5617,13 @@ pub mod shorthands {
mod property_bit_field {
pub struct PropertyBitField {
storage: [u32; (${len(LONGHANDS)} - 1 + 32) / 32]
storage: [u32; (${len(data.longhands)} - 1 + 32) / 32]
}
impl PropertyBitField {
#[inline]
pub fn new() -> PropertyBitField {
PropertyBitField { storage: [0; (${len(LONGHANDS)} - 1 + 32) / 32] }
PropertyBitField { storage: [0; (${len(data.longhands)} - 1 + 32) / 32] }
}
#[inline]
@ -5771,7 +5634,7 @@ mod property_bit_field {
fn set(&mut self, bit: usize) {
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:
#[allow(non_snake_case)]
#[inline]
@ -5788,7 +5651,7 @@ mod property_bit_field {
}
}
% for property in LONGHANDS:
% for property in data.longhands:
% if not property.derived_from:
#[allow(non_snake_case)]
fn substitute_variables_${property.ident}<F>(
@ -5838,7 +5701,7 @@ mod property_bit_field {
None => {
longhands::${property.ident}::parse_specified(&context, input)
}
% for shorthand in SHORTHANDS:
% for shorthand in data.shorthands:
% if property in shorthand.sub_properties:
Some(Shorthand::${shorthand.camel_case}) => {
shorthands::${shorthand.ident}::parse_value(&context, input)
@ -5958,7 +5821,7 @@ fn deduplicate_property_declarations(declarations: Vec<PropertyDeclaration>)
let mut seen_custom = Vec::new();
for declaration in declarations.into_iter().rev() {
match declaration {
% for property in LONGHANDS:
% for property in data.longhands:
PropertyDeclaration::${property.camel_case}(..) => {
% if not property.derived_from:
if seen.get_${property.ident}() {
@ -6003,7 +5866,7 @@ impl CSSWideKeyword {
#[derive(Clone, Copy, Eq, PartialEq, Debug, HeapSizeOf)]
pub enum Shorthand {
% for property in SHORTHANDS:
% for property in data.shorthands:
${property.camel_case},
% endfor
}
@ -6011,7 +5874,7 @@ pub enum Shorthand {
impl Shorthand {
pub fn from_name(name: &str) -> Option<Shorthand> {
match_ignore_ascii_case! { name,
% for property in SHORTHANDS:
% for property in data.shorthands:
"${property.name}" => Some(Shorthand::${property.camel_case}),
% endfor
_ => None
@ -6019,7 +5882,7 @@ impl Shorthand {
}
pub fn longhands(&self) -> &'static [&'static str] {
% for property in SHORTHANDS:
% for property in data.shorthands:
static ${property.ident.upper()}: &'static [&'static str] = &[
% for sub in property.sub_properties:
"${sub.name}",
@ -6027,7 +5890,7 @@ impl Shorthand {
];
% endfor
match *self {
% for property in SHORTHANDS:
% for property in data.shorthands:
Shorthand::${property.camel_case} => ${property.ident.upper()},
% endfor
}
@ -6067,7 +5930,7 @@ impl<T: ToCss> ToCss for DeclaredValue<T> {
#[derive(PartialEq, Clone, Debug, HeapSizeOf)]
pub enum PropertyDeclaration {
% for property in LONGHANDS:
% for property in data.longhands:
${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
% endfor
Custom(::custom_properties::Name, DeclaredValue<::custom_properties::SpecifiedValue>),
@ -6117,7 +5980,7 @@ impl fmt::Display for PropertyDeclarationName {
impl PropertyDeclaration {
pub fn name(&self) -> PropertyDeclarationName {
match *self {
% for property in LONGHANDS:
% for property in data.longhands:
PropertyDeclaration::${property.camel_case}(..) =>
% if not property.derived_from:
PropertyDeclarationName::Longhand("${property.name}"),
@ -6133,7 +5996,7 @@ impl PropertyDeclaration {
pub fn value(&self) -> String {
match *self {
% for property in LONGHANDS:
% for property in data.longhands:
PropertyDeclaration::${property.camel_case}
% if not property.derived_from:
(ref value) => value.to_css_string(),
@ -6150,7 +6013,7 @@ impl PropertyDeclaration {
// ↓
pub fn with_variables_from_shorthand(&self, shorthand: Shorthand) -> Option< &str> {
match *self {
% for property in LONGHANDS:
% for property in data.longhands:
PropertyDeclaration::${property.camel_case}(ref value) => match *value {
DeclaredValue::WithVariables { ref css, from_shorthand: Some(s), .. }
if s == shorthand => {
@ -6167,7 +6030,7 @@ impl PropertyDeclaration {
/// https://drafts.csswg.org/css-variables/#variables-in-shorthands
pub fn with_variables(&self) -> bool {
match *self {
% for property in LONGHANDS:
% for property in data.longhands:
PropertyDeclaration::${property.camel_case}(ref value) => match *value {
DeclaredValue::WithVariables { .. } => true,
_ => false,
@ -6182,7 +6045,7 @@ impl PropertyDeclaration {
pub fn matches(&self, name: &str) -> bool {
match *self {
% for property in LONGHANDS:
% for property in data.longhands:
PropertyDeclaration::${property.camel_case}(..) =>
% if not property.derived_from:
name.eq_ignore_ascii_case("${property.name}"),
@ -6212,7 +6075,7 @@ impl PropertyDeclaration {
return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration;
}
match_ignore_ascii_case! { name,
% for property in LONGHANDS:
% for property in data.longhands:
% if not property.derived_from:
"${property.name}" => {
% if property.internal:
@ -6238,7 +6101,7 @@ impl PropertyDeclaration {
"${property.name}" => PropertyDeclarationParseResult::UnknownProperty,
% endif
% endfor
% for shorthand in SHORTHANDS:
% for shorthand in data.shorthands:
"${shorthand.name}" => {
% if shorthand.internal:
if context.stylesheet_origin != Origin::UserAgent {
@ -6292,7 +6155,7 @@ impl PropertyDeclaration {
pub mod style_struct_traits {
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 {
% for longhand in style_struct.longhands:
#[allow(non_snake_case)]
@ -6313,7 +6176,7 @@ pub mod style_structs {
use super::longhands;
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":
#[derive(Clone, HeapSizeOf, Debug)]
% else:
@ -6403,7 +6266,7 @@ pub mod style_structs {
fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T {
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) ->
longhands::_servo_text_decorations_in_effect::computed_value::T {
self._servo_text_decorations_in_effect.clone()
@ -6429,7 +6292,7 @@ pub mod style_structs {
}
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};
% endfor
@ -6444,7 +6307,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
shareable: bool,
writing_mode: WritingMode,
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}>,
% endfor
) -> Self;
@ -6453,7 +6316,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
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) ->
Arc<Self::Concrete${style_struct.trait_name}>;
fn get_${style_struct.trait_name_lower}<'a>(&'a self) ->
@ -6471,7 +6334,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
#[derive(Clone, HeapSizeOf)]
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}>,
% endfor
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
@ -6481,7 +6344,7 @@ pub struct 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};
% endfor
@ -6492,7 +6355,7 @@ impl ComputedValues for ServoComputedValues {
shareable: bool,
writing_mode: WritingMode,
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}>,
% endfor
) -> Self {
@ -6501,7 +6364,7 @@ impl ComputedValues for ServoComputedValues {
shareable: shareable,
writing_mode: writing_mode,
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},
% endfor
}
@ -6513,7 +6376,7 @@ impl ComputedValues for ServoComputedValues {
CASCADE_PROPERTY.with(|x| f(x));
}
% for style_struct in active_style_structs():
% for style_struct in data.active_style_structs():
#[inline]
fn clone_${style_struct.trait_name_lower}(&self) ->
Arc<Self::Concrete${style_struct.trait_name}> {
@ -6715,7 +6578,7 @@ impl ServoComputedValues {
pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> {
match name {
% for style_struct in active_style_structs():
% for style_struct in data.active_style_structs():
% for longhand in style_struct.longhands:
"${longhand.name}" => Ok(self.${style_struct.ident}.${longhand.ident}.to_css_string()),
% 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.
lazy_static! {
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} {
% for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
@ -6807,7 +6670,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
shareable,
WritingMode::empty(),
parent_style.root_font_size(),
% for style_struct in active_style_structs():
% for style_struct in data.active_style_structs():
% if style_struct.inherited:
parent_style
% else:
@ -6824,7 +6687,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
// Declarations are already stored in reverse order.
for declaration in sub_list.declarations.iter() {
match *declaration {
% for style_struct in active_style_structs():
% for style_struct in data.active_style_structs():
% for property in style_struct.longhands:
% if not property.derived_from:
PropertyDeclaration::${property.camel_case}(ref
@ -6867,8 +6730,8 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
);
% endif
% if property.name in DERIVED_LONGHANDS:
% for derived in DERIVED_LONGHANDS[property.name]:
% if property.name in data.derived_longhands:
% for derived in data.derived_longhands[property.name]:
longhands::${derived.ident}
::derive_from_${property.ident}(&mut context);
% endfor
@ -6905,7 +6768,7 @@ pub type CascadePropertyFn<C /*: ComputedValues */> =
pub fn make_cascade_vec<C: ComputedValues>() -> Vec<Option<CascadePropertyFn<C>>> {
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:
let discriminant;
unsafe {
@ -7000,7 +6863,7 @@ pub fn cascade<C: ComputedValues>(
shareable,
WritingMode::empty(),
inherited_style.root_font_size(),
% for style_struct in active_style_structs():
% for style_struct in data.active_style_structs():
% if style_struct.inherited:
inherited_style
% else:
@ -7090,7 +6953,7 @@ pub fn cascade<C: ComputedValues>(
if let Some(computed_display) = computed_display {
let box_ = style.mutate_box();
box_.set_display(computed_display);
% if CONFIG["product"] == "servo":
% if product == "servo":
box_.set__servo_display_for_hypothetical_box(if is_root_element {
computed_display
} 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 {
match_ignore_ascii_case! { property,
% for property in SHORTHANDS + LONGHANDS:
% for property in data.shorthands + data.longhands:
"${property.name}" => true,
% endfor
_ => property.starts_with("--")
@ -7331,12 +7194,12 @@ pub fn is_supported_property(property: &str) -> bool {
macro_rules! css_properties_accessors {
($macro_name: ident) => {
$macro_name! {
% for property in SHORTHANDS + LONGHANDS:
% for property in data.shorthands + data.longhands:
% if not property.derived_from and not property.internal:
% if '-' in property.name:
[${property.ident.capitalize()}, Set${property.ident.capitalize()}, "${property.name}"],
% endif
% if property != LONGHANDS[-1]:
% if property != data.longhands[-1]:
[${property.camel_case}, Set${property.camel_case}, "${property.name}"],
% else:
[${property.camel_case}, Set${property.camel_case}, "${property.name}"]
@ -7351,7 +7214,7 @@ macro_rules! css_properties_accessors {
macro_rules! longhand_properties_idents {
($macro_name: ident) => {
$macro_name! {
% for property in LONGHANDS:
% for property in data.longhands:
${property.ident}
% endfor
}

View file

@ -3,10 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::process::{Command, Stdio, exit};
use std::process::{Command, exit};
#[cfg(windows)]
fn find_python() -> String {
@ -31,36 +29,25 @@ fn find_python() -> String {
}
fn main() {
let python = match env::var("PYTHON") {
Ok(python_path) => python_path,
Err(_) => find_python(),
};
let python = env::var("PYTHON").ok().unwrap_or_else(find_python);
// Mako refuses to load templates outside the scope of the current working directory,
// so we need to run it from the top source directory.
let geckolib_dir = Path::new(file!()).parent().unwrap();
let top_dir = geckolib_dir.join("..").join("..");
let properties_dir = top_dir.join("components").join("style").join("properties");
println!("cargo:rerun-if-changed={}", properties_dir.to_str().unwrap());
let properties_dir = Path::new("components").join("style").join("properties");
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());
let style_template = Path::new("components/style/properties/properties.mako.rs");
let geckolib_template = Path::new("ports/geckolib/properties.mako.rs");
let mako = Path::new("components/style/properties/Mako-0.9.1.zip");
let result = Command::new(python)
.current_dir(top_dir)
.env("PYTHONPATH", &mako)
.env("STYLE_TEMPLATE", &style_template)
.env("GECKOLIB_TEMPLATE", &geckolib_template)
.arg("ports/geckolib/generate_properties_rs.py")
.stderr(Stdio::inherit())
.output()
let status = Command::new(python)
.current_dir(&top_dir)
.arg(&properties_dir.join("build.py"))
.arg("gecko")
.arg("geckolib")
.status()
.unwrap();
if !result.status.success() {
if !status.success() {
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
* 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;
% for style_struct in STYLE_STRUCTS:
% 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};
@ -27,7 +31,7 @@ use style::properties::style_struct_traits::*;
#[derive(Clone)]
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}>,
% endfor
@ -38,7 +42,7 @@ pub struct 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};
% endfor
@ -50,7 +54,7 @@ impl ComputedValues for GeckoComputedValues {
shareable: bool,
writing_mode: WritingMode,
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}>,
% endfor
) -> Self {
@ -59,7 +63,7 @@ impl ComputedValues for GeckoComputedValues {
shareable: shareable,
writing_mode: writing_mode,
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},
% endfor
}
@ -71,7 +75,7 @@ impl ComputedValues for GeckoComputedValues {
CASCADE_PROPERTY.with(|x| f(x));
}
% for style_struct in STYLE_STRUCTS:
% for style_struct in data.style_structs:
#[inline]
fn clone_${style_struct.trait_name_lower}(&self) -> Arc<Self::Concrete${style_struct.trait_name}> {
self.${style_struct.ident}.clone()
@ -237,13 +241,13 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
}
</%def>
<%! MANUAL_STYLE_STRUCTS = [] %>
<% data.manual_style_structs = [] %>
<%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}">
${caller.body()}
</%self:raw_impl_trait>
<% MANUAL_STYLE_STRUCTS.append(style_struct_name) %>
<% data.manual_style_structs.append(style_struct_name) %>
</%def>
// Proof-of-concept for a style struct with some manually-implemented methods. We add
@ -270,17 +274,17 @@ ${caller.body()}
}
</%self:impl_trait>
% for style_struct in STYLE_STRUCTS:
% for style_struct in data.style_structs:
${declare_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>
% endif
% endfor
lazy_static! {
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(),
% endfor
custom_properties: None,