mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
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).
This commit is contained in:
parent
ddb4e369dd
commit
0215d09ccb
8 changed files with 67 additions and 173 deletions
|
@ -41,7 +41,6 @@ set(globalgen_deps
|
||||||
${bindings_src}/Configuration.py
|
${bindings_src}/Configuration.py
|
||||||
${bindings_src}/CodegenRust.py
|
${bindings_src}/CodegenRust.py
|
||||||
${bindings_src}/parser/WebIDL.py
|
${bindings_src}/parser/WebIDL.py
|
||||||
${PROJECT_BINARY_DIR}/css_properties.json
|
|
||||||
)
|
)
|
||||||
set(bindinggen_deps
|
set(bindinggen_deps
|
||||||
${globalgen_deps}
|
${globalgen_deps}
|
||||||
|
@ -69,28 +68,12 @@ add_custom_command(
|
||||||
${bindings_src}/Bindings.conf
|
${bindings_src}/Bindings.conf
|
||||||
.
|
.
|
||||||
${PROJECT_SOURCE_DIR}
|
${PROJECT_SOURCE_DIR}
|
||||||
${PROJECT_BINARY_DIR}/css_properties.json
|
${PROJECT_BINARY_DIR}/../css-properties.json
|
||||||
DEPENDS Bindings _cache ${globalgen_deps} ${webidls}
|
${PROJECT_SOURCE_DIR}/../../target/doc/servo
|
||||||
|
DEPENDS Bindings _cache ${globalgen_deps} ${webidls} ${PROJECT_BINARY_DIR}/../css-properties.json
|
||||||
VERBATIM
|
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:
|
# 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
|
# > If any dependency is an OUTPUT of another custom command in the same
|
||||||
# > directory CMake automatically brings the other custom command into the
|
# > directory CMake automatically brings the other custom command into the
|
||||||
|
|
|
@ -17,10 +17,8 @@ fn main() {
|
||||||
|
|
||||||
let style_out_dir = PathBuf::from(env::var_os("DEP_SERVO_STYLE_CRATE_OUT_DIR").unwrap());
|
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 out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
let build_dir = out_dir.join("build");
|
let json = "css-properties.json";
|
||||||
let json = "css_properties.json";
|
std::fs::copy(style_out_dir.join(json), out_dir.join(json)).unwrap();
|
||||||
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();
|
|
||||||
|
|
||||||
// This must use the Ninja generator -- it's the only one that
|
// This must use the Ninja generator -- it's the only one that
|
||||||
// parallelizes cmake's output properly. (Cmake generates
|
// parallelizes cmake's output properly. (Cmake generates
|
||||||
|
|
|
@ -7550,7 +7550,7 @@ impl %(base)s {
|
||||||
def SupportedDomApis(config):
|
def SupportedDomApis(config):
|
||||||
descriptors = config.getDescriptors(isExposedConditionally=False)
|
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:
|
with open(os.path.join(base_path, 'apis.html.template')) as f:
|
||||||
base_template = f.read()
|
base_template = f.read()
|
||||||
with open(os.path.join(base_path, 'api.html.template')) as f:
|
with open(os.path.join(base_path, 'api.html.template')) as f:
|
||||||
|
|
|
@ -29,12 +29,10 @@ def generate_file(config, name, filename):
|
||||||
def main():
|
def main():
|
||||||
# Parse arguments.
|
# Parse arguments.
|
||||||
from optparse import OptionParser
|
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 = OptionParser(usage=usageString)
|
||||||
o.add_option("--cachedir", dest='cachedir', default=None,
|
o.add_option("--cachedir", dest='cachedir', default=None,
|
||||||
help="Directory in which to cache lex/parse tables.")
|
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,
|
o.add_option("--filelist", dest='filelist', default=None,
|
||||||
help="A file containing the list (one per line) of webidl files to process.")
|
help="A file containing the list (one per line) of webidl files to process.")
|
||||||
(options, args) = o.parse_args()
|
(options, args) = o.parse_args()
|
||||||
|
@ -46,6 +44,7 @@ def main():
|
||||||
outputdir = args[1]
|
outputdir = args[1]
|
||||||
baseDir = args[2]
|
baseDir = args[2]
|
||||||
css_properties_json = args[3]
|
css_properties_json = args[3]
|
||||||
|
doc_servo = args[4]
|
||||||
if options.filelist is not None:
|
if options.filelist is not None:
|
||||||
fileList = [l.strip() for l in open(options.filelist).xreadlines()]
|
fileList = [l.strip() for l in open(options.filelist).xreadlines()]
|
||||||
else:
|
else:
|
||||||
|
@ -63,7 +62,6 @@ def main():
|
||||||
|
|
||||||
parserResults = parser.finish()
|
parserResults = parser.finish()
|
||||||
|
|
||||||
if not options.only_html:
|
|
||||||
# Write the parser results out to a pickle.
|
# Write the parser results out to a pickle.
|
||||||
resultsPath = os.path.join(outputdir, 'ParserResults.pkl')
|
resultsPath = os.path.join(outputdir, 'ParserResults.pkl')
|
||||||
with open(resultsPath, 'wb') as resultsFile:
|
with open(resultsPath, 'wb') as resultsFile:
|
||||||
|
@ -72,11 +70,6 @@ def main():
|
||||||
# Load the configuration.
|
# Load the configuration.
|
||||||
config = Configuration(configFile, parserResults)
|
config = Configuration(configFile, parserResults)
|
||||||
|
|
||||||
to_generate = [
|
|
||||||
('SupportedDomApis', 'apis.html'),
|
|
||||||
]
|
|
||||||
|
|
||||||
if not options.only_html:
|
|
||||||
to_generate = [
|
to_generate = [
|
||||||
('PrototypeList', 'PrototypeList.rs'),
|
('PrototypeList', 'PrototypeList.rs'),
|
||||||
('RegisterBindings', 'RegisterBindings.rs'),
|
('RegisterBindings', 'RegisterBindings.rs'),
|
||||||
|
@ -91,6 +84,8 @@ def main():
|
||||||
for name, filename in to_generate:
|
for name, filename in to_generate:
|
||||||
generate_file(config, name, os.path.join(outputdir, filename))
|
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):
|
def add_css_properties_attributes(webidl_files, css_properties_json, parser):
|
||||||
for filename in webidl_files:
|
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"))
|
css_properties = json.load(open(css_properties_json, "rb"))
|
||||||
idl = "partial interface CSSStyleDeclaration {\n%s\n};\n" % "\n".join(
|
idl = "partial interface CSSStyleDeclaration {\n%s\n};\n" % "\n".join(
|
||||||
" [%sCEReactions, SetterThrows] attribute [TreatNullAs=EmptyString] DOMString %s;" % (
|
" [%sCEReactions, SetterThrows] attribute [TreatNullAs=EmptyString] DOMString %s;" % (
|
||||||
('Pref="%s", ' % pref if pref else ""),
|
('Pref="%s", ' % data["pref"] if data["pref"] else ""),
|
||||||
attribute_name
|
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)
|
for attribute_name in attribute_names(property_name)
|
||||||
)
|
)
|
||||||
parser.parse(idl.encode("utf-8"), "CSSStyleDeclaration_generated.webidl")
|
parser.parse(idl.encode("utf-8"), "CSSStyleDeclaration_generated.webidl")
|
||||||
|
|
|
@ -101,21 +101,32 @@ def main():
|
||||||
pref_attr = "servo_2013_pref"
|
pref_attr = "servo_2013_pref"
|
||||||
if engine == "servo-2020":
|
if engine == "servo-2020":
|
||||||
pref_attr = "servo_2020_pref"
|
pref_attr = "servo_2020_pref"
|
||||||
names_and_prefs = [
|
properties_dict = {
|
||||||
(prop.name, getattr(prop, pref_attr))
|
kind: {
|
||||||
for p in properties.longhands + properties.shorthands
|
p.name: {
|
||||||
if p.enabled_in_content()
|
"pref": getattr(p, pref_attr)
|
||||||
for prop in [p] + p.alias
|
}
|
||||||
|
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)
|
||||||
]
|
]
|
||||||
write(OUT_DIR, "css_properties.json", json.dumps(names_and_prefs, indent=4))
|
}
|
||||||
|
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":
|
elif output == "geckolib":
|
||||||
if len(sys.argv) < 4:
|
if len(sys.argv) < 4:
|
||||||
abort(usage)
|
abort(usage)
|
||||||
template = sys.argv[3]
|
template = sys.argv[3]
|
||||||
header = render(template, data=properties)
|
header = render(template, data=properties)
|
||||||
sys.stdout.write(header)
|
sys.stdout.write(header)
|
||||||
elif output == "html":
|
|
||||||
write_html(properties)
|
|
||||||
|
|
||||||
|
|
||||||
def abort(message):
|
def abort(message):
|
||||||
|
@ -153,19 +164,5 @@ def write(directory, filename, content):
|
||||||
abort("Found \"{}\" in {} ({})".format(python_addr.group(0), filename, full_path))
|
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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -3,38 +3,29 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="generator" content="rustdoc">
|
<title>Supported CSS properties in Servo</title>
|
||||||
<meta name="description" content="API documentation for the Rust `servo` crate.">
|
<link rel="stylesheet" type="text/css" href="../normalize.css">
|
||||||
<meta name="keywords" content="rust, rustlang, rust-lang, servo">
|
|
||||||
<title>Supported CSS properties - servo - Rust</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="../rustdoc.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>
|
</head>
|
||||||
<body class="rustdoc">
|
<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">
|
<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>
|
<h1 class='fqn'><span class='in-band'>CSS properties currently supported in Servo</span></h1>
|
||||||
<div id='properties' class='docblock'>
|
% for kind, props in sorted(properties.items()):
|
||||||
|
<h2>${kind.capitalize()}</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Property</th>
|
<th>Name</th>
|
||||||
<th>Flag</th>
|
<th>Pref</th>
|
||||||
<th>Shorthand</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
% for prop in properties:
|
% for name, data in sorted(props.items()):
|
||||||
<tr>
|
<tr>
|
||||||
<td>${prop}</td>
|
<td><code>${name}</code></td>
|
||||||
<td>${properties[prop]['flag']}</td>
|
<td><code>${data['pref'] or ''}</code></td>
|
||||||
<td>${properties[prop]['shorthand']}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
% endfor
|
% endfor
|
||||||
</table>
|
</table>
|
||||||
</div>
|
% endfor
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -13,7 +13,6 @@ import json
|
||||||
import os
|
import os
|
||||||
import os.path as path
|
import os.path as path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
from shutil import copytree, rmtree, copy2
|
from shutil import copytree, rmtree, copy2
|
||||||
|
|
||||||
from mach.decorators import (
|
from mach.decorators import (
|
||||||
|
@ -274,18 +273,6 @@ class PostBuildCommands(CommandBase):
|
||||||
for name in os.listdir(static):
|
for name in os.listdir(static):
|
||||||
copy2(path.join(static, name), path.join(docs, name))
|
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',
|
@Command('browse-doc',
|
||||||
description='Generate documentation and open it in a web browser',
|
description='Generate documentation and open it in a web browser',
|
||||||
category='post-build')
|
category='post-build')
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
|
|
||||||
use serde_json::{self, Value};
|
use serde_json::{self, Value};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{remove_file, File};
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn properties_list_json() {
|
fn properties_list_json() {
|
||||||
|
@ -19,67 +18,10 @@ fn properties_list_json() {
|
||||||
.join("doc")
|
.join("doc")
|
||||||
.join("servo")
|
.join("servo")
|
||||||
.join("css-properties.json");
|
.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();
|
let properties: Value = serde_json::from_reader(File::open(json).unwrap()).unwrap();
|
||||||
assert!(properties.as_object().unwrap().len() > 100);
|
let longhands = properties["longhands"].as_object().unwrap();
|
||||||
assert!(properties.as_object().unwrap().contains_key("margin"));
|
assert!(longhands.len() > 100);
|
||||||
assert!(properties.as_object().unwrap().contains_key("margin-top"));
|
assert!(longhands.get("margin-top").is_some());
|
||||||
}
|
assert!(properties["shorthands"].get("margin").is_some());
|
||||||
|
|
||||||
#[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()
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue