summaryrefslogtreecommitdiffstats
path: root/servo/components/style/properties/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'servo/components/style/properties/build.py')
-rw-r--r--servo/components/style/properties/build.py176
1 files changed, 176 insertions, 0 deletions
diff --git a/servo/components/style/properties/build.py b/servo/components/style/properties/build.py
new file mode 100644
index 0000000000..6c3ee0cf66
--- /dev/null
+++ b/servo/components/style/properties/build.py
@@ -0,0 +1,176 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import json
+import os.path
+import re
+import sys
+
+BASE = os.path.dirname(__file__.replace("\\", "/"))
+sys.path.insert(0, os.path.join(BASE, "Mako-1.1.2-py2.py3-none-any.whl"))
+sys.path.insert(0, BASE) # For importing `data.py`
+
+from mako import exceptions
+from mako.lookup import TemplateLookup
+from mako.template import Template
+
+import data
+
+RE_PYTHON_ADDR = re.compile(r"<.+? object at 0x[0-9a-fA-F]+>")
+
+OUT_DIR = os.environ.get("OUT_DIR", "")
+
+STYLE_STRUCT_LIST = [
+ "background",
+ "border",
+ "box",
+ "column",
+ "counters",
+ "effects",
+ "font",
+ "inherited_box",
+ "inherited_svg",
+ "inherited_table",
+ "inherited_text",
+ "inherited_ui",
+ "list",
+ "margin",
+ "outline",
+ "page",
+ "padding",
+ "position",
+ "svg",
+ "table",
+ "text",
+ "ui",
+ "xul",
+]
+
+
+def main():
+ usage = (
+ "Usage: %s [ servo-2013 | servo-2020 | gecko ] [ style-crate | geckolib <template> | html ]"
+ % sys.argv[0]
+ )
+ if len(sys.argv) < 3:
+ abort(usage)
+ engine = sys.argv[1]
+ output = sys.argv[2]
+
+ if engine not in ["servo-2013", "servo-2020", "gecko"] or output not in [
+ "style-crate",
+ "geckolib",
+ "html",
+ ]:
+ abort(usage)
+
+ properties = data.PropertiesData(engine=engine)
+ files = {}
+ for kind in ["longhands", "shorthands"]:
+ files[kind] = {}
+ for struct in STYLE_STRUCT_LIST:
+ file_name = os.path.join(BASE, kind, "{}.mako.rs".format(struct))
+ if kind == "shorthands" and not os.path.exists(file_name):
+ files[kind][struct] = ""
+ continue
+ files[kind][struct] = render(
+ file_name,
+ engine=engine,
+ data=properties,
+ )
+ properties_template = os.path.join(BASE, "properties.mako.rs")
+ files["properties"] = render(
+ properties_template,
+ engine=engine,
+ data=properties,
+ __file__=properties_template,
+ OUT_DIR=OUT_DIR,
+ )
+ if output == "style-crate":
+ write(OUT_DIR, "properties.rs", files["properties"])
+ for kind in ["longhands", "shorthands"]:
+ for struct in files[kind]:
+ write(
+ os.path.join(OUT_DIR, kind),
+ "{}.rs".format(struct),
+ files[kind][struct],
+ )
+
+ if engine == "gecko":
+ template = os.path.join(BASE, "gecko.mako.rs")
+ rust = render(template, data=properties)
+ write(OUT_DIR, "gecko_properties.rs", rust)
+
+ if engine in ["servo-2013", "servo-2020"]:
+ if engine == "servo-2013":
+ pref_attr = "servo_2013_pref"
+ if engine == "servo-2020":
+ pref_attr = "servo_2020_pref"
+ properties_dict = {
+ kind: {
+ p.name: {"pref": getattr(p, pref_attr)}
+ for prop in properties_list
+ if prop.enabled_in_content()
+ for p in [prop] + prop.alias
+ }
+ for kind, properties_list in [
+ ("longhands", properties.longhands),
+ ("shorthands", properties.shorthands),
+ ]
+ }
+ as_html = render(
+ os.path.join(BASE, "properties.html.mako"), properties=properties_dict
+ )
+ as_json = json.dumps(properties_dict, indent=4, sort_keys=True)
+ doc_servo = os.path.join(BASE, "..", "..", "..", "target", "doc", "servo")
+ write(doc_servo, "css-properties.html", as_html)
+ write(doc_servo, "css-properties.json", as_json)
+ write(OUT_DIR, "css-properties.json", as_json)
+ elif output == "geckolib":
+ if len(sys.argv) < 4:
+ abort(usage)
+ template = sys.argv[3]
+ header = render(template, data=properties)
+ sys.stdout.write(header)
+
+
+def abort(message):
+ print(message, file=sys.stderr)
+ sys.exit(1)
+
+
+def render(filename, **context):
+ try:
+ lookup = TemplateLookup(
+ directories=[BASE], input_encoding="utf8", strict_undefined=True
+ )
+ template = Template(
+ open(filename, "rb").read(),
+ filename=filename,
+ input_encoding="utf8",
+ lookup=lookup,
+ strict_undefined=True,
+ )
+ # Uncomment to debug generated Python code:
+ # write("/tmp", "mako_%s.py" % os.path.basename(filename), template.code)
+ return template.render(**context)
+ except Exception:
+ # Uncomment to see a traceback in generated Python code:
+ # raise
+ abort(exceptions.text_error_template().render())
+
+
+def write(directory, filename, content):
+ if not os.path.exists(directory):
+ os.makedirs(directory)
+ full_path = os.path.join(directory, filename)
+ open(full_path, "w", encoding="utf-8").write(content)
+
+ python_addr = RE_PYTHON_ADDR.search(content)
+ if python_addr:
+ abort('Found "{}" in {} ({})'.format(python_addr.group(0), filename, full_path))
+
+
+if __name__ == "__main__":
+ main()