# 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/. """ This script implements the `mach devtools-css-db` command. It runs an xpcshell script that uses inIDOMUtils to query the CSS properties used by the browser. This information is used to generate the properties-db.js file. """ import json import os import sys import string import subprocess from mozbuild.base import ( MozbuildObject, MachCommandBase, ) from mach.decorators import ( CommandProvider, Command, ) def resolve_path(start, relativePath): """Helper to resolve a path from a start, and a relative path""" return os.path.normpath(os.path.join(start, relativePath)) def stringify(obj): """Helper to stringify to JSON""" return json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': ')) @CommandProvider class MachCommands(MachCommandBase): @Command( 'devtools-css-db', category='post-build', description='Rebuild the devtool\'s static css properties database.') def generate_css_db(self): """Generate the static css properties database for devtools and write it to file.""" print("Re-generating the css properties database...") db = self.get_properties_db_from_xpcshell() self.output_template({ 'cssProperties': stringify(db['cssProperties']), 'pseudoElements': stringify(db['pseudoElements'])}) def get_properties_db_from_xpcshell(self): """Generate the static css properties db for devtools from an xpcshell script.""" build = MozbuildObject.from_environment() # Get the paths script_path = resolve_path(self.topsrcdir, 'devtools/shared/css/generated/generate-properties-db.js') gre_path = resolve_path(self.topobjdir, 'dist/bin') browser_path = resolve_path(self.topobjdir, 'dist/bin/browser') xpcshell_path = build.get_binary_path(what='xpcshell') print(browser_path) sub_env = dict(os.environ) if sys.platform.startswith('linux'): sub_env["LD_LIBRARY_PATH"] = gre_path # Run the xcpshell script, and set the appdir flag to the browser path so that # we have the proper dependencies for requiring the loader. contents = subprocess.check_output([xpcshell_path, '-g', gre_path, '-a', browser_path, script_path], env = sub_env) # Extract just the output between the delimiters as the xpcshell output can # have extra output that we don't want. contents = contents.split('DEVTOOLS_CSS_DB_DELIMITER')[1] return json.loads(contents) def output_template(self, substitutions): """Output a the properties-db.js from a template.""" js_template_path = resolve_path(self.topsrcdir, 'devtools/shared/css/generated/properties-db.js.in') destination_path = resolve_path(self.topsrcdir, 'devtools/shared/css/generated/properties-db.js') with open(js_template_path, 'rb') as handle: js_template = handle.read() preamble = '/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT */\n\n' contents = string.Template(js_template).substitute(substitutions) with open(destination_path, 'wb') as destination: destination.write(preamble + contents) print('The database was successfully generated at ' + destination_path)