Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame^] | 1 | # Copyright 2022 The Chromium Authors |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 5 | # Genaretes a wrapper TS file around a source HTML file holding either |
| 6 | # 1) a Polymer element template or |
| 7 | # 2) an <iron-iconset-svg> definitions |
| 8 | # |
| 9 | # Note: The HTML file must be named either 'icons.html' or be suffixed with |
| 10 | # '_icons.html' for this tool to treat them as #2. Consequently, files holding |
| 11 | # Polymer element templates should not use such naming to be treated as #1. |
| 12 | # |
| 13 | # In case #1 the wrapper exports a getTemplate() function that can be used at |
| 14 | # runtime to import the template. This is useful for implementing Web Components |
| 15 | # using JS modules, where all the HTML needs to reside in a JS file (no more |
| 16 | # HTML imports). |
| 17 | # |
| 18 | # In case #2 the wrapper adds the <iron-iconset-svg> element to <head>, so that |
| 19 | # it can be used by <iron-icon> instances. |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 20 | |
| 21 | import argparse |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 22 | import io |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 23 | import shutil |
| 24 | import sys |
| 25 | import tempfile |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 26 | from os import path, getcwd, makedirs |
| 27 | |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 28 | _HERE_PATH = path.dirname(__file__) |
| 29 | _SRC_PATH = path.normpath(path.join(_HERE_PATH, '..', '..')) |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 30 | _CWD = getcwd() |
| 31 | |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 32 | sys.path.append(path.join(_SRC_PATH, 'third_party', 'node')) |
| 33 | import node |
| 34 | |
dpapad | bc6fc93 | 2022-05-28 00:47:57 | [diff] [blame] | 35 | # Template for non-Polymer elements. |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 36 | _NON_POLYMER_ELEMENT_TEMPLATE = """import {getTrustedHTML} from '%(scheme)s//resources/js/static_types.js'; |
dpapad | bc6fc93 | 2022-05-28 00:47:57 | [diff] [blame] | 37 | export function getTemplate() { |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 38 | return getTrustedHTML`<!--_html_template_start_-->%(content)s<!--_html_template_end_-->`; |
dpapad | bc6fc93 | 2022-05-28 00:47:57 | [diff] [blame] | 39 | }""" |
| 40 | |
| 41 | # Template for Polymer elements. |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 42 | _ELEMENT_TEMPLATE = """import {html} from '%(scheme)s//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 43 | export function getTemplate() { |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 44 | return html`<!--_html_template_start_-->%(content)s<!--_html_template_end_-->`; |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 45 | }""" |
| 46 | |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 47 | _ICONS_TEMPLATE = """import '%(scheme)s//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; |
| 48 | import {html} from '%(scheme)s//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 49 | |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 50 | const template = html`%(content)s`; |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 51 | document.head.appendChild(template.content); |
| 52 | """ |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 53 | |
| 54 | |
| 55 | def main(argv): |
| 56 | parser = argparse.ArgumentParser() |
| 57 | parser.add_argument('--in_folder', required=True) |
| 58 | parser.add_argument('--out_folder', required=True) |
| 59 | parser.add_argument('--in_files', required=True, nargs="*") |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 60 | parser.add_argument('--minify', action='store_true') |
dpapad | 0fb3780 | 2022-07-13 01:00:52 | [diff] [blame] | 61 | parser.add_argument('--use_js', action='store_true') |
dpapad | bc6fc93 | 2022-05-28 00:47:57 | [diff] [blame] | 62 | parser.add_argument('--template', |
| 63 | choices=['polymer', 'native'], |
| 64 | default='polymer') |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 65 | parser.add_argument('--scheme', |
| 66 | choices=['chrome', 'relative'], |
| 67 | default='chrome') |
dpapad | bc6fc93 | 2022-05-28 00:47:57 | [diff] [blame] | 68 | |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 69 | args = parser.parse_args(argv) |
| 70 | |
| 71 | in_folder = path.normpath(path.join(_CWD, args.in_folder)) |
| 72 | out_folder = path.normpath(path.join(_CWD, args.out_folder)) |
dpapad | 0fb3780 | 2022-07-13 01:00:52 | [diff] [blame] | 73 | extension = '.js' if args.use_js else '.ts' |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 74 | |
| 75 | results = [] |
| 76 | |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 77 | # The folder to be used to read the HTML files to be wrapped. |
| 78 | wrapper_in_folder = in_folder |
| 79 | |
| 80 | if args.minify: |
| 81 | # Minify the HTML files with html-minifier before generating the wrapper |
| 82 | # .ts files. |
| 83 | # Note: Passing all HTML files to html-minifier all at once because |
| 84 | # passing them individually takes a lot longer. |
| 85 | # Storing the output in a temporary folder, which is used further below when |
| 86 | # creating the final wrapper files. |
| 87 | tmp_out_dir = tempfile.mkdtemp(dir=out_folder) |
| 88 | try: |
| 89 | wrapper_in_folder = tmp_out_dir |
| 90 | |
| 91 | # Using the programmatic Node API to invoke html-minifier, because the |
| 92 | # built-in command line API does not support explicitly specifying |
| 93 | # multiple files to be processed, and only supports specifying an input |
| 94 | # folder, which would lead to potentially processing unnecessary HTML |
| 95 | # files that are not part of the build (stale), or handled by other |
| 96 | # html_to_wrapper targets. |
| 97 | node.RunNode( |
| 98 | [path.join(_HERE_PATH, 'html_minifier.js'), in_folder, tmp_out_dir] + |
| 99 | args.in_files) |
| 100 | except RuntimeError as err: |
| 101 | shutil.rmtree(tmp_out_dir) |
| 102 | raise err |
| 103 | |
| 104 | # Wrap the input files (minified or not) with an enclosing .ts file. |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 105 | for in_file in args.in_files: |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 106 | wrapper_in_file = path.join(wrapper_in_folder, in_file) |
| 107 | |
| 108 | with io.open(wrapper_in_file, encoding='utf-8', mode='r') as f: |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 109 | html_content = f.read() |
| 110 | |
| 111 | wrapper = None |
dpapad | bc6fc93 | 2022-05-28 00:47:57 | [diff] [blame] | 112 | template = _ELEMENT_TEMPLATE \ |
| 113 | if args.template == 'polymer' else _NON_POLYMER_ELEMENT_TEMPLATE |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 114 | |
| 115 | filename = path.basename(in_file) |
| 116 | if filename == 'icons.html' or filename.endswith('_icons.html'): |
| 117 | template = _ICONS_TEMPLATE |
| 118 | |
dpapad | 24071ff | 2022-09-02 01:07:54 | [diff] [blame] | 119 | wrapper = template % { |
| 120 | 'content': html_content, |
| 121 | 'scheme': 'chrome:' if args.scheme == 'chrome' else '', |
| 122 | } |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 123 | |
| 124 | out_folder_for_file = path.join(out_folder, path.dirname(in_file)) |
| 125 | makedirs(out_folder_for_file, exist_ok=True) |
| 126 | with io.open(path.join(out_folder, in_file) + extension, mode='wb') as f: |
dpapad | b0e74d3 | 2022-05-10 18:39:31 | [diff] [blame] | 127 | f.write(wrapper.encode('utf-8')) |
dpapad | d55b8f7 | 2022-06-29 19:37:32 | [diff] [blame] | 128 | |
| 129 | if args.minify: |
| 130 | # Delete the temporary folder that was holding minified HTML files, no |
| 131 | # longer needed. |
| 132 | shutil.rmtree(tmp_out_dir) |
| 133 | |
dpapad | 5d67ad17 | 2022-01-24 10:04:05 | [diff] [blame] | 134 | return |
| 135 | |
| 136 | |
| 137 | if __name__ == '__main__': |
| 138 | main(sys.argv[1:]) |