WebUI: Support wrapping of Lit element templates in html_to_wrapper().
This is part of the ongoing experimentation to offer Lit as an
alternative to Polymer.
Bug: 1503223
Change-Id: I6c7a7941b401417e2f6baa3494bbbf943f867e2d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5078093
Commit-Queue: Demetrios Papadopoulos <[email protected]>
Reviewed-by: Rebekah Potter <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1232258}
diff --git a/tools/polymer/html_to_wrapper.py b/tools/polymer/html_to_wrapper.py
index d0ee812..749fb6d 100644
--- a/tools/polymer/html_to_wrapper.py
+++ b/tools/polymer/html_to_wrapper.py
@@ -32,43 +32,58 @@
sys.path.append(path.join(_SRC_PATH, 'third_party', 'node'))
import node
-# Template for non-Polymer elements.
-_NON_POLYMER_ELEMENT_TEMPLATE = """import {getTrustedHTML} from '%(scheme)s//resources/js/static_types.js';
+# Template for native web component HTML templates.
+_NATIVE_ELEMENT_TEMPLATE = """import {getTrustedHTML} from '%(scheme)s//resources/js/static_types.js';
export function getTemplate() {
return getTrustedHTML`<!--_html_template_start_-->%(content)s<!--_html_template_end_-->`;
}"""
-# Template for Polymer elements.
-_ELEMENT_TEMPLATE = """import {html} from '%(scheme)s//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+# Template for Polymer web component HTML templates.
+_POLYMER_ELEMENT_TEMPLATE = """import {html} from '%(scheme)s//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
export function getTemplate() {
return html`<!--_html_template_start_-->%(content)s<!--_html_template_end_-->`;
}"""
-_ICONS_TEMPLATE = """import '%(scheme)s//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
+# Template for Lit component HTML templates.
+_LIT_ELEMENT_TEMPLATE = """import {html} from '%(scheme)s//resources/lit/v3_0/lit.rollup.js';
+import type {%(class_name)s} from './%(file_name)s.js';
+
+export function getHtml(this: %(class_name)s) {
+ return html`<!--_html_template_start_-->%(content)s<!--_html_template_end_-->`;
+}"""
+
+# Template for Polymer icon HTML files.
+_POLYMER_ICONS_TEMPLATE = """import '%(scheme)s//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
import {html} from '%(scheme)s//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
const template = html`%(content)s`;
document.head.appendChild(template.content);
"""
-# Token used to detect whether the underlying custom element is based on
-# Polymer.
+# Tokens used to detect whether the underlying custom element is based on
+# Polymer or Lit.
POLYMER_TOKEN = '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'
+LIT_TOKEN = '//resources/lit/v3_0/lit.rollup.js'
+
+# Map holding all the different types of HTML files to generate wrappers for.
+TEMPLATE_MAP = {
+ 'lit': _LIT_ELEMENT_TEMPLATE,
+ 'native': _NATIVE_ELEMENT_TEMPLATE,
+ 'polymer_icons': _POLYMER_ICONS_TEMPLATE,
+ 'polymer': _POLYMER_ELEMENT_TEMPLATE,
+}
-# Detects whether the element to be wrapped is using Polymer or native APIs.
-def get_wrapper_element_template(template_type, definition_file):
- if template_type == 'native':
- return _NON_POLYMER_ELEMENT_TEMPLATE
+def detect_template_type(definition_file):
+ with io.open(definition_file, encoding='utf-8', mode='r') as f:
+ content = f.read()
- if template_type == 'polymer':
- return _ELEMENT_TEMPLATE
+ if POLYMER_TOKEN in content:
+ return 'polymer'
+ elif LIT_TOKEN in content:
+ return 'lit'
- if template_type == 'detect':
- with io.open(definition_file, encoding='utf-8', mode='r') as f:
- content = f.read()
- return _ELEMENT_TEMPLATE if POLYMER_TOKEN in content else \
- _NON_POLYMER_ELEMENT_TEMPLATE
+ return 'native'
def main(argv):
@@ -79,7 +94,7 @@
parser.add_argument('--minify', action='store_true')
parser.add_argument('--use_js', action='store_true')
parser.add_argument('--template',
- choices=['polymer', 'native', 'detect'],
+ choices=['polymer', 'lit', 'native', 'detect'],
default='polymer')
parser.add_argument('--scheme',
choices=['chrome', 'relative'],
@@ -130,23 +145,36 @@
html_content = f.read()
template = None
+ template_type = args.template
filename = path.basename(in_file)
if filename == 'icons.html' or filename.endswith('_icons.html'):
- assert args.template != 'native', (
- 'Polymer icons files not supported with template="native"')
- template = _ICONS_TEMPLATE
- else:
+ assert args.template == 'polymer' or args.template == 'detect', (
+ r'Polymer icons files not supported with template="%s"' %
+ args.template)
+ template_type = 'polymer_icons'
+ elif template_type == 'detect':
# Locate the file that holds the web component's definition. Assumed to
# be in the same folder as input HTML template file.
definition_file = path.splitext(path.join(in_folder,
in_file))[0] + extension
- template = get_wrapper_element_template(args.template, definition_file)
+ template_type = detect_template_type(definition_file)
- wrapper = template % {
+ substitutions = {
'content': html_content,
'scheme': 'chrome:' if args.scheme == 'chrome' else '',
}
+ if template_type == 'lit':
+ # Add Lit specific substitutions.
+ basename = path.splitext(path.basename(in_file))[0]
+ # Derive class name from file name. For example
+ # foo_bar.html -> FooBarElement.
+ class_name = ''.join(map(str.title, basename.split('_'))) + 'Element'
+ substitutions['class_name'] = class_name
+ substitutions['file_name'] = basename
+
+ wrapper = TEMPLATE_MAP[template_type] % substitutions
+
out_folder_for_file = path.join(out_folder, path.dirname(in_file))
makedirs(out_folder_for_file, exist_ok=True)
out_file = path.join(out_folder, in_file) + extension