diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2019-07-29 18:57:20 +0200 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2019-07-30 08:37:33 +0200 |
commit | 0215d09ccbfed85c91605dedbb175dc9a96ba0ab (patch) | |
tree | 748fa7b4806ce88d8d1376b95f386812bede0383 | |
parent | ddb4e369ddb8d9bb20142d34e320370cd3be196f (diff) | |
download | servo-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.txt | 23 | ||||
-rw-r--r-- | components/script/build.rs | 6 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 2 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/GlobalGen.py | 42 | ||||
-rw-r--r-- | components/style/properties/build.py | 43 | ||||
-rw-r--r-- | components/style/properties/properties.html.mako | 43 | ||||
-rw-r--r-- | python/servo/post_build_commands.py | 13 | ||||
-rw-r--r-- | tests/unit/style/properties/scaffolding.rs | 68 |
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()); } |