aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-07-29 18:57:20 +0200
committerSimon Sapin <simon.sapin@exyr.org>2019-07-30 08:37:33 +0200
commit0215d09ccbfed85c91605dedbb175dc9a96ba0ab (patch)
tree748fa7b4806ce88d8d1376b95f386812bede0383
parentddb4e369ddb8d9bb20142d34e320370cd3be196f (diff)
downloadservo-0215d09ccbfed85c91605dedbb175dc9a96ba0ab.tar.gz
servo-0215d09ccbfed85c91605dedbb175dc9a96ba0ab.zip
Generate apis.html and css-properties.json for docs as part of crates’ build scripts
… rather than as an extra step after `cargo doc`. This helps always using the correct set of CSS properties (for layout 2013 v.s. 2020).
-rw-r--r--components/script/CMakeLists.txt23
-rw-r--r--components/script/build.rs6
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py2
-rw-r--r--components/script/dom/bindings/codegen/GlobalGen.py42
-rw-r--r--components/style/properties/build.py43
-rw-r--r--components/style/properties/properties.html.mako43
-rw-r--r--python/servo/post_build_commands.py13
-rw-r--r--tests/unit/style/properties/scaffolding.rs68
8 files changed, 67 insertions, 173 deletions
diff --git a/components/script/CMakeLists.txt b/components/script/CMakeLists.txt
index 3bb3f2d5dbb..4ad45327d29 100644
--- a/components/script/CMakeLists.txt
+++ b/components/script/CMakeLists.txt
@@ -41,7 +41,6 @@ set(globalgen_deps
${bindings_src}/Configuration.py
${bindings_src}/CodegenRust.py
${bindings_src}/parser/WebIDL.py
- ${PROJECT_BINARY_DIR}/css_properties.json
)
set(bindinggen_deps
${globalgen_deps}
@@ -69,28 +68,12 @@ add_custom_command(
${bindings_src}/Bindings.conf
.
${PROJECT_SOURCE_DIR}
- ${PROJECT_BINARY_DIR}/css_properties.json
- DEPENDS Bindings _cache ${globalgen_deps} ${webidls}
+ ${PROJECT_BINARY_DIR}/../css-properties.json
+ ${PROJECT_SOURCE_DIR}/../../target/doc/servo
+ DEPENDS Bindings _cache ${globalgen_deps} ${webidls} ${PROJECT_BINARY_DIR}/../css-properties.json
VERBATIM
)
-add_custom_command(
- OUTPUT apis.html
- COMMAND ${PYTHON_EXECUTABLE} -B ${bindings_src}/pythonpath.py -I ${bindings_src}/parser -I ${bindings_src}/ply
- ${bindings_src}/GlobalGen.py
- --cachedir=_cache
- --filelist=webidls.list
- --only-html
- ${bindings_src}/Bindings.conf
- .
- ${PROJECT_SOURCE_DIR}
- ${PROJECT_BINARY_DIR}/css_properties.json
- DEPENDS _cache ${globalgen_deps} ${webidls}
- VERBATIM
- )
-
-add_custom_target(supported-apis DEPENDS apis.html)
-
# We need an intermediate custom target for this, due to this misfeature:
# > If any dependency is an OUTPUT of another custom command in the same
# > directory CMake automatically brings the other custom command into the
diff --git a/components/script/build.rs b/components/script/build.rs
index d044b6e4fb4..bf496fb48f3 100644
--- a/components/script/build.rs
+++ b/components/script/build.rs
@@ -17,10 +17,8 @@ fn main() {
let style_out_dir = PathBuf::from(env::var_os("DEP_SERVO_STYLE_CRATE_OUT_DIR").unwrap());
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
- let build_dir = out_dir.join("build");
- let json = "css_properties.json";
- let _ = std::fs::create_dir(&build_dir); // Ignore errors: they most likely indicate it already exists
- std::fs::copy(style_out_dir.join(json), build_dir.join(json)).unwrap();
+ let json = "css-properties.json";
+ std::fs::copy(style_out_dir.join(json), out_dir.join(json)).unwrap();
// This must use the Ninja generator -- it's the only one that
// parallelizes cmake's output properly. (Cmake generates
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index c7b2c1fe5ef..72f13335ac0 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -7550,7 +7550,7 @@ impl %(base)s {
def SupportedDomApis(config):
descriptors = config.getDescriptors(isExposedConditionally=False)
- base_path = os.path.join('dom', 'bindings', 'codegen')
+ base_path = os.path.dirname(__file__)
with open(os.path.join(base_path, 'apis.html.template')) as f:
base_template = f.read()
with open(os.path.join(base_path, 'api.html.template')) as f:
diff --git a/components/script/dom/bindings/codegen/GlobalGen.py b/components/script/dom/bindings/codegen/GlobalGen.py
index 9fe736e71fd..1850a41d5f3 100644
--- a/components/script/dom/bindings/codegen/GlobalGen.py
+++ b/components/script/dom/bindings/codegen/GlobalGen.py
@@ -29,12 +29,10 @@ def generate_file(config, name, filename):
def main():
# Parse arguments.
from optparse import OptionParser
- usageString = "usage: %prog [options] configFile outputdir webidldir cssProperties.json [files]"
+ usageString = "usage: %prog [options] configFile outputdir webidldir cssProperties.json docServoDir [files]"
o = OptionParser(usage=usageString)
o.add_option("--cachedir", dest='cachedir', default=None,
help="Directory in which to cache lex/parse tables.")
- o.add_option("--only-html", dest='only_html', action="store_true",
- help="Only generate HTML from WebIDL inputs")
o.add_option("--filelist", dest='filelist', default=None,
help="A file containing the list (one per line) of webidl files to process.")
(options, args) = o.parse_args()
@@ -46,6 +44,7 @@ def main():
outputdir = args[1]
baseDir = args[2]
css_properties_json = args[3]
+ doc_servo = args[4]
if options.filelist is not None:
fileList = [l.strip() for l in open(options.filelist).xreadlines()]
else:
@@ -63,34 +62,30 @@ def main():
parserResults = parser.finish()
- if not options.only_html:
- # Write the parser results out to a pickle.
- resultsPath = os.path.join(outputdir, 'ParserResults.pkl')
- with open(resultsPath, 'wb') as resultsFile:
- cPickle.dump(parserResults, resultsFile, -1)
+ # Write the parser results out to a pickle.
+ resultsPath = os.path.join(outputdir, 'ParserResults.pkl')
+ with open(resultsPath, 'wb') as resultsFile:
+ cPickle.dump(parserResults, resultsFile, -1)
# Load the configuration.
config = Configuration(configFile, parserResults)
to_generate = [
- ('SupportedDomApis', 'apis.html'),
+ ('PrototypeList', 'PrototypeList.rs'),
+ ('RegisterBindings', 'RegisterBindings.rs'),
+ ('InterfaceObjectMap', 'InterfaceObjectMap.rs'),
+ ('InterfaceObjectMapData', 'InterfaceObjectMapData.json'),
+ ('InterfaceTypes', 'InterfaceTypes.rs'),
+ ('InheritTypes', 'InheritTypes.rs'),
+ ('Bindings', os.path.join('Bindings', 'mod.rs')),
+ ('UnionTypes', 'UnionTypes.rs'),
]
- if not options.only_html:
- to_generate = [
- ('PrototypeList', 'PrototypeList.rs'),
- ('RegisterBindings', 'RegisterBindings.rs'),
- ('InterfaceObjectMap', 'InterfaceObjectMap.rs'),
- ('InterfaceObjectMapData', 'InterfaceObjectMapData.json'),
- ('InterfaceTypes', 'InterfaceTypes.rs'),
- ('InheritTypes', 'InheritTypes.rs'),
- ('Bindings', os.path.join('Bindings', 'mod.rs')),
- ('UnionTypes', 'UnionTypes.rs'),
- ]
-
for name, filename in to_generate:
generate_file(config, name, os.path.join(outputdir, filename))
+ generate_file(config, 'SupportedDomApis', os.path.join(doc_servo, 'apis.html'))
+
def add_css_properties_attributes(webidl_files, css_properties_json, parser):
for filename in webidl_files:
@@ -102,10 +97,11 @@ def add_css_properties_attributes(webidl_files, css_properties_json, parser):
css_properties = json.load(open(css_properties_json, "rb"))
idl = "partial interface CSSStyleDeclaration {\n%s\n};\n" % "\n".join(
" [%sCEReactions, SetterThrows] attribute [TreatNullAs=EmptyString] DOMString %s;" % (
- ('Pref="%s", ' % pref if pref else ""),
+ ('Pref="%s", ' % data["pref"] if data["pref"] else ""),
attribute_name
)
- for (property_name, pref) in css_properties
+ for (kind, properties_list) in sorted(css_properties.items())
+ for (property_name, data) in sorted(properties_list.items())
for attribute_name in attribute_names(property_name)
)
parser.parse(idl.encode("utf-8"), "CSSStyleDeclaration_generated.webidl")
diff --git a/components/style/properties/build.py b/components/style/properties/build.py
index 186018e99a4..45d8fa676ab 100644
--- a/components/style/properties/build.py
+++ b/components/style/properties/build.py
@@ -101,21 +101,32 @@ def main():
pref_attr = "servo_2013_pref"
if engine == "servo-2020":
pref_attr = "servo_2020_pref"
- names_and_prefs = [
- (prop.name, getattr(prop, pref_attr))
- for p in properties.longhands + properties.shorthands
- if p.enabled_in_content()
- for prop in [p] + p.alias
- ]
- write(OUT_DIR, "css_properties.json", json.dumps(names_and_prefs, indent=4))
+ 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)
- elif output == "html":
- write_html(properties)
def abort(message):
@@ -153,19 +164,5 @@ def write(directory, filename, content):
abort("Found \"{}\" in {} ({})".format(python_addr.group(0), filename, full_path))
-def write_html(properties):
- properties = dict(
- (p.name, {
- "flag": p.servo_2013_pref,
- "shorthand": hasattr(p, "sub_properties")
- })
- for p in properties.longhands + properties.shorthands
- )
- doc_servo = os.path.join(BASE, "..", "..", "..", "target", "doc", "servo")
- 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__":
main()
diff --git a/components/style/properties/properties.html.mako b/components/style/properties/properties.html.mako
index d06524d3e13..5c515935175 100644
--- a/components/style/properties/properties.html.mako
+++ b/components/style/properties/properties.html.mako
@@ -3,38 +3,29 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="generator" content="rustdoc">
- <meta name="description" content="API documentation for the Rust `servo` crate.">
- <meta name="keywords" content="rust, rustlang, rust-lang, servo">
- <title>Supported CSS properties - servo - Rust</title>
+ <title>Supported CSS properties in Servo</title>
+ <link rel="stylesheet" type="text/css" href="../normalize.css">
<link rel="stylesheet" type="text/css" href="../rustdoc.css">
- <link rel="stylesheet" type="text/css" href="../main.css">
+ <link rel="stylesheet" type="text/css" href="../light.css">
</head>
<body class="rustdoc">
- <!--[if lte IE 8]>
- <div class="warning">
- This old browser is unsupported and will most likely display funky
- things.
- </div>
- <![endif]-->
<section id='main' class="content mod">
- <h1 class='fqn'><span class='in-band'>CSS properties currently supported in <a class='mod' href=''>Servo</a></span></h1>
- <div id='properties' class='docblock'>
- <table>
+ <h1 class='fqn'><span class='in-band'>CSS properties currently supported in Servo</span></h1>
+ % for kind, props in sorted(properties.items()):
+ <h2>${kind.capitalize()}</h2>
+ <table>
+ <tr>
+ <th>Name</th>
+ <th>Pref</th>
+ </tr>
+ % for name, data in sorted(props.items()):
<tr>
- <th>Property</th>
- <th>Flag</th>
- <th>Shorthand</th>
+ <td><code>${name}</code></td>
+ <td><code>${data['pref'] or ''}</code></td>
</tr>
- % for prop in properties:
- <tr>
- <td>${prop}</td>
- <td>${properties[prop]['flag']}</td>
- <td>${properties[prop]['shorthand']}</td>
- </tr>
- % endfor
- </table>
- </div>
+ % endfor
+ </table>
+ % endfor
</section>
</body>
</html>
diff --git a/python/servo/post_build_commands.py b/python/servo/post_build_commands.py
index 2e3a2aff8e2..1855fefff25 100644
--- a/python/servo/post_build_commands.py
+++ b/python/servo/post_build_commands.py
@@ -13,7 +13,6 @@ import json
import os
import os.path as path
import subprocess
-import sys
from shutil import copytree, rmtree, copy2
from mach.decorators import (
@@ -274,18 +273,6 @@ class PostBuildCommands(CommandBase):
for name in os.listdir(static):
copy2(path.join(static, name), path.join(docs, name))
- build = path.join(self.context.topdir, "components", "style", "properties", "build.py")
- if "layout-2020" in features:
- engine = "servo-2020"
- if "layout-2013" in features:
- engine = "servo-2013"
- subprocess.check_call([sys.executable, build, engine, "html"])
-
- script = path.join(self.context.topdir, "components", "script")
- subprocess.check_call(["cmake", "."], cwd=script)
- subprocess.check_call(["cmake", "--build", ".", "--target", "supported-apis"], cwd=script)
- copy2(path.join(script, "apis.html"), path.join(docs, "servo", "apis.html"))
-
@Command('browse-doc',
description='Generate documentation and open it in a web browser',
category='post-build')
diff --git a/tests/unit/style/properties/scaffolding.rs b/tests/unit/style/properties/scaffolding.rs
index bc521e2576f..d123f283c16 100644
--- a/tests/unit/style/properties/scaffolding.rs
+++ b/tests/unit/style/properties/scaffolding.rs
@@ -4,9 +4,8 @@
use serde_json::{self, Value};
use std::env;
-use std::fs::{remove_file, File};
+use std::fs::File;
use std::path::Path;
-use std::process::Command;
#[test]
fn properties_list_json() {
@@ -19,67 +18,10 @@ fn properties_list_json() {
.join("doc")
.join("servo")
.join("css-properties.json");
- if json.exists() {
- remove_file(&json).unwrap()
- }
- let python = env::var("PYTHON").ok().unwrap_or_else(find_python);
- let script = top
- .join("components")
- .join("style")
- .join("properties")
- .join("build.py");
- let status = Command::new(python)
- .arg(&script)
- .arg("servo-2013")
- .arg("html")
- .arg("regular")
- .status()
- .unwrap();
- assert!(status.success(), "{:?}", status);
let properties: Value = serde_json::from_reader(File::open(json).unwrap()).unwrap();
- assert!(properties.as_object().unwrap().len() > 100);
- assert!(properties.as_object().unwrap().contains_key("margin"));
- assert!(properties.as_object().unwrap().contains_key("margin-top"));
-}
-
-#[cfg(windows)]
-fn find_python() -> String {
- if Command::new("python2.7.exe")
- .arg("--version")
- .output()
- .is_ok()
- {
- return "python2.7.exe".to_owned();
- }
-
- if Command::new("python27.exe")
- .arg("--version")
- .output()
- .is_ok()
- {
- return "python27.exe".to_owned();
- }
-
- if Command::new("python.exe").arg("--version").output().is_ok() {
- return "python.exe".to_owned();
- }
-
- panic!("Can't find python (tried python27.exe and python.exe)! Try fixing PATH or setting the PYTHON env var");
-}
-
-#[cfg(not(windows))]
-fn find_python() -> String {
- if Command::new("python2.7")
- .arg("--version")
- .output()
- .unwrap()
- .status
- .success()
- {
- "python2.7"
- } else {
- "python"
- }
- .to_owned()
+ let longhands = properties["longhands"].as_object().unwrap();
+ assert!(longhands.len() > 100);
+ assert!(longhands.get("margin-top").is_some());
+ assert!(properties["shorthands"].get("margin").is_some());
}