From e1b60500383c3da79fb28f382183a6375177fd48 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Tue, 30 Nov 2021 16:25:32 -0800 Subject: [PATCH 01/15] perf: hoist static object/arrays in templates Fixes #2559 W-10113376 --- .../expected_compat_config_simple_app.js | 34 +- .../expected_default_config_simple_app.js | 32 +- ..._default_config_simple_app_css_resolver.js | 32 +- ...cted_default_config_simple_app_relative.js | 32 +- ...d_default_config_simple_app_third_party.js | 7 +- ...lt_config_simple_app_with_scoped_styles.js | 8 +- .../expected_default_config_ts_simple_app.js | 32 +- .../attributes/attribute-allow/expected.js | 20 +- .../attribute-crossorigin/expected.js | 58 +- .../expected.js | 50 +- .../attribute-href-with-id/expected.js | 50 +- .../attributes/attribute-href/expected.js | 65 +- .../attribute-uppercase/expected.js | 33 +- .../hidden-global-attr/expected.js | 146 +-- .../boolean-attribute/required/expected.js | 174 ++- .../boolean-attributes-valid/expected.js | 66 +- .../fixtures/attributes/boolean/expected.js | 20 +- .../fixtures/attributes/class/expected.js | 75 +- .../attributes/dataset-complex/expected.js | 31 +- .../fixtures/attributes/dataset/expected.js | 33 +- .../attributes/error-empty-value/expected.js | 38 +- .../attributes/html-input/expected.js | 34 +- .../attributes/html-tag-invalid/expected.js | 34 +- .../fixtures/attributes/html-tag/expected.js | 30 +- .../fixtures/attributes/id/expected.js | 13 +- .../attributes/mixed-props-attrs/expected.js | 133 +- .../spellcheck/static/false-value/expected.js | 55 +- .../static/truthy-value/expected.js | 55 +- .../fixtures/attributes/style/expected.js | 15 +- .../attributes/tabindex-computed/expected.js | 3 +- .../expected.js | 20 +- .../__tests__/fixtures/base/class/expected.js | 24 +- .../base/style-expression/expected.js | 3 +- .../fixtures/base/style-important/expected.js | 3 +- .../fixtures/base/style-static/expected.js | 5 +- .../base/svg-with-iteration/expected.js | 12 +- .../__tests__/fixtures/base/svg/expected.js | 60 +- .../fixtures/base/template/expected.js | 13 +- .../fixtures/comments/basic/expected.js | 11 +- .../comments/directive-for-each/expected.js | 7 +- .../comments/directive-if/expected.js | 24 +- .../preserve-html-comments-option/expected.js | 11 +- .../fixtures/comments/slots/expected.js | 27 +- .../flatten-child/expected.js | 24 +- .../directive-dynamic/only-child/expected.js | 13 +- .../directive-for-each/children/expected.js | 107 +- .../foreach-with-if/expected.js | 7 +- .../inline-index/expected.js | 7 +- .../inline-item/expected.js | 27 +- .../expected.js | 36 +- .../inline-refence-item/expected.js | 7 +- .../inline-sibling/expected.js | 18 +- .../directive-for-each/inline/expected.js | 27 +- .../template-multiple-children/expected.js | 7 +- .../expected.js | 7 +- .../template-sibling/expected.js | 18 +- .../directive-for-each/template/expected.js | 7 +- .../directive-if/inline-multiple/expected.js | 52 +- .../inline-sibling-static/expected.js | 41 +- .../directive-if/strict-true/expected.js | 26 +- .../template-expression/expected.js | 23 +- .../directive-if/template-if-else/expected.js | 26 +- .../template-multiple/expected.js | 39 +- .../template-sibiling/expected.js | 48 +- .../directive-if/template/expected.js | 23 +- .../usage-if-for-each/expected.js | 35 +- .../directive-inner-html/valid/expected.js | 22 +- .../directive-iterator/iterator/expected.js | 20 +- .../directive-key/component/expected.js | 7 +- .../directive-key/element/expected.js | 7 +- .../directive-key/for-each/expected.js | 27 +- .../iterator-key-identifier/expected.js | 7 +- .../expected.js | 7 +- .../iterator-value-as-key/expected.js | 7 +- .../nested-iterator-if/expected.js | 20 +- .../outside-iterator/expected.js | 3 +- .../shadow-template/expected.js | 13 +- .../template/expected.js | 41 +- .../fixtures/events/component/expected.js | 34 +- .../__tests__/fixtures/events/tag/expected.js | 49 +- .../expression/attribute-deep/expected.js | 30 +- .../expression/attribute-multiple/expected.js | 3 +- .../fixtures/expression/attribute/expected.js | 30 +- .../fixtures/expression/escaped/expected.js | 20 +- .../fixtures/expression/tag/expected.js | 13 +- .../html-tags/unkown-element/expected.js | 52 +- .../fixtures/lwc-dom/comments/expected.js | 24 +- .../fixtures/lwc-dom/manual/expected.js | 24 +- .../fixtures/metadata/used-attrs/expected.js | 24 +- .../duplicate-default-slot/expected.js | 25 +- .../duplicate-named-slot/expected.js | 37 +- .../multiple-attributes/expected.js | 7 +- .../single-attribute/expected.js | 3 +- .../named-slot-in-iterator/expected.js | 21 +- .../slot-in-iterator/expected.js | 15 +- .../regression/class-name-slash/expected.js | 27 +- .../regression/dashed-html-tag/expected.js | 29 +- .../regression/excaped-json/expected.js | 21 +- .../handler-memoization/expected.js | 7 +- .../invalid-html-recovery/expected.js | 23 +- .../regression/nested-if-loops/expected.js | 3 +- .../slot-name-with-dash/expected.js | 26 +- .../regression/table-with-tr/expected.js | 36 +- .../secure/secure-template/expected.js | 15 +- .../slots/component-definition/expected.js | 27 +- .../definition-sibiling-slot/expected.js | 75 +- .../definition-sibling-static/expected.js | 52 +- .../fixtures/slots/definition/expected.js | 41 +- .../fixtures/slots/mixed-1/expected.js | 126 +- .../fixtures/slots/mixed/expected.js | 56 +- .../fixtures/slots/no-slot/expected.js | 15 +- .../slots/usage-if-for-each/expected.js | 16 +- .../fixtures/slots/usage-if/expected.js | 63 +- .../fixtures/slots/usage-named/expected.js | 47 +- .../fixtures/slots/usage/expected.js | 61 +- .../__tests__/fixtures/svg/filter/expected.js | 1088 ++++++++--------- .../fixtures/svg/foreign-object/expected.js | 114 +- .../fixtures/svg/linear-gradient/expected.js | 136 +-- .../svg/scoped-id-dynamic/expected.js | 137 +-- .../fixtures/svg/scoped-id-static/expected.js | 137 +-- .../fixtures/svg/simple-svg/expected.js | 105 +- .../fixtures/svg/valid-image/expected.js | 51 +- .../fixtures/svg/valid-svg/expected.js | 289 ++--- .../xlink-with-expression-value/expected.js | 60 +- .../svg/xlink-with-literal-value/expected.js | 60 +- .../src/codegen/formatters/function.ts | 5 +- .../src/codegen/formatters/module.ts | 5 +- .../template-compiler/src/codegen/optimize.ts | 105 ++ .../template-compiler/src/shared/estree.ts | 12 + 129 files changed, 2640 insertions(+), 3275 deletions(-) create mode 100644 packages/@lwc/template-compiler/src/codegen/optimize.ts diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_compat_config_simple_app.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_compat_config_simple_app.js index 78f1ba6bf9..82dd66069f 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_compat_config_simple_app.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_compat_config_simple_app.js @@ -75,13 +75,15 @@ var _implicitStylesheets = [stylesheet]; + var stc0$1 = { + key: 0 + }; + function tmpl$1($api, $cmp, $slotset, $ctx) { var api_dynamic_text = $api._ES5ProxyType ? $api.get("d") : $api.d, api_text = $api._ES5ProxyType ? $api.get("t") : $api.t, api_element = $api._ES5ProxyType ? $api.get("h") : $api.h; - return [api_element("div", { - key: 0 - }, [api_text(api_dynamic_text($cmp._ES5ProxyType ? $cmp.get("x") : $cmp.x))])]; + return [api_element("div", stc0$1, [api_text(api_dynamic_text($cmp._ES5ProxyType ? $cmp.get("x") : $cmp.x))])]; } var _tmpl$1 = lwc.registerTemplate(tmpl$1); @@ -134,20 +136,24 @@ tmpl: _tmpl$1 }); + var stc0 = { + classMap: { + "container": true + }, + key: 0 + }; + var stc1 = { + props: { + "x": "1" + }, + key: 1 + }; + var stc2 = []; + function tmpl($api, $cmp, $slotset, $ctx) { var api_custom_element = $api._ES5ProxyType ? $api.get("c") : $api.c, api_element = $api._ES5ProxyType ? $api.get("h") : $api.h; - return [api_element("div", { - classMap: { - "container": true - }, - key: 0 - }, [api_custom_element("x-foo", _xFoo, { - props: { - "x": "1" - }, - key: 1 - }, [])])]; + return [api_element("div", stc0, [api_custom_element("x-foo", _xFoo, stc1, stc2)])]; } var _tmpl = lwc.registerTemplate(tmpl); diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app.js index 512addc1e7..1b84ddead7 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app.js @@ -7,11 +7,12 @@ } var _implicitStylesheets = [stylesheet]; + const stc0$1 = { + key: 0 + }; function tmpl$1($api, $cmp, $slotset, $ctx) { const {d: api_dynamic_text, t: api_text, h: api_element} = $api; - return [api_element("div", { - key: 0 - }, [api_text(api_dynamic_text($cmp.x))])]; + return [api_element("div", stc0$1, [api_text(api_dynamic_text($cmp.x))])]; } var _tmpl$1 = lwc.registerTemplate(tmpl$1); tmpl$1.stylesheets = []; @@ -42,19 +43,22 @@ tmpl: _tmpl$1 }); + const stc0 = { + classMap: { + "container": true + }, + key: 0 + }; + const stc1 = { + props: { + "x": "1" + }, + key: 1 + }; + const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {c: api_custom_element, h: api_element} = $api; - return [api_element("div", { - classMap: { - "container": true - }, - key: 0 - }, [api_custom_element("x-foo", _xFoo, { - props: { - "x": "1" - }, - key: 1 - }, [])])]; + return [api_element("div", stc0, [api_custom_element("x-foo", _xFoo, stc1, stc2)])]; } var _tmpl = lwc.registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_css_resolver.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_css_resolver.js index 54aab5e580..3eb529a9f8 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_css_resolver.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_css_resolver.js @@ -11,11 +11,12 @@ } var _implicitStylesheets = [stylesheet]; + const stc0$1 = { + key: 0 + }; function tmpl$1($api, $cmp, $slotset, $ctx) { const {d: api_dynamic_text, t: api_text, h: api_element} = $api; - return [api_element("div", { - key: 0 - }, [api_text(api_dynamic_text($cmp.x))])]; + return [api_element("div", stc0$1, [api_text(api_dynamic_text($cmp.x))])]; } var _tmpl$1 = lwc.registerTemplate(tmpl$1); tmpl$1.stylesheets = []; @@ -46,19 +47,22 @@ tmpl: _tmpl$1 }); + const stc0 = { + classMap: { + "container": true + }, + key: 0 + }; + const stc1 = { + props: { + "x": "1" + }, + key: 1 + }; + const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {c: api_custom_element, h: api_element} = $api; - return [api_element("div", { - classMap: { - "container": true - }, - key: 0 - }, [api_custom_element("x-foo", _xFoo, { - props: { - "x": "1" - }, - key: 1 - }, [])])]; + return [api_element("div", stc0, [api_custom_element("x-foo", _xFoo, stc1, stc2)])]; } var _tmpl = lwc.registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_relative.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_relative.js index 512addc1e7..1b84ddead7 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_relative.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_relative.js @@ -7,11 +7,12 @@ } var _implicitStylesheets = [stylesheet]; + const stc0$1 = { + key: 0 + }; function tmpl$1($api, $cmp, $slotset, $ctx) { const {d: api_dynamic_text, t: api_text, h: api_element} = $api; - return [api_element("div", { - key: 0 - }, [api_text(api_dynamic_text($cmp.x))])]; + return [api_element("div", stc0$1, [api_text(api_dynamic_text($cmp.x))])]; } var _tmpl$1 = lwc.registerTemplate(tmpl$1); tmpl$1.stylesheets = []; @@ -42,19 +43,22 @@ tmpl: _tmpl$1 }); + const stc0 = { + classMap: { + "container": true + }, + key: 0 + }; + const stc1 = { + props: { + "x": "1" + }, + key: 1 + }; + const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {c: api_custom_element, h: api_element} = $api; - return [api_element("div", { - classMap: { - "container": true - }, - key: 0 - }, [api_custom_element("x-foo", _xFoo, { - props: { - "x": "1" - }, - key: 1 - }, [])])]; + return [api_element("div", stc0, [api_custom_element("x-foo", _xFoo, stc1, stc2)])]; } var _tmpl = lwc.registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_third_party.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_third_party.js index dd50e0f757..6a0a5d9d14 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_third_party.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_third_party.js @@ -1,11 +1,12 @@ (function (lwc) { 'use strict'; + const stc0 = { + key: 0 + }; function tmpl($api, $cmp, $slotset, $ctx) { const {d: api_dynamic_text, t: api_text, h: api_element} = $api; - return [api_element("pre", { - key: 0 - }, [api_text(api_dynamic_text($cmp.hello))])]; + return [api_element("pre", stc0, [api_text(api_dynamic_text($cmp.hello))])]; } var _tmpl = lwc.registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_with_scoped_styles.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_with_scoped_styles.js index 4c8f9686b7..37a0354dd3 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_with_scoped_styles.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_simple_app_with_scoped_styles.js @@ -8,11 +8,13 @@ stylesheet.$scoped$ = true; var _implicitScopedStylesheets = [stylesheet]; + const stc0 = { + key: 0 + }; + const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {h: api_element} = $api; - return [api_element("div", { - key: 0 - }, [])]; + return [api_element("div", stc0, stc1)]; } var _tmpl = lwc.registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_ts_simple_app.js b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_ts_simple_app.js index c0524c276f..b3ce2a1704 100644 --- a/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_ts_simple_app.js +++ b/packages/@lwc/rollup-plugin/src/__tests__/fixtures/expected_default_config_ts_simple_app.js @@ -7,11 +7,12 @@ } var _implicitStylesheets = [stylesheet]; + const stc0$1 = { + key: 0 + }; function tmpl$1($api, $cmp, $slotset, $ctx) { const {d: api_dynamic_text, t: api_text, h: api_element} = $api; - return [api_element("div", { - key: 0 - }, [api_text(api_dynamic_text($cmp.x))])]; + return [api_element("div", stc0$1, [api_text(api_dynamic_text($cmp.x))])]; } var _tmpl$1 = lwc.registerTemplate(tmpl$1); tmpl$1.stylesheets = []; @@ -42,19 +43,22 @@ tmpl: _tmpl$1 }); + const stc0 = { + classMap: { + "container": true + }, + key: 0 + }; + const stc1 = { + props: { + "x": "1" + }, + key: 1 + }; + const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {c: api_custom_element, h: api_element} = $api; - return [api_element("div", { - classMap: { - "container": true - }, - key: 0 - }, [api_custom_element("ts-foo", _tsFoo, { - props: { - "x": "1" - }, - key: 1 - }, [])])]; + return [api_element("div", stc0, [api_custom_element("ts-foo", _tsFoo, stc1, stc2)])]; } var _tmpl = lwc.registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-allow/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-allow/expected.js index 4932de5532..fba04483dd 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-allow/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-allow/expected.js @@ -1,18 +1,14 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + allow: "geolocation https://google-developers.appspot.com", + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "iframe", - { - attrs: { - allow: "geolocation https://google-developers.appspot.com", - }, - key: 0, - }, - [] - ), - ]; + return [api_element("iframe", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-crossorigin/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-crossorigin/expected.js index 4bc8e2f3ed..829d619732 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-crossorigin/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-crossorigin/expected.js @@ -1,40 +1,32 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + src: "http://www.example.com/image.png", + crossorigin: "anonymous", + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + attrs: { + src: "http://www.example.com/video.mp4", + crossorigin: "anonymous", + }, + key: 1, +}; +const stc3 = { + attrs: { + src: "http://www.example.com/video.mp3", + crossorigin: "anonymous", + }, + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "img", - { - attrs: { - src: "http://www.example.com/image.png", - crossorigin: "anonymous", - }, - key: 0, - }, - [] - ), - api_element( - "video", - { - attrs: { - src: "http://www.example.com/video.mp4", - crossorigin: "anonymous", - }, - key: 1, - }, - [] - ), - api_element( - "audio", - { - attrs: { - src: "http://www.example.com/video.mp3", - crossorigin: "anonymous", - }, - key: 2, - }, - [] - ), + api_element("img", stc0, stc1), + api_element("video", stc2, stc1), + api_element("audio", stc3, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id-expression/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id-expression/expected.js index 61112f34e9..d877f31bf5 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id-expression/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id-expression/expected.js @@ -1,4 +1,8 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { fid: api_scoped_frag_id, @@ -17,34 +21,28 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, [api_text("KIX")] ), - api_element( - "map", - { - key: 1, - }, - [ - api_element( - "area", - { - attrs: { - href: api_scoped_frag_id("#haneda"), - }, - key: 2, + api_element("map", stc0, [ + api_element( + "area", + { + attrs: { + href: api_scoped_frag_id("#haneda"), }, - [] - ), - api_element( - "area", - { - attrs: { - href: api_scoped_frag_id("#chubu"), - }, - key: 3, + key: 2, + }, + stc1 + ), + api_element( + "area", + { + attrs: { + href: api_scoped_frag_id("#chubu"), }, - [] - ), - ] - ), + key: 3, + }, + stc1 + ), + ]), api_element( "h1", { diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id/expected.js index f1bac5afbf..c31f38e19a 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href-with-id/expected.js @@ -1,4 +1,8 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { fid: api_scoped_frag_id, @@ -17,34 +21,28 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, [api_text("KIX")] ), - api_element( - "map", - { - key: 1, - }, - [ - api_element( - "area", - { - attrs: { - href: api_scoped_frag_id("#eneos-gas"), - }, - key: 2, + api_element("map", stc0, [ + api_element( + "area", + { + attrs: { + href: api_scoped_frag_id("#eneos-gas"), }, - [] - ), - api_element( - "area", - { - attrs: { - href: api_scoped_frag_id("#kawaramachi"), - }, - key: 3, + key: 2, + }, + stc1 + ), + api_element( + "area", + { + attrs: { + href: api_scoped_frag_id("#kawaramachi"), }, - [] - ), - ] - ), + key: 3, + }, + stc1 + ), + ]), api_element( "h1", { diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href/expected.js index 28ce366510..88856761fd 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-href/expected.js @@ -1,45 +1,34 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + href: "#yasaka-taxi", + }, + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + attrs: { + href: "#eneos-gas", + }, + key: 2, +}; +const stc3 = []; +const stc4 = { + attrs: { + href: "#kawaramachi", + }, + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "a", - { - attrs: { - href: "#yasaka-taxi", - }, - key: 0, - }, - [api_text("Yasaka Taxi")] - ), - api_element( - "map", - { - key: 1, - }, - [ - api_element( - "area", - { - attrs: { - href: "#eneos-gas", - }, - key: 2, - }, - [] - ), - api_element( - "area", - { - attrs: { - href: "#kawaramachi", - }, - key: 3, - }, - [] - ), - ] - ), + api_element("a", stc0, [api_text("Yasaka Taxi")]), + api_element("map", stc1, [ + api_element("area", stc2, stc3), + api_element("area", stc4, stc3), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-uppercase/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-uppercase/expected.js index b52f7ce789..9387cc7b5f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-uppercase/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/attribute-uppercase/expected.js @@ -1,26 +1,21 @@ import _xButton from "x/button"; import { registerTemplate } from "lwc"; +const stc0 = { + props: { + Class: "r", + DataXx: "foo", + AriaHidden: "hidden", + Role: "xx", + FooBar: "x", + FooZaz: "z", + Foo_bar_baz: "baz", + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; - return [ - api_custom_element( - "x-button", - _xButton, - { - props: { - Class: "r", - DataXx: "foo", - AriaHidden: "hidden", - Role: "xx", - FooBar: "x", - FooZaz: "z", - Foo_bar_baz: "baz", - }, - key: 0, - }, - [] - ), - ]; + return [api_custom_element("x-button", _xButton, stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/hidden-global-attr/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/hidden-global-attr/expected.js index ac0385e219..ab58ffc1f5 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/hidden-global-attr/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/hidden-global-attr/expected.js @@ -1,38 +1,59 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + hidden: "", + }, + key: 0, +}; +const stc1 = { + attrs: { + hidden: "", + }, + key: 1, +}; +const stc2 = { + attrs: { + hidden: "other than true", + }, + key: 2, +}; +const stc3 = { + attrs: { + hidden: "3", + }, + key: 4, +}; +const stc4 = { + props: { + hidden: true, + }, + key: 5, +}; +const stc5 = { + props: { + hidden: true, + }, + key: 6, +}; +const stc6 = { + props: { + hidden: true, + }, + key: 7, +}; +const stc7 = { + props: { + hidden: true, + }, + key: 9, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, c: api_custom_element } = $api; return [ - api_element( - "p", - { - attrs: { - hidden: "", - }, - key: 0, - }, - [api_text("boolean present")] - ), - api_element( - "p", - { - attrs: { - hidden: "", - }, - key: 1, - }, - [api_text("empty string, should be true")] - ), - api_element( - "p", - { - attrs: { - hidden: "other than true", - }, - key: 2, - }, - [api_text("string value, should be true")] - ), + api_element("p", stc0, [api_text("boolean present")]), + api_element("p", stc1, [api_text("empty string, should be true")]), + api_element("p", stc2, [api_text("string value, should be true")]), api_element( "p", { @@ -43,49 +64,14 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, [api_text("computed value, should be resolved in component")] ), - api_element( - "p", - { - attrs: { - hidden: "3", - }, - key: 4, - }, - [api_text("integer value, should be true")] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - hidden: true, - }, - key: 5, - }, - [api_text("boolean present")] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - hidden: true, - }, - key: 6, - }, - [api_text("empty string, should be true")] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - hidden: true, - }, - key: 7, - }, - [api_text("string value, should be true")] - ), + api_element("p", stc3, [api_text("integer value, should be true")]), + api_custom_element("x-foo", _xFoo, stc4, [api_text("boolean present")]), + api_custom_element("x-foo", _xFoo, stc5, [ + api_text("empty string, should be true"), + ]), + api_custom_element("x-foo", _xFoo, stc6, [ + api_text("string value, should be true"), + ]), api_custom_element( "x-foo", _xFoo, @@ -97,17 +83,9 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, [api_text("computed value, should be resolved in component")] ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - hidden: true, - }, - key: 9, - }, - [api_text("integer value, should be true")] - ), + api_custom_element("x-foo", _xFoo, stc7, [ + api_text("integer value, should be true"), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/required/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/required/expected.js index 092708b2fa..d3e050d953 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/required/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attribute/required/expected.js @@ -1,106 +1,90 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + required: "", + }, + props: { + value: "boolean present", + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + attrs: { + required: "", + }, + props: { + value: "empty string", + }, + key: 1, +}; +const stc3 = { + attrs: { + required: "other than true", + }, + props: { + value: "string value", + }, + key: 2, +}; +const stc4 = { + value: "computed value", +}; +const stc5 = { + attrs: { + required: "3", + }, + props: { + value: "integer value", + }, + key: 4, +}; +const stc6 = { + props: { + required: true, + }, + key: 5, +}; +const stc7 = { + props: { + required: "", + }, + key: 6, +}; +const stc8 = { + props: { + required: "other than true", + }, + key: 7, +}; +const stc9 = { + props: { + required: "3", + }, + key: 9, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element, t: api_text, c: api_custom_element } = $api; return [ - api_element( - "input", - { - attrs: { - required: "", - }, - props: { - value: "boolean present", - }, - key: 0, - }, - [] - ), - api_element( - "input", - { - attrs: { - required: "", - }, - props: { - value: "empty string", - }, - key: 1, - }, - [] - ), - api_element( - "input", - { - attrs: { - required: "other than true", - }, - props: { - value: "string value", - }, - key: 2, - }, - [] - ), + api_element("input", stc0, stc1), + api_element("input", stc2, stc1), + api_element("input", stc3, stc1), api_element( "input", { attrs: { required: $cmp.computed ? "" : null, }, - props: { - value: "computed value", - }, + props: stc4, key: 3, }, - [] - ), - api_element( - "input", - { - attrs: { - required: "3", - }, - props: { - value: "integer value", - }, - key: 4, - }, - [] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - required: true, - }, - key: 5, - }, - [api_text("boolean present")] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - required: "", - }, - key: 6, - }, - [api_text("empty string")] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - required: "other than true", - }, - key: 7, - }, - [api_text("string value")] + stc1 ), + api_element("input", stc5, stc1), + api_custom_element("x-foo", _xFoo, stc6, [api_text("boolean present")]), + api_custom_element("x-foo", _xFoo, stc7, [api_text("empty string")]), + api_custom_element("x-foo", _xFoo, stc8, [api_text("string value")]), api_custom_element( "x-foo", _xFoo, @@ -112,17 +96,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, [api_text("computed value, should be resolved in component")] ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - required: "3", - }, - key: 9, - }, - [api_text("integer value")] - ), + api_custom_element("x-foo", _xFoo, stc9, [api_text("integer value")]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attributes-valid/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attributes-valid/expected.js index 7c2a83aafc..c4d74b3031 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attributes-valid/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean-attributes-valid/expected.js @@ -1,43 +1,37 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + hidden: "", + }, + key: 0, +}; +const stc1 = { + props: { + autofocus: "true", + autoplay: "true", + capture: "true", + checked: "true", + disabled: "true", + formnovalidate: "true", + loop: "true", + multiple: "true", + muted: "true", + noValidate: "true", + open: "true", + readOnly: "true", + required: "true", + reversed: "true", + selected: "true", + }, + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, c: api_custom_element } = $api; return [ - api_element( - "p", - { - attrs: { - hidden: "", - }, - key: 0, - }, - [api_text("x")] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - autofocus: "true", - autoplay: "true", - capture: "true", - checked: "true", - disabled: "true", - formnovalidate: "true", - loop: "true", - multiple: "true", - muted: "true", - noValidate: "true", - open: "true", - readOnly: "true", - required: "true", - reversed: "true", - selected: "true", - }, - key: 1, - }, - [] - ), + api_element("p", stc0, [api_text("x")]), + api_custom_element("x-foo", _xFoo, stc1, stc2), api_element( "input", { @@ -48,7 +42,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 2, }, - [] + stc2 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean/expected.js index 259e51226a..62729d7f72 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/boolean/expected.js @@ -1,17 +1,15 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + hidden: "", + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "p", - { - attrs: { - hidden: "", - }, - key: 0, - }, - [api_text("x")] - ), + api_element("p", stc0, [api_text("x")]), api_element( "input", { @@ -22,7 +20,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 1, }, - [] + stc1 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/class/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/class/expected.js index 3baa14161e..c52dc25906 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/class/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/class/expected.js @@ -1,50 +1,39 @@ import { registerTemplate } from "lwc"; +const stc0 = { + classMap: { + foo: true, + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + classMap: { + foo: true, + bar: true, + }, + key: 1, +}; +const stc3 = { + classMap: { + foo: true, + bar: true, + }, + key: 2, +}; +const stc4 = { + classMap: { + foo: true, + bar: true, + }, + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "div", - { - classMap: { - foo: true, - }, - key: 0, - }, - [] - ), - api_element( - "div", - { - classMap: { - foo: true, - bar: true, - }, - key: 1, - }, - [] - ), - api_element( - "div", - { - classMap: { - foo: true, - bar: true, - }, - key: 2, - }, - [] - ), - api_element( - "div", - { - classMap: { - foo: true, - bar: true, - }, - key: 3, - }, - [] - ), + api_element("div", stc0, stc1), + api_element("div", stc2, stc1), + api_element("div", stc3, stc1), + api_element("div", stc4, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset-complex/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset-complex/expected.js index 10896010f8..85c4ad7adb 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset-complex/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset-complex/expected.js @@ -1,26 +1,17 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + "data--bar-baz": "xyz", + }, + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - attrs: { - "data--bar-baz": "xyz", - }, - key: 1, - }, - [] - ), - ] - ), - ]; + return [api_element("section", stc0, [api_element("p", stc1, stc2)])]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset/expected.js index 3cb93af7eb..bc46bc5df5 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/dataset/expected.js @@ -1,27 +1,18 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + "data-foo": "1", + "data-bar-baz": "xyz", + }, + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - attrs: { - "data-foo": "1", - "data-bar-baz": "xyz", - }, - key: 1, - }, - [] - ), - ] - ), - ]; + return [api_element("section", stc0, [api_element("p", stc1, stc2)])]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/error-empty-value/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/error-empty-value/expected.js index 0bf08aee15..e9aca2c30f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/error-empty-value/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/error-empty-value/expected.js @@ -1,30 +1,24 @@ import _fooBar from "foo/bar"; import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + title: "", + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + props: { + content: "", + visible: true, + }, + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element, c: api_custom_element } = $api; return [ - api_element( - "p", - { - attrs: { - title: "", - }, - key: 0, - }, - [] - ), - api_custom_element( - "foo-bar", - _fooBar, - { - props: { - content: "", - visible: true, - }, - key: 1, - }, - [] - ), + api_element("p", stc0, stc1), + api_custom_element("foo-bar", _fooBar, stc2, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-input/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-input/expected.js index fdb28f3ade..a3d5b38525 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-input/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-input/expected.js @@ -1,25 +1,21 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + type: "checkbox", + required: "", + readonly: "", + minlength: "5", + maxlength: "10", + }, + props: { + checked: true, + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "input", - { - attrs: { - type: "checkbox", - required: "", - readonly: "", - minlength: "5", - maxlength: "10", - }, - props: { - checked: true, - }, - key: 0, - }, - [] - ), - ]; + return [api_element("input", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag-invalid/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag-invalid/expected.js index 215ea3cf14..123d3dfbc6 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag-invalid/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag-invalid/expected.js @@ -1,27 +1,21 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + minlength: "1", + maxlength: "5", + "unknown-attr": "should-error", + }, + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "textarea", - { - attrs: { - minlength: "1", - maxlength: "5", - "unknown-attr": "should-error", - }, - key: 1, - }, - [api_text("x")] - ), - ] - ), + api_element("section", stc0, [ + api_element("textarea", stc1, [api_text("x")]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag/expected.js index 15a4dd2994..b46ba9f33c 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/html-tag/expected.js @@ -1,26 +1,18 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + title: "x", + "aria-hidden": "x", + }, + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - attrs: { - title: "x", - "aria-hidden": "x", - }, - key: 1, - }, - [api_text("x")] - ), - ] - ), + api_element("section", stc0, [api_element("p", stc1, [api_text("x")])]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/id/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/id/expected.js index 333864fca0..1b8404e3b0 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/id/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/id/expected.js @@ -2,6 +2,7 @@ import _xSubject from "x/subject"; import _xDescription from "x/description"; import _xTextarea from "x/textarea"; import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { gid: api_scoped_id, @@ -22,7 +23,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 0, }, - [] + stc0 ), api_custom_element( "x-description", @@ -33,7 +34,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 1, }, - [] + stc0 ), api_custom_element( "x-description", @@ -44,7 +45,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 2, }, - [] + stc0 ), api_custom_element( "x-textarea", @@ -56,7 +57,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 3, }, - [] + stc0 ), api_element( "label", @@ -76,7 +77,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 5, }, - [] + stc0 ), api_iterator($cmp.things, function (thing) { return [ @@ -98,7 +99,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: api_key(7, thing.key), }, - [] + stc0 ), ]; }), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/mixed-props-attrs/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/mixed-props-attrs/expected.js index a14d92f425..803e0a793e 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/mixed-props-attrs/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/mixed-props-attrs/expected.js @@ -1,6 +1,46 @@ import _nsFoo from "ns/foo"; import _nsBar from "ns/bar"; import { registerTemplate, sanitizeAttribute } from "lwc"; +const stc0 = []; +const stc1 = { + classMap: { + test: true, + }, + attrs: { + "data-foo": "datafoo", + "aria-hidden": "h", + role: "presentation", + href: "/foo", + title: "test", + tabindex: "-1", + }, + key: 1, +}; +const stc2 = { + r: true, +}; +const stc3 = { + "data-xx": "foo", +}; +const stc4 = { + classMap: { + cubano: true, + }, + attrs: { + focusable: "true", + }, + key: 3, + svg: true, +}; +const stc5 = { + attrs: { + bgcolor: "x", + }, + key: 5, +}; +const stc6 = { + "aria-hidden": "hidden", +}; function tmpl($api, $cmp, $slotset, $ctx) { const { gid: api_scoped_id, c: api_custom_element, h: api_element } = $api; return [ @@ -14,36 +54,15 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 0, }, - [] - ), - api_element( - "a", - { - classMap: { - test: true, - }, - attrs: { - "data-foo": "datafoo", - "aria-hidden": "h", - role: "presentation", - href: "/foo", - title: "test", - tabindex: "-1", - }, - key: 1, - }, - [] + stc0 ), + api_element("a", stc1, stc0), api_custom_element( "ns-bar", _nsBar, { - classMap: { - r: true, - }, - attrs: { - "data-xx": "foo", - }, + classMap: stc2, + attrs: stc3, props: { ariaDescribedBy: api_scoped_id("ns-foo"), ariaHidden: "hidden", @@ -55,59 +74,35 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 2, }, - [] + stc0 ), - api_element( - "svg", - { - classMap: { - cubano: true, - }, - attrs: { - focusable: "true", - }, - key: 3, - svg: true, - }, - [ - api_element( - "use", - { - attrs: { - "xlink:href": sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "xlink:href", - "xx" - ), - }, - key: 4, - svg: true, + api_element("svg", stc4, [ + api_element( + "use", + { + attrs: { + "xlink:href": sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "xlink:href", + "xx" + ), }, - [] - ), - ] - ), - api_element( - "table", - { - attrs: { - bgcolor: "x", + key: 4, + svg: true, }, - key: 5, - }, - [] - ), + stc0 + ), + ]), + api_element("table", stc5, stc0), api_element( "div", { className: $cmp.foo, - attrs: { - "aria-hidden": "hidden", - }, + attrs: stc6, key: 6, }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/false-value/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/false-value/expected.js index 663282da37..bdbdbe8674 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/false-value/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/false-value/expected.js @@ -1,41 +1,30 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + props: { + spellcheck: false, + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + props: { + spellcheck: false, + }, + key: 1, +}; +const stc3 = { + props: { + spellcheck: false, + }, + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; return [ - api_custom_element( - "x-foo", - _xFoo, - { - props: { - spellcheck: false, - }, - key: 0, - }, - [] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - spellcheck: false, - }, - key: 1, - }, - [] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - spellcheck: false, - }, - key: 2, - }, - [] - ), + api_custom_element("x-foo", _xFoo, stc0, stc1), + api_custom_element("x-foo", _xFoo, stc2, stc1), + api_custom_element("x-foo", _xFoo, stc3, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/truthy-value/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/truthy-value/expected.js index 714494b2a8..600a1e36bb 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/truthy-value/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/spellcheck/static/truthy-value/expected.js @@ -1,41 +1,30 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + props: { + spellcheck: true, + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + props: { + spellcheck: true, + }, + key: 1, +}; +const stc3 = { + props: { + spellcheck: true, + }, + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; return [ - api_custom_element( - "x-foo", - _xFoo, - { - props: { - spellcheck: true, - }, - key: 0, - }, - [] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - spellcheck: true, - }, - key: 1, - }, - [] - ), - api_custom_element( - "x-foo", - _xFoo, - { - props: { - spellcheck: true, - }, - key: 2, - }, - [] - ), + api_custom_element("x-foo", _xFoo, stc0, stc1), + api_custom_element("x-foo", _xFoo, stc2, stc1), + api_custom_element("x-foo", _xFoo, stc3, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js index b4096c8731..8586ec1fef 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ @@ -8,7 +9,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { styleDecls: [["color", "blue", false]], key: 0, }, - [] + stc0 ), api_element( "div", @@ -16,7 +17,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { styleDecls: [["color", "blue", false]], key: 1, }, - [] + stc0 ), api_element( "div", @@ -24,7 +25,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { styleDecls: [["color", "blue", false]], key: 2, }, - [] + stc0 ), api_element( "div", @@ -32,7 +33,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { styleDecls: [["box-shadow", "10px 5px 5px black", false]], key: 3, }, - [] + stc0 ), api_element( "div", @@ -44,7 +45,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ], key: 4, }, - [] + stc0 ), api_element( "div", @@ -56,7 +57,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ], key: 5, }, - [] + stc0 ), api_element( "div", @@ -64,7 +65,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { styleDecls: [["background-color", "rgba(255,0,0,0.3)", false]], key: 6, }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/tabindex-computed/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/tabindex-computed/expected.js index 020589f9c0..190291324e 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/tabindex-computed/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/tabindex-computed/expected.js @@ -1,5 +1,6 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { ti: api_tab_index, @@ -27,7 +28,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { }, key: 1, }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/unknown-html-tag-known-attribute/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/unknown-html-tag-known-attribute/expected.js index b517e8c010..07692efff7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/unknown-html-tag-known-attribute/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/unknown-html-tag-known-attribute/expected.js @@ -1,18 +1,14 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + min: "4", + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "somefancytag", - { - attrs: { - min: "4", - }, - key: 0, - }, - [] - ), - ]; + return [api_element("somefancytag", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/class/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/class/expected.js index 670f6287c3..293f72c660 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/class/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/class/expected.js @@ -1,20 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + classMap: { + foo: true, + bar: true, + "baz-fiz": true, + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "section", - { - classMap: { - foo: true, - bar: true, - "baz-fiz": true, - }, - key: 0, - }, - [] - ), - ]; + return [api_element("section", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-expression/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-expression/expected.js index 1dd34ab7de..dd241a7b38 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-expression/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-expression/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ @@ -8,7 +9,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { style: $cmp.customStyle, key: 0, }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js index 7a75c2e696..dbd415fa45 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ @@ -12,7 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ], key: 0, }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js index d89a3d0484..b440d169db 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ @@ -12,7 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ], key: 0, }, - [] + stc0 ), api_element( "section", @@ -23,7 +24,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ], key: 1, }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg-with-iteration/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg-with-iteration/expected.js index 917da9f02e..6acd201fcf 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg-with-iteration/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg-with-iteration/expected.js @@ -1,13 +1,15 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, + svg: true, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, h: api_element, i: api_iterator } = $api; return [ api_element( "svg", - { - key: 0, - svg: true, - }, + stc0, api_iterator($cmp.lines, function (line) { return api_element( "line", @@ -21,7 +23,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { key: api_key(1, line.key), svg: true, }, - [] + stc1 ); }) ), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg/expected.js index 272f3fa847..5bb9b8227d 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/svg/expected.js @@ -1,39 +1,37 @@ import { registerTemplate, sanitizeAttribute } from "lwc"; +const stc0 = { + classMap: { + "slds-button__icon": true, + }, + attrs: { + viewBox: "0 0 5 5", + "aria-hidden": "true", + }, + key: 0, + svg: true, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "svg", - { - classMap: { - "slds-button__icon": true, - }, - attrs: { - viewBox: "0 0 5 5", - "aria-hidden": "true", - }, - key: 0, - svg: true, - }, - [ - api_element( - "use", - { - attrs: { - "xlink:href": sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "xlink:href", - "/x" - ), - }, - key: 1, - svg: true, + api_element("svg", stc0, [ + api_element( + "use", + { + attrs: { + "xlink:href": sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "xlink:href", + "/x" + ), }, - [] - ), - ] - ), + key: 1, + svg: true, + }, + stc1 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/template/expected.js index 5baa396d25..4c58fe1239 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/template/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/template/expected.js @@ -1,15 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; - return [ - api_element( - "p", - { - key: 0, - }, - [api_text("Root")] - ), - ]; + return [api_element("p", stc0, [api_text("Root")])]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/basic/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/basic/expected.js index ad9d1cc046..06a0a3f5b7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/basic/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/basic/expected.js @@ -1,15 +1,12 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { co: api_comment, t: api_text, h: api_element } = $api; return [ api_comment(" This is an HTML comment "), - api_element( - "button", - { - key: 0, - }, - [api_text("click me")] - ), + api_element("button", stc0, [api_text("click me")]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-for-each/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-for-each/expected.js index bf641bea79..ff8862c86b 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-for-each/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-for-each/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { co: api_comment, @@ -11,9 +14,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "ul", - { - key: 0, - }, + stc0, api_iterator($cmp.colors, function (color) { return [ api_comment(" color "), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-if/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-if/expected.js index c68d6ae61e..d77126253a 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-if/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/directive-if/expected.js @@ -1,26 +1,18 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { co: api_comment, t: api_text, h: api_element } = $api; return [ $cmp.truthyValue ? api_comment(" HTML comment inside if:true ") : null, - $cmp.truthyValue - ? api_element( - "p", - { - key: 0, - }, - [api_text("true branch")] - ) - : null, + $cmp.truthyValue ? api_element("p", stc0, [api_text("true branch")]) : null, !$cmp.truthyValue ? api_comment(" HTML comment inside if:false ") : null, !$cmp.truthyValue - ? api_element( - "p", - { - key: 1, - }, - [api_text("false branch")] - ) + ? api_element("p", stc1, [api_text("false branch")]) : null, ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/preserve-html-comments-option/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/preserve-html-comments-option/expected.js index ad9d1cc046..06a0a3f5b7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/preserve-html-comments-option/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/preserve-html-comments-option/expected.js @@ -1,15 +1,12 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { co: api_comment, t: api_text, h: api_element } = $api; return [ api_comment(" This is an HTML comment "), - api_element( - "button", - { - key: 0, - }, - [api_text("click me")] - ), + api_element("button", stc0, [api_text("click me")]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/slots/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/slots/expected.js index 93b4b6ab9e..ee766585e8 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/slots/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/comments/slots/expected.js @@ -1,5 +1,11 @@ import _xChild from "x/child"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { co: api_comment, @@ -8,23 +14,10 @@ function tmpl($api, $cmp, $slotset, $ctx) { c: api_custom_element, } = $api; return [ - api_custom_element( - "x-child", - _xChild, - { - key: 0, - }, - [ - api_comment(" HTML comment inside slot "), - api_element( - "p", - { - key: 1, - }, - [api_text("slot content")] - ), - ] - ), + api_custom_element("x-child", _xChild, stc0, [ + api_comment(" HTML comment inside slot "), + api_element("p", stc1, [api_text("slot content")]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/flatten-child/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/flatten-child/expected.js index f01e90801b..6b894ddd06 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/flatten-child/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/flatten-child/expected.js @@ -1,4 +1,11 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, @@ -7,21 +14,8 @@ function tmpl($api, $cmp, $slotset, $ctx) { f: api_flatten, } = $api; return api_flatten([ - api_element( - "div", - { - key: 0, - }, - [api_text("sibling")] - ), - api_dynamic_component( - "x-foo", - $cmp.trackedProp.foo, - { - key: 1, - }, - [] - ), + api_element("div", stc0, [api_text("sibling")]), + api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc1, stc2), ]); } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/only-child/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/only-child/expected.js index 54c41016f9..c7aef74f9f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/only-child/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-dynamic/only-child/expected.js @@ -1,15 +1,12 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { dc: api_dynamic_component, f: api_flatten } = $api; return api_flatten([ - api_dynamic_component( - "x-foo", - $cmp.trackedProp.foo, - { - key: 0, - }, - [] - ), + api_dynamic_component("x-foo", $cmp.trackedProp.foo, stc0, stc1), ]); } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/children/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/children/expected.js index da151ef720..20696d0a81 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/children/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/children/expected.js @@ -1,4 +1,41 @@ import { registerTemplate } from "lwc"; +const stc0 = { + classMap: { + s1: true, + }, + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + classMap: { + s2: true, + }, + key: 2, +}; +const stc3 = []; +const stc4 = { + classMap: { + s3: true, + }, + key: 5, +}; +const stc5 = { + key: 6, +}; +const stc6 = { + classMap: { + s4: true, + }, + key: 8, +}; +const stc7 = { + key: 9, +}; +const stc8 = { + key: 10, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, @@ -10,34 +47,18 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - classMap: { - s1: true, - }, - key: 0, - }, + stc0, api_flatten([ api_text("Other Child"), api_iterator($cmp.items, function (item) { return api_text("X"); }), - api_element( - "p", - { - key: 1, - }, - [api_text("Last child")] - ), + api_element("p", stc1, [api_text("Last child")]), ]) ), api_element( "section", - { - classMap: { - s2: true, - }, - key: 2, - }, + stc2, api_flatten([ api_text("Other Child"), $cmp.isTrue @@ -59,61 +80,29 @@ function tmpl($api, $cmp, $slotset, $ctx) { ), ]; }) - : [], + : stc3, ]) ), api_element( "section", - { - classMap: { - s3: true, - }, - key: 5, - }, + stc4, api_flatten([ - api_element( - "p", - { - key: 6, - }, - [api_text("Last child")] - ), + api_element("p", stc5, [api_text("Last child")]), api_iterator($cmp.items, function (item) { return api_element( "div", { key: api_key(7, item.id), }, - [] + stc3 ); }), ]) ), - api_element( - "section", - { - classMap: { - s4: true, - }, - key: 8, - }, - [ - api_element( - "p", - { - key: 9, - }, - [api_text("Other child1")] - ), - api_element( - "p", - { - key: 10, - }, - [api_text("Other child2")] - ), - ] - ), + api_element("section", stc6, [ + api_element("p", stc7, [api_text("Other child1")]), + api_element("p", stc8, [api_text("Other child2")]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/foreach-with-if/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/foreach-with-if/expected.js index dfef037cc3..f1085a4ad7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/foreach-with-if/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/foreach-with-if/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return $cmp.showItems ? api_element( diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-index/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-index/expected.js index 7ab5c7d664..e6c2651495 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-index/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-index/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "ul", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item, index) { return api_element( "li", diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-item/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-item/expected.js index 48ce4995aa..fd8cf12567 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-item/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-item/expected.js @@ -1,4 +1,13 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + "my-list": true, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,27 +19,15 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "div", { - classMap: { - "my-list": true, - }, + classMap: stc1, key: api_key(1, item.id), }, - [ - api_element( - "p", - { - key: 2, - }, - [api_text(api_dynamic_text(item))] - ), - ] + [api_element("p", stc2, [api_text(api_dynamic_text(item))])] ); }) ), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-outside-scope-reference/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-outside-scope-reference/expected.js index 7492470187..40ef06c475 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-outside-scope-reference/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-outside-scope-reference/expected.js @@ -1,4 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + "my-list": true, +}; +const stc2 = { + key: 2, +}; +const stc3 = { + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,33 +22,17 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "div", { - classMap: { - "my-list": true, - }, + classMap: stc1, key: api_key(1, item.id), }, [ - api_element( - "p", - { - key: 2, - }, - [api_text(api_dynamic_text(item))] - ), - api_element( - "p", - { - key: 3, - }, - [api_text(api_dynamic_text($cmp.item2))] - ), + api_element("p", stc2, [api_text(api_dynamic_text(item))]), + api_element("p", stc3, [api_text(api_dynamic_text($cmp.item2))]), ] ); }) diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-refence-item/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-refence-item/expected.js index c6060688fc..75cb2870ab 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-refence-item/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-refence-item/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "ul", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "li", diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-sibling/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-sibling/expected.js index 2e5d1481bd..6a01aad59c 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-sibling/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline-sibling/expected.js @@ -1,4 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -11,9 +17,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "ul", - { - key: 0, - }, + stc0, api_flatten([ api_iterator($cmp.items, function (item) { return api_element( @@ -25,13 +29,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { [api_text(api_dynamic_text(item))] ); }), - api_element( - "li", - { - key: 2, - }, - [api_text("Last")] - ), + api_element("li", stc1, [api_text("Last")]), ]) ), ]; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline/expected.js index e1a71a6584..197edf0ccd 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/inline/expected.js @@ -1,30 +1,27 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + "my-list": true, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, t: api_text, h: api_element, i: api_iterator } = $api; return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "div", { - classMap: { - "my-list": true, - }, + classMap: stc1, key: api_key(1, item.id), }, - [ - api_element( - "p", - { - key: 2, - }, - [api_text("items")] - ), - ] + [api_element("p", stc2, [api_text("items")])] ); }) ), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-multiple-children/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-multiple-children/expected.js index f215439aff..3754834ce9 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-multiple-children/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-multiple-children/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return [ api_element( diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-outside-scope-reference/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-outside-scope-reference/expected.js index 98a20bf40c..8685a0e940 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-outside-scope-reference/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-outside-scope-reference/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return [ api_element( diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-sibling/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-sibling/expected.js index a1c0e7dadc..8ce883c93b 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-sibling/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template-sibling/expected.js @@ -1,4 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -11,9 +17,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_flatten([ api_iterator($cmp.items, function (item) { return [ @@ -33,13 +37,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ), ]; }), - api_element( - "p", - { - key: 3, - }, - [api_text("3" + api_dynamic_text($cmp.item))] - ), + api_element("p", stc1, [api_text("3" + api_dynamic_text($cmp.item))]), ]) ), ]; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template/expected.js index 45ec7e5d99..651d356c86 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-for-each/template/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "p", diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-multiple/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-multiple/expected.js index 910e398e05..c3793e6410 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-multiple/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-multiple/expected.js @@ -1,42 +1,24 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; +const stc3 = { + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - $cmp.isTrue - ? api_element( - "p", - { - key: 1, - }, - [api_text("1")] - ) - : null, - $cmp.isTrue - ? api_element( - "p", - { - key: 2, - }, - [api_text("2")] - ) - : null, - $cmp.isTrue - ? api_element( - "p", - { - key: 3, - }, - [api_text("3")] - ) - : null, - ] - ), + api_element("section", stc0, [ + $cmp.isTrue ? api_element("p", stc1, [api_text("1")]) : null, + $cmp.isTrue ? api_element("p", stc2, [api_text("2")]) : null, + $cmp.isTrue ? api_element("p", stc3, [api_text("3")]) : null, + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-sibling-static/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-sibling-static/expected.js index 60c4fb25eb..ac2a3bf4a9 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-sibling-static/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/inline-sibling-static/expected.js @@ -1,34 +1,21 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, d: api_dynamic_text } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - $cmp.isTrue - ? api_element( - "p", - { - key: 1, - }, - [api_text("1")] - ) - : null, - api_text(api_dynamic_text($cmp.foo)), - $cmp.isTrue - ? api_element( - "p", - { - key: 2, - }, - [api_text("3")] - ) - : null, - ] - ), + api_element("section", stc0, [ + $cmp.isTrue ? api_element("p", stc1, [api_text("1")]) : null, + api_text(api_dynamic_text($cmp.foo)), + $cmp.isTrue ? api_element("p", stc2, [api_text("3")]) : null, + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/strict-true/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/strict-true/expected.js index 1a1fa09c40..20cfb45308 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/strict-true/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/strict-true/expected.js @@ -1,24 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - $cmp.isTrue === true - ? api_element( - "p", - { - key: 1, - }, - [api_text("1")] - ) - : null, - ] - ), + api_element("section", stc0, [ + $cmp.isTrue === true ? api_element("p", stc1, [api_text("1")]) : null, + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-expression/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-expression/expected.js index 3091813edc..42ee169774 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-expression/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-expression/expected.js @@ -1,20 +1,17 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { d: api_dynamic_text, t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - $cmp.state.isTrue - ? api_text( - api_dynamic_text($cmp.foo) + " " + api_dynamic_text($cmp.bar) - ) - : null, - ] - ), + api_element("section", stc0, [ + $cmp.state.isTrue + ? api_text( + api_dynamic_text($cmp.foo) + " " + api_dynamic_text($cmp.bar) + ) + : null, + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-if-else/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-if-else/expected.js index 64e28d561c..7d131f7cc1 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-if-else/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-if-else/expected.js @@ -1,25 +1,15 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - $cmp.isTrue - ? api_element( - "p", - { - key: 0, - }, - [api_text("1")] - ) - : null, - !$cmp.isTrue2 - ? api_element( - "p", - { - key: 1, - }, - [api_text("2")] - ) - : null, + $cmp.isTrue ? api_element("p", stc0, [api_text("1")]) : null, + !$cmp.isTrue2 ? api_element("p", stc1, [api_text("2")]) : null, ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-multiple/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-multiple/expected.js index c2268b9516..fcd98d3c6d 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-multiple/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-multiple/expected.js @@ -1,34 +1,19 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - $cmp.isTrue - ? api_element( - "p", - { - key: 0, - }, - [api_text("1")] - ) - : null, - $cmp.isTrue - ? api_element( - "p", - { - key: 1, - }, - [api_text("2")] - ) - : null, - $cmp.isTrue - ? api_element( - "p", - { - key: 2, - }, - [api_text("3")] - ) - : null, + $cmp.isTrue ? api_element("p", stc0, [api_text("1")]) : null, + $cmp.isTrue ? api_element("p", stc1, [api_text("2")]) : null, + $cmp.isTrue ? api_element("p", stc2, [api_text("3")]) : null, ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-sibiling/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-sibiling/expected.js index 5230139be6..fb96c1521f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-sibiling/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template-sibiling/expected.js @@ -1,38 +1,24 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; +const stc3 = { + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - key: 1, - }, - [api_text("1")] - ), - $cmp.bar - ? api_element( - "p", - { - key: 2, - }, - [api_text("2")] - ) - : null, - api_element( - "p", - { - key: 3, - }, - [api_text("3")] - ), - ] - ), + api_element("section", stc0, [ + api_element("p", stc1, [api_text("1")]), + $cmp.bar ? api_element("p", stc2, [api_text("2")]) : null, + api_element("p", stc3, [api_text("3")]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template/expected.js index 0658a86771..f5e9ccfd1f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-if/template/expected.js @@ -1,20 +1,17 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { d: api_dynamic_text, t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - $cmp.isTrue - ? api_text( - api_dynamic_text($cmp.foo) + " " + api_dynamic_text($cmp.bar) - ) - : null, - ] - ), + api_element("section", stc0, [ + $cmp.isTrue + ? api_text( + api_dynamic_text($cmp.foo) + " " + api_dynamic_text($cmp.bar) + ) + : null, + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/usage-if-for-each/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/usage-if-for-each/expected.js index db9da73490..c5dfcab292 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/usage-if-for-each/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/usage-if-for-each/expected.js @@ -1,5 +1,17 @@ import _aB from "a/b"; import { registerTemplate } from "lwc"; +const stc0 = { + classMap: { + s2: true, + }, + key: 0, +}; +const stc1 = { + lwc: { + dom: "manual", + }, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { shc: api_sanitize_html_content, @@ -13,12 +25,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { api_custom_element( "a-b", _aB, - { - classMap: { - s2: true, - }, - key: 0, - }, + stc0, api_flatten([ $cmp.isTrue ? api_element( @@ -32,14 +39,10 @@ function tmpl($api, $cmp, $slotset, $ctx) { )) : $ctx._sanitizedHtml$0, }, - context: { - lwc: { - dom: "manual", - }, - }, + context: stc1, key: 1, }, - [] + stc2 ) : null, api_iterator($cmp.items, function (item) { @@ -54,14 +57,10 @@ function tmpl($api, $cmp, $slotset, $ctx) { )) : $ctx._sanitizedHtml$1, }, - context: { - lwc: { - dom: "manual", - }, - }, + context: stc1, key: api_key(2, item.id), }, - [] + stc2 ); }), ]) diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/valid/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/valid/expected.js index 4c31a4f22b..9e255fe096 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/valid/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-inner-html/valid/expected.js @@ -1,4 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + lwc: { + dom: "manual", + }, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { shc: api_sanitize_html_content, h: api_element } = $api; return [ @@ -12,14 +18,10 @@ function tmpl($api, $cmp, $slotset, $ctx) { "Hello world!" )), }, - context: { - lwc: { - dom: "manual", - }, - }, + context: stc0, key: 0, }, - [] + stc1 ), api_element( "div", @@ -32,14 +34,10 @@ function tmpl($api, $cmp, $slotset, $ctx) { )) : $ctx._sanitizedHtml$1, }, - context: { - lwc: { - dom: "manual", - }, - }, + context: stc0, key: 1, }, - [] + stc1 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-iterator/iterator/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-iterator/iterator/expected.js index 301d6180dd..ae72c50270 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-iterator/iterator/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-iterator/iterator/expected.js @@ -1,4 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +16,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (xValue, xIndex, xFirst, xLast) { const x = { value: xValue, @@ -30,13 +34,9 @@ function tmpl($api, $cmp, $slotset, $ctx) { key: api_key(1, x.value.id), }, [ - api_element( - "span", - { - key: 2, - }, - [api_text("Row: " + api_dynamic_text(x.index))] - ), + api_element("span", stc1, [ + api_text("Row: " + api_dynamic_text(x.index)), + ]), api_text(". Value: " + api_dynamic_text(x.value)), ] ); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/component/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/component/expected.js index af8406e957..f682aac8f0 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/component/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/component/expected.js @@ -1,5 +1,8 @@ import _nsItem from "ns/item"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -12,9 +15,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "ul", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_custom_element( "ns-item", diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/element/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/element/expected.js index ab5e5fc6d3..58d0e5714f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/element/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/element/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "ul", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "li", diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/for-each/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/for-each/expected.js index 48ce4995aa..fd8cf12567 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/for-each/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/for-each/expected.js @@ -1,4 +1,13 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + "my-list": true, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,27 +19,15 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return api_element( "div", { - classMap: { - "my-list": true, - }, + classMap: stc1, key: api_key(1, item.id), }, - [ - api_element( - "p", - { - key: 2, - }, - [api_text(api_dynamic_text(item))] - ), - ] + [api_element("p", stc2, [api_text(api_dynamic_text(item))])] ); }) ), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-identifier/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-identifier/expected.js index e8c112a1da..7c52423714 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-identifier/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-identifier/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (xValue, xIndex, xFirst, xLast) { const x = { value: xValue, diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-member-expression/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-member-expression/expected.js index 332e051d02..5965b8e127 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-member-expression/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-key-member-expression/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (xValue, xIndex, xFirst, xLast) { const x = { value: xValue, diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-value-as-key/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-value-as-key/expected.js index a8a869aa8d..921b2c8834 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-value-as-key/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/iterator-value-as-key/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (xValue, xIndex, xFirst, xLast) { const x = { value: xValue, diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/nested-iterator-if/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/nested-iterator-if/expected.js index a1243adf67..4e1dd3046e 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/nested-iterator-if/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/nested-iterator-if/expected.js @@ -1,4 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +16,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (xValue, xIndex, xFirst, xLast) { const x = { value: xValue, @@ -31,13 +35,9 @@ function tmpl($api, $cmp, $slotset, $ctx) { key: api_key(1, x.value.id), }, [ - api_element( - "span", - { - key: 2, - }, - [api_text("Row: " + api_dynamic_text(x.index))] - ), + api_element("span", stc1, [ + api_text("Row: " + api_dynamic_text(x.index)), + ]), api_text(". Value: " + api_dynamic_text(x.value)), ] ), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/outside-iterator/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/outside-iterator/expected.js index 2505a3928b..14c6b88fb0 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/outside-iterator/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-key/outside-iterator/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, h: api_element } = $api; return [ @@ -7,7 +8,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { { key: api_key(0, $cmp.keyGetter), }, - [] + stc0 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/shadow-template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/shadow-template/expected.js index 5baa396d25..4c58fe1239 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/shadow-template/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/shadow-template/expected.js @@ -1,15 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; - return [ - api_element( - "p", - { - key: 0, - }, - [api_text("Root")] - ), - ]; + return [api_element("p", stc0, [api_text("Root")])]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/template/expected.js index 4521ad4b0d..7fde6d0481 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/template/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/directive-render-mode/template/expected.js @@ -1,33 +1,22 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + attrs: { + name: "named", + }, + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot, f: api_flatten } = $api; return api_flatten([ - api_element( - "p", - { - key: 0, - }, - [api_text("Root")] - ), - api_slot( - "", - { - key: 1, - }, - [api_text("Default")], - $slotset - ), - api_slot( - "named", - { - attrs: { - name: "named", - }, - key: 2, - }, - [api_text("Named")], - $slotset - ), + api_element("p", stc0, [api_text("Root")]), + api_slot("", stc1, [api_text("Default")], $slotset), + api_slot("named", stc2, [api_text("Named")], $slotset), ]); } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/events/component/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/events/component/expected.js index fcda7ca919..5120597205 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/events/component/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/events/component/expected.js @@ -1,28 +1,26 @@ import _nsFoo from "ns/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { b: api_bind, c: api_custom_element, h: api_element } = $api; const { _m0 } = $ctx; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_custom_element( - "ns-foo", - _nsFoo, - { - key: 1, - on: { - foo: _m0 || ($ctx._m0 = api_bind($cmp.handleFoo)), - }, + api_element("section", stc0, [ + api_custom_element( + "ns-foo", + _nsFoo, + { + key: 1, + on: { + foo: _m0 || ($ctx._m0 = api_bind($cmp.handleFoo)), }, - [] - ), - ] - ), + }, + stc1 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/events/tag/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/events/tag/expected.js index 0d3e5aa924..fc619cf0f6 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/events/tag/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/events/tag/expected.js @@ -1,36 +1,33 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { b: api_bind, t: api_text, h: api_element } = $api; const { _m0, _m1 } = $ctx; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "div", - { - key: 1, - on: { - click: _m0 || ($ctx._m0 = api_bind($cmp.handleClick)), - }, + api_element("section", stc0, [ + api_element( + "div", + { + key: 1, + on: { + click: _m0 || ($ctx._m0 = api_bind($cmp.handleClick)), }, - [api_text("x")] - ), - api_element( - "div", - { - key: 2, - on: { - press: _m1 || ($ctx._m1 = api_bind($cmp.handlePress)), - }, + }, + [api_text("x")] + ), + api_element( + "div", + { + key: 2, + on: { + press: _m1 || ($ctx._m1 = api_bind($cmp.handlePress)), }, - [api_text("x")] - ), - ] - ), + }, + [api_text("x")] + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-deep/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-deep/expected.js index 23e588c969..12d52c5771 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-deep/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-deep/expected.js @@ -1,23 +1,21 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - className: $cmp.bar.foo.baz, - key: 1, - }, - [] - ), - ] - ), + api_element("section", stc0, [ + api_element( + "p", + { + className: $cmp.bar.foo.baz, + key: 1, + }, + stc1 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-multiple/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-multiple/expected.js index ec95585af8..effc42d6af 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-multiple/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute-multiple/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ @@ -15,7 +16,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { className: $cmp.bar.c, key: 1, }, - [] + stc0 ), ] ), diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute/expected.js index a2680e9e0f..b585336cc7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/attribute/expected.js @@ -1,23 +1,21 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - className: $cmp.bar, - key: 1, - }, - [] - ), - ] - ), + api_element("section", stc0, [ + api_element( + "p", + { + className: $cmp.bar, + key: 1, + }, + stc1 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/escaped/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/escaped/expected.js index 90b018be72..7a7ca49079 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/escaped/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/escaped/expected.js @@ -1,18 +1,14 @@ import { registerTemplate } from "lwc"; +const stc0 = { + props: { + value: "{value}", + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "input", - { - props: { - value: "{value}", - }, - key: 0, - }, - [] - ), - ]; + return [api_element("input", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/tag/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/tag/expected.js index 96fbd4d78e..5f6281cd20 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/tag/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/expression/tag/expected.js @@ -1,15 +1,10 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { d: api_dynamic_text, t: api_text, h: api_element } = $api; - return [ - api_element( - "p", - { - key: 0, - }, - [api_text(api_dynamic_text($cmp.text))] - ), - ]; + return [api_element("p", stc0, [api_text(api_dynamic_text($cmp.text))])]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/html-tags/unkown-element/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/html-tags/unkown-element/expected.js index d7e13cff71..43ca39fbfe 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/html-tags/unkown-element/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/html-tags/unkown-element/expected.js @@ -1,40 +1,28 @@ import _xCustomComponent from "x/customComponent"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; +const stc2 = { + props: { + someTruthyValue: true, + }, + key: 1, +}; +const stc3 = { + key: 2, +}; +const stc4 = { + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element, c: api_custom_element, t: api_text } = $api; return [ - api_element( - "unknonwtag", - { - key: 0, - }, - [] - ), - api_custom_element( - "x-custom-component", - _xCustomComponent, - { - props: { - someTruthyValue: true, - }, - key: 1, - }, - [] - ), - api_element( - "span", - { - key: 2, - }, - [api_text("valid tags should not warn")] - ), - api_element( - "spam", - { - key: 3, - }, - [api_text("this tag has a typo")] - ), + api_element("unknonwtag", stc0, stc1), + api_custom_element("x-custom-component", _xCustomComponent, stc2, stc1), + api_element("span", stc3, [api_text("valid tags should not warn")]), + api_element("spam", stc4, [api_text("this tag has a typo")]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/comments/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/comments/expected.js index 730bc29b7f..4d6634a3cc 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/comments/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/comments/expected.js @@ -1,20 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + context: { + lwc: { + dom: "manual", + }, + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "div", - { - context: { - lwc: { - dom: "manual", - }, - }, - key: 0, - }, - [] - ), - ]; + return [api_element("div", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/manual/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/manual/expected.js index 730bc29b7f..4d6634a3cc 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/manual/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/lwc-dom/manual/expected.js @@ -1,20 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + context: { + lwc: { + dom: "manual", + }, + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "div", - { - context: { - lwc: { - dom: "manual", - }, - }, - key: 0, - }, - [] - ), - ]; + return [api_element("div", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/metadata/used-attrs/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/metadata/used-attrs/expected.js index f4bdad7dec..9c5f9859f2 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/metadata/used-attrs/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/metadata/used-attrs/expected.js @@ -1,22 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { d: api_dynamic_text, t: api_text, h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - key: 1, - }, - [api_text(api_dynamic_text($cmp.obj.sub))] - ), - ] - ), + api_element("section", stc0, [ + api_element("p", stc1, [api_text(api_dynamic_text($cmp.obj.sub))]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-default-slot/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-default-slot/expected.js index 0ec5649039..a67efd7f9c 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-default-slot/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-default-slot/expected.js @@ -1,23 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; +const stc2 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { s: api_slot } = $api; return [ - api_slot( - "", - { - key: 0, - }, - [], - $slotset - ), - api_slot( - "", - { - key: 1, - }, - [], - $slotset - ), + api_slot("", stc0, stc1, $slotset), + api_slot("", stc2, stc1, $slotset), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-named-slot/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-named-slot/expected.js index 9a9c738d1b..b7da62d0f8 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-named-slot/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/duplicate-named-slot/expected.js @@ -1,29 +1,22 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "foo", + }, + key: 0, +}; +const stc1 = []; +const stc2 = { + attrs: { + name: "foo", + }, + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { s: api_slot } = $api; return [ - api_slot( - "foo", - { - attrs: { - name: "foo", - }, - key: 0, - }, - [], - $slotset - ), - api_slot( - "foo", - { - attrs: { - name: "foo", - }, - key: 1, - }, - [], - $slotset - ), + api_slot("foo", stc0, stc1, $slotset), + api_slot("foo", stc2, stc1, $slotset), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/multiple-attributes/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/multiple-attributes/expected.js index dfef037cc3..f1085a4ad7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/multiple-attributes/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/multiple-attributes/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -10,9 +13,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { return [ api_element( "section", - { - key: 0, - }, + stc0, api_iterator($cmp.items, function (item) { return $cmp.showItems ? api_element( diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js index 5c3a8bbc78..f492d00435 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js @@ -1,7 +1,8 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {} = $api; - return []; + return stc0; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/named-slot-in-iterator/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/named-slot-in-iterator/expected.js index 080cb4ef40..e9f5c0d817 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/named-slot-in-iterator/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/named-slot-in-iterator/expected.js @@ -1,4 +1,11 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "james", + }, + key: 1, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, s: api_slot, h: api_element, i: api_iterator } = $api; return api_iterator($cmp.items, function (item) { @@ -7,19 +14,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { { key: api_key(0, item), }, - [ - api_slot( - "james", - { - attrs: { - name: "james", - }, - key: 1, - }, - [], - $slotset - ), - ] + [api_slot("james", stc0, stc1, $slotset)] ); }); } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/slot-in-iterator/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/slot-in-iterator/expected.js index d7a68df40f..abd70d1865 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/slot-in-iterator/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/slot-in-iterator/expected.js @@ -1,4 +1,8 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, s: api_slot, h: api_element, i: api_iterator } = $api; return api_iterator($cmp.items, function (item) { @@ -7,16 +11,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { { key: api_key(0, item), }, - [ - api_slot( - "", - { - key: 1, - }, - [], - $slotset - ), - ] + [api_slot("", stc0, stc1, $slotset)] ); }); } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/class-name-slash/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/class-name-slash/expected.js index 1f6daac69f..d8d80787d7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/class-name-slash/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/class-name-slash/expected.js @@ -1,23 +1,18 @@ import _xCmp from "x/cmp"; import { registerTemplate } from "lwc"; +const stc0 = { + classMap: { + foo: true, + }, + props: { + xClass: "bar", + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; - return [ - api_custom_element( - "x-cmp", - _xCmp, - { - classMap: { - foo: true, - }, - props: { - xClass: "bar", - }, - key: 0, - }, - [] - ), - ]; + return [api_custom_element("x-cmp", _xCmp, stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/dashed-html-tag/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/dashed-html-tag/expected.js index f927abe6e3..66256e074a 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/dashed-html-tag/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/dashed-html-tag/expected.js @@ -1,25 +1,18 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + local: "x", + }, + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "color-profile", - { - attrs: { - local: "x", - }, - key: 1, - }, - [] - ), - ] - ), + api_element("section", stc0, [api_element("color-profile", stc1, stc2)]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/excaped-json/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/excaped-json/expected.js index 4abf3d3c05..b892309bab 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/excaped-json/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/excaped-json/expected.js @@ -1,20 +1,15 @@ import _xTest from "x/test"; import { registerTemplate } from "lwc"; +const stc0 = { + props: { + json: '[{"column":"ID","value":"5e","operator":"equals","f":true}]', + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; - return [ - api_custom_element( - "x-test", - _xTest, - { - props: { - json: '[{"column":"ID","value":"5e","operator":"equals","f":true}]', - }, - key: 0, - }, - [] - ), - ]; + return [api_custom_element("x-test", _xTest, stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/handler-memoization/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/handler-memoization/expected.js index 484fec2c3b..cd3d509d22 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/handler-memoization/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/handler-memoization/expected.js @@ -1,4 +1,7 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { b: api_bind, @@ -22,9 +25,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ), api_element( "ul", - { - key: 1, - }, + stc0, api_iterator($cmp.list, function (task) { return api_element( "li", diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/invalid-html-recovery/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/invalid-html-recovery/expected.js index 80137b8f71..a350620ea2 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/invalid-html-recovery/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/invalid-html-recovery/expected.js @@ -1,21 +1,16 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "h1", - { - key: 0, - }, - [api_text("hello")] - ), - api_element( - "br", - { - key: 1, - }, - [] - ), + api_element("h1", stc0, [api_text("hello")]), + api_element("br", stc1, stc2), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/nested-if-loops/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/nested-if-loops/expected.js index 4a0a0bd2bc..ee41782ff7 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/nested-if-loops/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/nested-if-loops/expected.js @@ -1,4 +1,5 @@ import { registerTemplate } from "lwc"; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, @@ -20,7 +21,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { ); }), ]) - : []; + : stc0; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/slot-name-with-dash/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/slot-name-with-dash/expected.js index e8812288e6..e9bd13a8d8 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/slot-name-with-dash/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/slot-name-with-dash/expected.js @@ -1,24 +1,20 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + name: "secret-slot", + }, + key: 0, +}; +const stc1 = { + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot } = $api; return [ api_slot( "secret-slot", - { - attrs: { - name: "secret-slot", - }, - key: 0, - }, - [ - api_element( - "p", - { - key: 1, - }, - [api_text("Test slot content")] - ), - ], + stc0, + [api_element("p", stc1, [api_text("Test slot content")])], $slotset ), ]; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/table-with-tr/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/table-with-tr/expected.js index 15bc6ea545..589f5baa60 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/table-with-tr/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/regression/table-with-tr/expected.js @@ -1,30 +1,20 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; +const stc3 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "table", - { - key: 0, - }, - [ - api_element( - "tbody", - { - key: 1, - }, - [ - api_element( - "tr", - { - key: 2, - }, - [] - ), - ] - ), - ] - ), + api_element("table", stc0, [ + api_element("tbody", stc1, [api_element("tr", stc2, stc3)]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/secure/secure-template/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/secure/secure-template/expected.js index 0c7db845a9..4f82cf51c4 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/secure/secure-template/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/secure/secure-template/expected.js @@ -1,17 +1,12 @@ import _xTest from "x/test"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; - return [ - api_custom_element( - "x-test", - _xTest, - { - key: 0, - }, - [] - ), - ]; + return [api_custom_element("x-test", _xTest, stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/component-definition/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/component-definition/expected.js index 13cb6be951..b662cc2869 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/component-definition/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/component-definition/expected.js @@ -1,25 +1,18 @@ import _xFoo from "x/foo"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { s: api_slot, c: api_custom_element } = $api; return [ - api_custom_element( - "x-foo", - _xFoo, - { - key: 0, - }, - [ - api_slot( - "", - { - key: 1, - }, - [], - $slotset - ), - ] - ), + api_custom_element("x-foo", _xFoo, stc0, [ + api_slot("", stc1, stc2, $slotset), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibiling-slot/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibiling-slot/expected.js index e5b096d224..e15f1ae1b9 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibiling-slot/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibiling-slot/expected.js @@ -1,50 +1,39 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + name: "other", + }, + key: 1, +}; +const stc2 = { + key: 2, +}; +const stc3 = { + key: 3, +}; +const stc4 = { + key: 4, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_slot( - "other", - { - attrs: { - name: "other", - }, - key: 1, - }, - [ - api_element( - "p", - { - key: 2, - }, - [api_text("Default slot other content")] - ), - ], - $slotset - ), - api_slot( - "", - { - key: 3, - }, - [ - api_element( - "p", - { - key: 4, - }, - [api_text("Default slot content")] - ), - ], - $slotset - ), - ] - ), + api_element("section", stc0, [ + api_slot( + "other", + stc1, + [api_element("p", stc2, [api_text("Default slot other content")])], + $slotset + ), + api_slot( + "", + stc3, + [api_element("p", stc4, [api_text("Default slot content")])], + $slotset + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibling-static/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibling-static/expected.js index 98dcf29ec5..49fa342f8b 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibling-static/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition-sibling-static/expected.js @@ -1,38 +1,28 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; +const stc3 = { + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - key: 1, - }, - [api_text("Sibling")] - ), - api_slot( - "", - { - key: 2, - }, - [ - api_element( - "p", - { - key: 3, - }, - [api_text("Default slot content")] - ), - ], - $slotset - ), - ] - ), + api_element("section", stc0, [ + api_element("p", stc1, [api_text("Sibling")]), + api_slot( + "", + stc2, + [api_element("p", stc3, [api_text("Default slot content")])], + $slotset + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition/expected.js index fa280d3a21..c8646c45cf 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/definition/expected.js @@ -1,31 +1,24 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_slot( - "", - { - key: 1, - }, - [ - api_element( - "p", - { - key: 2, - }, - [api_text("Default slot content")] - ), - ], - $slotset - ), - ] - ), + api_element("section", stc0, [ + api_slot( + "", + stc1, + [api_element("p", stc2, [api_text("Default slot content")])], + $slotset + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed-1/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed-1/expected.js index b37999861a..50d545bf1d 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed-1/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed-1/expected.js @@ -1,82 +1,58 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + attrs: { + name: "header", + }, + key: 2, +}; +const stc3 = { + key: 3, +}; +const stc4 = { + key: 4, +}; +const stc5 = { + key: 5, +}; +const stc6 = { + key: 6, +}; +const stc7 = { + attrs: { + name: "footer", + }, + key: 7, +}; +const stc8 = { + key: 8, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_element( - "p", - { - key: 1, - }, - [api_text("Before header")] - ), - api_slot( - "header", - { - attrs: { - name: "header", - }, - key: 2, - }, - [api_text("Default header")], - $slotset - ), - api_element( - "p", - { - key: 3, - }, - [api_text("In")] - ), - api_element( - "p", - { - key: 4, - }, - [api_text("between")] - ), - api_slot( - "", - { - key: 5, - }, - [ - api_element( - "p", - { - key: 6, - }, - [api_text("Default body")] - ), - ], - $slotset - ), - api_slot( - "footer", - { - attrs: { - name: "footer", - }, - key: 7, - }, - [ - api_element( - "p", - { - key: 8, - }, - [api_text("Default footer")] - ), - ], - $slotset - ), - ] - ), + api_element("section", stc0, [ + api_element("p", stc1, [api_text("Before header")]), + api_slot("header", stc2, [api_text("Default header")], $slotset), + api_element("p", stc3, [api_text("In")]), + api_element("p", stc4, [api_text("between")]), + api_slot( + "", + stc5, + [api_element("p", stc6, [api_text("Default body")])], + $slotset + ), + api_slot( + "footer", + stc7, + [api_element("p", stc8, [api_text("Default footer")])], + $slotset + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed/expected.js index 7f47bc92e3..7effe28266 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/mixed/expected.js @@ -1,5 +1,15 @@ import _xB from "x/b"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + key: 2, +}; +const stc3 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element, @@ -9,37 +19,21 @@ function tmpl($api, $cmp, $slotset, $ctx) { c: api_custom_element, } = $api; return [ - api_element( - "div", - { - key: 0, - }, - [ - api_custom_element( - "x-b", - _xB, - { - key: 1, - }, - api_flatten([ - $cmp.isLoading - ? api_element( - "div", - { - key: 2, - }, - [] - ) - : null, - $cmp.haveLoadedItems - ? api_iterator($cmp.menuItems, function (item) { - return api_text("x"); - }) - : [], - ]) - ), - ] - ), + api_element("div", stc0, [ + api_custom_element( + "x-b", + _xB, + stc1, + api_flatten([ + $cmp.isLoading ? api_element("div", stc2, stc3) : null, + $cmp.haveLoadedItems + ? api_iterator($cmp.menuItems, function (item) { + return api_text("x"); + }) + : stc3, + ]) + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/no-slot/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/no-slot/expected.js index 2936925ff1..8d03df6877 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/no-slot/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/no-slot/expected.js @@ -1,17 +1,12 @@ import _xCmp from "x/cmp"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { c: api_custom_element } = $api; - return [ - api_custom_element( - "x-cmp", - _xCmp, - { - key: 0, - }, - [] - ), - ]; + return [api_custom_element("x-cmp", _xCmp, stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if-for-each/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if-for-each/expected.js index d96d839352..1cf12a448f 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if-for-each/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if-for-each/expected.js @@ -1,5 +1,12 @@ import _aB from "a/b"; import { registerTemplate } from "lwc"; +const stc0 = { + classMap: { + s2: true, + }, + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { k: api_key, @@ -12,12 +19,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { api_custom_element( "a-b", _aB, - { - classMap: { - s2: true, - }, - key: 0, - }, + stc0, $cmp.isTrue ? api_iterator($cmp.items, function (item) { return api_element( @@ -28,7 +30,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { [api_text("X")] ); }) - : [] + : stc1 ), ]; } diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if/expected.js index 5692eeaab1..d5ca9e65ad 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-if/expected.js @@ -1,47 +1,32 @@ import _nsCmp from "ns/cmp"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + attrs: { + slot: "", + }, + key: 2, +}; +const stc3 = { + attrs: { + slot: "", + }, + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, c: api_custom_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_custom_element( - "ns-cmp", - _nsCmp, - { - key: 1, - }, - [ - $cmp.isTrue - ? api_element( - "p", - { - attrs: { - slot: "", - }, - key: 2, - }, - [api_text("S1")] - ) - : null, - api_element( - "p", - { - attrs: { - slot: "", - }, - key: 3, - }, - [api_text("S2")] - ), - ] - ), - ] - ), + api_element("section", stc0, [ + api_custom_element("ns-cmp", _nsCmp, stc1, [ + $cmp.isTrue ? api_element("p", stc2, [api_text("S1")]) : null, + api_element("p", stc3, [api_text("S2")]), + ]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-named/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-named/expected.js index 332efa279b..f47675d09e 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-named/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage-named/expected.js @@ -1,34 +1,27 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + name: "test", + }, + key: 1, +}; +const stc2 = { + key: 2, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, s: api_slot } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_slot( - "test", - { - attrs: { - name: "test", - }, - key: 1, - }, - [ - api_element( - "p", - { - key: 2, - }, - [api_text("Test slot content")] - ), - ], - $slotset - ), - ] - ), + api_element("section", stc0, [ + api_slot( + "test", + stc1, + [api_element("p", stc2, [api_text("Test slot content")])], + $slotset + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage/expected.js index 9ff6b7385f..4f8085bcf9 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/slots/usage/expected.js @@ -1,45 +1,32 @@ import _nsCmp from "ns/cmp"; import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + key: 1, +}; +const stc2 = { + attrs: { + slot: "header", + }, + key: 2, +}; +const stc3 = { + attrs: { + slot: "", + }, + key: 3, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element, c: api_custom_element } = $api; return [ - api_element( - "section", - { - key: 0, - }, - [ - api_custom_element( - "ns-cmp", - _nsCmp, - { - key: 1, - }, - [ - api_element( - "p", - { - attrs: { - slot: "header", - }, - key: 2, - }, - [api_text("Header Slot Content")] - ), - api_element( - "p", - { - attrs: { - slot: "", - }, - key: 3, - }, - [api_text("Default Content")] - ), - ] - ), - ] - ), + api_element("section", stc0, [ + api_custom_element("ns-cmp", _nsCmp, stc1, [ + api_element("p", stc2, [api_text("Header Slot Content")]), + api_element("p", stc3, [api_text("Default Content")]), + ]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/filter/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/filter/expected.js index 90ad07028d..5ff43f9f01 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/filter/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/filter/expected.js @@ -1,641 +1,511 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + width: "400", + height: "400", + xmlns: "http://www.w3.org/2000/svg", + }, + key: 0, + svg: true, +}; +const stc1 = { + key: 1, + svg: true, +}; +const stc2 = { + attrs: { + x: "25%", + y: "25%", + width: "50%", + height: "50%", + "flood-color": "green", + "flood-opacity": "0.75", + }, + key: 3, + svg: true, +}; +const stc3 = []; +const stc4 = { + attrs: { + x: "25%", + y: "25%", + width: "50%", + height: "50%", + in2: "SourceGraphic", + mode: "multiply", + }, + key: 5, + svg: true, +}; +const stc5 = { + attrs: { + x: "25%", + y: "25%", + width: "50%", + height: "50%", + }, + key: 7, + svg: true, +}; +const stc6 = { + attrs: { + in: "SourceGraphic", + }, + key: 8, + svg: true, +}; +const stc7 = { + attrs: { + in: "FillPaint", + }, + key: 9, + svg: true, +}; +const stc8 = { + attrs: { + fill: "none", + stroke: "blue", + "stroke-width": "4", + }, + key: 10, + svg: true, +}; +const stc9 = { + attrs: { + width: "200", + height: "200", + }, + key: 11, + svg: true, +}; +const stc10 = { + attrs: { + x2: "200", + y2: "200", + }, + key: 12, + svg: true, +}; +const stc11 = { + attrs: { + x1: "200", + y2: "200", + }, + key: 13, + svg: true, +}; +const stc12 = { + attrs: { + fill: "green", + filter: "url(#flood)", + cx: "100", + cy: "100", + r: "90", + }, + key: 14, + svg: true, +}; +const stc13 = { + attrs: { + transform: "translate(200 0)", + }, + key: 15, + svg: true, +}; +const stc14 = { + attrs: { + fill: "none", + stroke: "blue", + "stroke-width": "4", + }, + key: 16, + svg: true, +}; +const stc15 = { + attrs: { + width: "200", + height: "200", + }, + key: 17, + svg: true, +}; +const stc16 = { + attrs: { + x2: "200", + y2: "200", + }, + key: 18, + svg: true, +}; +const stc17 = { + attrs: { + x1: "200", + y2: "200", + }, + key: 19, + svg: true, +}; +const stc18 = { + attrs: { + fill: "green", + filter: "url(#blend)", + cx: "100", + cy: "100", + r: "90", + }, + key: 20, + svg: true, +}; +const stc19 = { + attrs: { + transform: "translate(0 200)", + }, + key: 21, + svg: true, +}; +const stc20 = { + attrs: { + fill: "none", + stroke: "blue", + "stroke-width": "4", + }, + key: 22, + svg: true, +}; +const stc21 = { + attrs: { + width: "200", + height: "200", + }, + key: 23, + svg: true, +}; +const stc22 = { + attrs: { + x2: "200", + y2: "200", + }, + key: 24, + svg: true, +}; +const stc23 = { + attrs: { + x1: "200", + y2: "200", + }, + key: 25, + svg: true, +}; +const stc24 = { + attrs: { + fill: "green", + "fill-opacity": "0.5", + filter: "url(#merge)", + cx: "100", + cy: "100", + r: "90", + }, + key: 26, + svg: true, +}; +const stc25 = { + attrs: { + width: "600", + height: "250", + viewBox: "0 0 600 250", + xmlns: "http://www.w3.org/2000/svg", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + }, + key: 27, + svg: true, +}; +const stc26 = { + attrs: { + fill: "none", + stroke: "blue", + x: "1", + y: "1", + width: "598", + height: "248", + }, + key: 28, + svg: true, +}; +const stc27 = { + key: 29, + svg: true, +}; +const stc28 = { + attrs: { + x: "50", + y: "25", + width: "100", + height: "200", + filter: "url(#Default)", + }, + key: 30, + svg: true, +}; +const stc29 = { + attrs: { + x: "50", + y: "25", + width: "100", + height: "200", + fill: "none", + stroke: "green", + }, + key: 31, + svg: true, +}; +const stc30 = { + attrs: { + x: "250", + y: "25", + width: "100", + height: "200", + filter: "url(#Fitted)", + }, + key: 32, + svg: true, +}; +const stc31 = { + attrs: { + x: "250", + y: "25", + width: "100", + height: "200", + fill: "none", + stroke: "green", + }, + key: 33, + svg: true, +}; +const stc32 = { + attrs: { + x: "450", + y: "25", + width: "100", + height: "200", + filter: "url(#Shifted)", + }, + key: 34, + svg: true, +}; +const stc33 = { + attrs: { + x: "450", + y: "25", + width: "100", + height: "200", + fill: "none", + stroke: "green", + }, + key: 35, + svg: true, +}; +const stc34 = { + key: 37, + svg: true, +}; +const stc35 = { + attrs: { + in: "SourceAlpha", + stdDeviation: "4", + result: "blur", + }, + key: 38, + svg: true, +}; +const stc36 = { + attrs: { + in: "blur", + dx: "4", + dy: "4", + result: "offsetBlur", + }, + key: 39, + svg: true, +}; +const stc37 = { + attrs: { + in: "blur", + surfaceScale: "5", + specularConstant: ".75", + specularExponent: "20", + "lighting-color": "#bbbbbb", + result: "specOut", + }, + key: 40, + svg: true, +}; +const stc38 = { + attrs: { + x: "-5000", + y: "-10000", + z: "20000", + }, + key: 41, + svg: true, +}; +const stc39 = { + attrs: { + in: "specOut", + in2: "SourceAlpha", + operator: "in", + result: "specOut", + }, + key: 42, + svg: true, +}; +const stc40 = { + attrs: { + in: "SourceGraphic", + in2: "specOut", + operator: "arithmetic", + k1: "0", + k2: "1", + k3: "1", + k4: "0", + result: "litPaint", + }, + key: 43, + svg: true, +}; +const stc41 = { + key: 44, + svg: true, +}; +const stc42 = { + attrs: { + in: "offsetBlur", + }, + key: 45, + svg: true, +}; +const stc43 = { + attrs: { + in: "litPaint", + }, + key: 46, + svg: true, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { gid: api_scoped_id, h: api_element, t: api_text } = $api; return [ - api_element( - "svg", - { - attrs: { - width: "400", - height: "400", - xmlns: "http://www.w3.org/2000/svg", - }, - key: 0, - svg: true, - }, - [ + api_element("svg", stc0, [ + api_element("defs", stc1, [ api_element( - "defs", - { - key: 1, - svg: true, - }, - [ - api_element( - "filter", - { - attrs: { - id: api_scoped_id("flood"), - x: "0", - y: "0", - width: "100%", - height: "100%", - primitiveUnits: "objectBoundingBox", - }, - key: 2, - svg: true, - }, - [ - api_element( - "feFlood", - { - attrs: { - x: "25%", - y: "25%", - width: "50%", - height: "50%", - "flood-color": "green", - "flood-opacity": "0.75", - }, - key: 3, - svg: true, - }, - [] - ), - ] - ), - api_element( - "filter", - { - attrs: { - id: api_scoped_id("blend"), - primitiveUnits: "objectBoundingBox", - }, - key: 4, - svg: true, - }, - [ - api_element( - "feBlend", - { - attrs: { - x: "25%", - y: "25%", - width: "50%", - height: "50%", - in2: "SourceGraphic", - mode: "multiply", - }, - key: 5, - svg: true, - }, - [] - ), - ] - ), - api_element( - "filter", - { - attrs: { - id: api_scoped_id("merge"), - primitiveUnits: "objectBoundingBox", - }, - key: 6, - svg: true, - }, - [ - api_element( - "feMerge", - { - attrs: { - x: "25%", - y: "25%", - width: "50%", - height: "50%", - }, - key: 7, - svg: true, - }, - [ - api_element( - "feMergeNode", - { - attrs: { - in: "SourceGraphic", - }, - key: 8, - svg: true, - }, - [] - ), - api_element( - "feMergeNode", - { - attrs: { - in: "FillPaint", - }, - key: 9, - svg: true, - }, - [] - ), - ] - ), - ] - ), - ] - ), - api_element( - "g", + "filter", { attrs: { - fill: "none", - stroke: "blue", - "stroke-width": "4", + id: api_scoped_id("flood"), + x: "0", + y: "0", + width: "100%", + height: "100%", + primitiveUnits: "objectBoundingBox", }, - key: 10, + key: 2, svg: true, }, - [ - api_element( - "rect", - { - attrs: { - width: "200", - height: "200", - }, - key: 11, - svg: true, - }, - [] - ), - api_element( - "line", - { - attrs: { - x2: "200", - y2: "200", - }, - key: 12, - svg: true, - }, - [] - ), - api_element( - "line", - { - attrs: { - x1: "200", - y2: "200", - }, - key: 13, - svg: true, - }, - [] - ), - ] + [api_element("feFlood", stc2, stc3)] ), api_element( - "circle", + "filter", { attrs: { - fill: "green", - filter: "url(#flood)", - cx: "100", - cy: "100", - r: "90", + id: api_scoped_id("blend"), + primitiveUnits: "objectBoundingBox", }, - key: 14, + key: 4, svg: true, }, - [] + [api_element("feBlend", stc4, stc3)] ), api_element( - "g", + "filter", { attrs: { - transform: "translate(200 0)", + id: api_scoped_id("merge"), + primitiveUnits: "objectBoundingBox", }, - key: 15, + key: 6, svg: true, }, [ - api_element( - "g", - { - attrs: { - fill: "none", - stroke: "blue", - "stroke-width": "4", - }, - key: 16, - svg: true, - }, - [ - api_element( - "rect", - { - attrs: { - width: "200", - height: "200", - }, - key: 17, - svg: true, - }, - [] - ), - api_element( - "line", - { - attrs: { - x2: "200", - y2: "200", - }, - key: 18, - svg: true, - }, - [] - ), - api_element( - "line", - { - attrs: { - x1: "200", - y2: "200", - }, - key: 19, - svg: true, - }, - [] - ), - ] - ), - api_element( - "circle", - { - attrs: { - fill: "green", - filter: "url(#blend)", - cx: "100", - cy: "100", - r: "90", - }, - key: 20, - svg: true, - }, - [] - ), + api_element("feMerge", stc5, [ + api_element("feMergeNode", stc6, stc3), + api_element("feMergeNode", stc7, stc3), + ]), ] ), - api_element( - "g", - { - attrs: { - transform: "translate(0 200)", - }, - key: 21, - svg: true, + ]), + api_element("g", stc8, [ + api_element("rect", stc9, stc3), + api_element("line", stc10, stc3), + api_element("line", stc11, stc3), + ]), + api_element("circle", stc12, stc3), + api_element("g", stc13, [ + api_element("g", stc14, [ + api_element("rect", stc15, stc3), + api_element("line", stc16, stc3), + api_element("line", stc17, stc3), + ]), + api_element("circle", stc18, stc3), + ]), + api_element("g", stc19, [ + api_element("g", stc20, [ + api_element("rect", stc21, stc3), + api_element("line", stc22, stc3), + api_element("line", stc23, stc3), + ]), + api_element("circle", stc24, stc3), + ]), + ]), + api_element("svg", stc25, [ + api_element("rect", stc26, stc3), + api_element("g", stc27, [ + api_element("rect", stc28, stc3), + api_element("rect", stc29, stc3), + api_element("rect", stc30, stc3), + api_element("rect", stc31, stc3), + api_element("rect", stc32, stc3), + api_element("rect", stc33, stc3), + ]), + api_element( + "filter", + { + attrs: { + id: api_scoped_id("MyFilter"), + filterUnits: "userSpaceOnUse", + x: "0", + y: "0", + width: "200", + height: "120", }, - [ - api_element( - "g", - { - attrs: { - fill: "none", - stroke: "blue", - "stroke-width": "4", - }, - key: 22, - svg: true, - }, - [ - api_element( - "rect", - { - attrs: { - width: "200", - height: "200", - }, - key: 23, - svg: true, - }, - [] - ), - api_element( - "line", - { - attrs: { - x2: "200", - y2: "200", - }, - key: 24, - svg: true, - }, - [] - ), - api_element( - "line", - { - attrs: { - x1: "200", - y2: "200", - }, - key: 25, - svg: true, - }, - [] - ), - ] - ), - api_element( - "circle", - { - attrs: { - fill: "green", - "fill-opacity": "0.5", - filter: "url(#merge)", - cx: "100", - cy: "100", - r: "90", - }, - key: 26, - svg: true, - }, - [] - ), - ] - ), - ] - ), - api_element( - "svg", - { - attrs: { - width: "600", - height: "250", - viewBox: "0 0 600 250", - xmlns: "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink", + key: 36, + svg: true, }, - key: 27, - svg: true, - }, - [ - api_element( - "rect", - { - attrs: { - fill: "none", - stroke: "blue", - x: "1", - y: "1", - width: "598", - height: "248", - }, - key: 28, - svg: true, - }, - [] - ), - api_element( - "g", - { - key: 29, - svg: true, - }, - [ - api_element( - "rect", - { - attrs: { - x: "50", - y: "25", - width: "100", - height: "200", - filter: "url(#Default)", - }, - key: 30, - svg: true, - }, - [] - ), - api_element( - "rect", - { - attrs: { - x: "50", - y: "25", - width: "100", - height: "200", - fill: "none", - stroke: "green", - }, - key: 31, - svg: true, - }, - [] - ), - api_element( - "rect", - { - attrs: { - x: "250", - y: "25", - width: "100", - height: "200", - filter: "url(#Fitted)", - }, - key: 32, - svg: true, - }, - [] - ), - api_element( - "rect", - { - attrs: { - x: "250", - y: "25", - width: "100", - height: "200", - fill: "none", - stroke: "green", - }, - key: 33, - svg: true, - }, - [] - ), - api_element( - "rect", - { - attrs: { - x: "450", - y: "25", - width: "100", - height: "200", - filter: "url(#Shifted)", - }, - key: 34, - svg: true, - }, - [] - ), - api_element( - "rect", - { - attrs: { - x: "450", - y: "25", - width: "100", - height: "200", - fill: "none", - stroke: "green", - }, - key: 35, - svg: true, - }, - [] - ), - ] - ), - api_element( - "filter", - { - attrs: { - id: api_scoped_id("MyFilter"), - filterUnits: "userSpaceOnUse", - x: "0", - y: "0", - width: "200", - height: "120", - }, - key: 36, - svg: true, - }, - [ - api_element( - "desc", - { - key: 37, - svg: true, - }, - [api_text("Produces a 3D lighting effect.")] - ), - api_element( - "feGaussianBlur", - { - attrs: { - in: "SourceAlpha", - stdDeviation: "4", - result: "blur", - }, - key: 38, - svg: true, - }, - [] - ), - api_element( - "feOffset", - { - attrs: { - in: "blur", - dx: "4", - dy: "4", - result: "offsetBlur", - }, - key: 39, - svg: true, - }, - [] - ), - api_element( - "feSpecularLighting", - { - attrs: { - in: "blur", - surfaceScale: "5", - specularConstant: ".75", - specularExponent: "20", - "lighting-color": "#bbbbbb", - result: "specOut", - }, - key: 40, - svg: true, - }, - [ - api_element( - "fePointLight", - { - attrs: { - x: "-5000", - y: "-10000", - z: "20000", - }, - key: 41, - svg: true, - }, - [] - ), - ] - ), - api_element( - "feComposite", - { - attrs: { - in: "specOut", - in2: "SourceAlpha", - operator: "in", - result: "specOut", - }, - key: 42, - svg: true, - }, - [] - ), - api_element( - "feComposite", - { - attrs: { - in: "SourceGraphic", - in2: "specOut", - operator: "arithmetic", - k1: "0", - k2: "1", - k3: "1", - k4: "0", - result: "litPaint", - }, - key: 43, - svg: true, - }, - [] - ), - api_element( - "feMerge", - { - key: 44, - svg: true, - }, - [ - api_element( - "feMergeNode", - { - attrs: { - in: "offsetBlur", - }, - key: 45, - svg: true, - }, - [] - ), - api_element( - "feMergeNode", - { - attrs: { - in: "litPaint", - }, - key: 46, - svg: true, - }, - [] - ), - ] - ), - ] - ), - ] - ), + [ + api_element("desc", stc34, [ + api_text("Produces a 3D lighting effect."), + ]), + api_element("feGaussianBlur", stc35, stc3), + api_element("feOffset", stc36, stc3), + api_element("feSpecularLighting", stc37, [ + api_element("fePointLight", stc38, stc3), + ]), + api_element("feComposite", stc39, stc3), + api_element("feComposite", stc40, stc3), + api_element("feMerge", stc41, [ + api_element("feMergeNode", stc42, stc3), + api_element("feMergeNode", stc43, stc3), + ]), + ] + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/foreign-object/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/foreign-object/expected.js index 70ad6d595c..a221acca9e 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/foreign-object/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/foreign-object/expected.js @@ -1,73 +1,55 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, +}; +const stc1 = { + attrs: { + width: "706", + height: "180", + }, + key: 1, + svg: true, +}; +const stc2 = { + attrs: { + transform: "translate(3,3)", + }, + key: 2, + svg: true, +}; +const stc3 = { + attrs: { + transform: "translate(250,0)", + }, + key: 3, + svg: true, +}; +const stc4 = { + attrs: { + width: "200", + height: "36", + "xlink:href": "javascript:alert(1)", + }, + key: 4, + svg: true, +}; +const stc5 = { + key: 5, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { t: api_text, h: api_element } = $api; return [ - api_element( - "div", - { - key: 0, - }, - [ - api_element( - "svg", - { - attrs: { - width: "706", - height: "180", - }, - key: 1, - svg: true, - }, - [ - api_element( - "g", - { - attrs: { - transform: "translate(3,3)", - }, - key: 2, - svg: true, - }, - [ - api_element( - "g", - { - attrs: { - transform: "translate(250,0)", - }, - key: 3, - svg: true, - }, - [ - api_element( - "foreignObject", - { - attrs: { - width: "200", - height: "36", - "xlink:href": "javascript:alert(1)", - }, - key: 4, - svg: true, - }, - [ - api_element( - "a", - { - key: 5, - }, - [api_text("x")] - ), - ] - ), - ] - ), - ] - ), - ] - ), - ] - ), + api_element("div", stc0, [ + api_element("svg", stc1, [ + api_element("g", stc2, [ + api_element("g", stc3, [ + api_element("foreignObject", stc4, [ + api_element("a", stc5, [api_text("x")]), + ]), + ]), + ]), + ]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js index d9819a96e4..764ea0edb5 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js @@ -1,90 +1,84 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + height: "150", + width: "400", + }, + key: 0, + svg: true, +}; +const stc1 = { + key: 1, + svg: true, +}; +const stc2 = { + offset: "0%", +}; +const stc3 = []; +const stc4 = { + offset: "100%", +}; +const stc5 = { + attrs: { + cx: "200", + cy: "70", + rx: "85", + ry: "55", + fill: "url(#grad1)", + }, + key: 5, + svg: true, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { gid: api_scoped_id, h: api_element } = $api; return [ - api_element( - "svg", - { - attrs: { - height: "150", - width: "400", - }, - key: 0, - svg: true, - }, - [ + api_element("svg", stc0, [ + api_element("defs", stc1, [ api_element( - "defs", + "linearGradient", { - key: 1, + attrs: { + id: api_scoped_id("grad1"), + x1: "0%", + y1: "0%", + x2: "100%", + y2: "0%", + }, + key: 2, svg: true, }, [ api_element( - "linearGradient", + "stop", + { + styleDecls: [ + ["stop-color", "rgb(255,255,0)", false], + ["stop-opacity", "1", false], + ], + attrs: stc2, + key: 3, + svg: true, + }, + stc3 + ), + api_element( + "stop", { - attrs: { - id: api_scoped_id("grad1"), - x1: "0%", - y1: "0%", - x2: "100%", - y2: "0%", - }, - key: 2, + styleDecls: [ + ["stop-color", "rgb(255,0,0)", false], + ["stop-opacity", "1", false], + ], + attrs: stc4, + key: 4, svg: true, }, - [ - api_element( - "stop", - { - styleDecls: [ - ["stop-color", "rgb(255,255,0)", false], - ["stop-opacity", "1", false], - ], - attrs: { - offset: "0%", - }, - key: 3, - svg: true, - }, - [] - ), - api_element( - "stop", - { - styleDecls: [ - ["stop-color", "rgb(255,0,0)", false], - ["stop-opacity", "1", false], - ], - attrs: { - offset: "100%", - }, - key: 4, - svg: true, - }, - [] - ), - ] + stc3 ), ] ), - api_element( - "ellipse", - { - attrs: { - cx: "200", - cy: "70", - rx: "85", - ry: "55", - fill: "url(#grad1)", - }, - key: 5, - svg: true, - }, - [] - ), - ] - ), + ]), + api_element("ellipse", stc5, stc3), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-dynamic/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-dynamic/expected.js index 08a347b984..7e8c2f4411 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-dynamic/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-dynamic/expected.js @@ -1,92 +1,87 @@ import { registerTemplate, sanitizeAttribute } from "lwc"; +const stc0 = { + attrs: { + width: "100px", + height: "100px", + viewport: "0 0 100 100", + }, + key: 0, + svg: true, +}; +const stc1 = { + key: 1, + svg: true, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { gid: api_scoped_id, h: api_element, fid: api_scoped_frag_id } = $api; return [ - api_element( - "svg", - { - attrs: { - width: "100px", - height: "100px", - viewport: "0 0 100 100", - }, - key: 0, - svg: true, - }, - [ - api_element( - "defs", - { - key: 1, - svg: true, - }, - [ - api_element( - "circle", - { - attrs: { - id: api_scoped_id($cmp.blackId), - r: "10", - cx: "10", - cy: "10", - fill: "black", - }, - key: 2, - svg: true, - }, - [] - ), - api_element( - "circle", - { - attrs: { - id: api_scoped_id($cmp.redId), - r: "10", - cx: "14", - cy: "14", - fill: "red", - }, - key: 3, - svg: true, - }, - [] - ), - ] - ), + api_element("svg", stc0, [ + api_element("defs", stc1, [ api_element( - "use", + "circle", { attrs: { - href: sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "href", - api_scoped_frag_id($cmp.blackUrl) - ), + id: api_scoped_id($cmp.blackId), + r: "10", + cx: "10", + cy: "10", + fill: "black", }, - key: 4, + key: 2, svg: true, }, - [] + stc2 ), api_element( - "use", + "circle", { attrs: { - "xlink:href": sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "xlink:href", - api_scoped_frag_id($cmp.redUrl) - ), + id: api_scoped_id($cmp.redId), + r: "10", + cx: "14", + cy: "14", + fill: "red", }, - key: 5, + key: 3, svg: true, }, - [] + stc2 ), - ] - ), + ]), + api_element( + "use", + { + attrs: { + href: sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "href", + api_scoped_frag_id($cmp.blackUrl) + ), + }, + key: 4, + svg: true, + }, + stc2 + ), + api_element( + "use", + { + attrs: { + "xlink:href": sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "xlink:href", + api_scoped_frag_id($cmp.redUrl) + ), + }, + key: 5, + svg: true, + }, + stc2 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-static/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-static/expected.js index c0d93208d0..7d5f244ee3 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-static/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/scoped-id-static/expected.js @@ -1,92 +1,87 @@ import { registerTemplate, sanitizeAttribute } from "lwc"; +const stc0 = { + attrs: { + width: "100px", + height: "100px", + viewport: "0 0 100 100", + }, + key: 0, + svg: true, +}; +const stc1 = { + key: 1, + svg: true, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { gid: api_scoped_id, h: api_element, fid: api_scoped_frag_id } = $api; return [ - api_element( - "svg", - { - attrs: { - width: "100px", - height: "100px", - viewport: "0 0 100 100", - }, - key: 0, - svg: true, - }, - [ - api_element( - "defs", - { - key: 1, - svg: true, - }, - [ - api_element( - "circle", - { - attrs: { - id: api_scoped_id("black"), - r: "10", - cx: "10", - cy: "10", - fill: "black", - }, - key: 2, - svg: true, - }, - [] - ), - api_element( - "circle", - { - attrs: { - id: api_scoped_id("red"), - r: "10", - cx: "14", - cy: "14", - fill: "red", - }, - key: 3, - svg: true, - }, - [] - ), - ] - ), + api_element("svg", stc0, [ + api_element("defs", stc1, [ api_element( - "use", + "circle", { attrs: { - href: sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "href", - api_scoped_frag_id("#black") - ), + id: api_scoped_id("black"), + r: "10", + cx: "10", + cy: "10", + fill: "black", }, - key: 4, + key: 2, svg: true, }, - [] + stc2 ), api_element( - "use", + "circle", { attrs: { - "xlink:href": sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "xlink:href", - api_scoped_frag_id("#red") - ), + id: api_scoped_id("red"), + r: "10", + cx: "14", + cy: "14", + fill: "red", }, - key: 5, + key: 3, svg: true, }, - [] + stc2 ), - ] - ), + ]), + api_element( + "use", + { + attrs: { + href: sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "href", + api_scoped_frag_id("#black") + ), + }, + key: 4, + svg: true, + }, + stc2 + ), + api_element( + "use", + { + attrs: { + "xlink:href": sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "xlink:href", + api_scoped_frag_id("#red") + ), + }, + key: 5, + svg: true, + }, + stc2 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/simple-svg/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/simple-svg/expected.js index cf40c306ac..e53ec38504 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/simple-svg/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/simple-svg/expected.js @@ -1,65 +1,54 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + version: "1.1", + baseProfile: "full", + width: "300", + height: "200", + xmlns: "http://www.w3.org/2000/svg", + }, + key: 0, + svg: true, +}; +const stc1 = { + attrs: { + width: "100%", + height: "100%", + fill: "red", + }, + key: 1, + svg: true, +}; +const stc2 = []; +const stc3 = { + attrs: { + cx: "150", + cy: "100", + r: "80", + fill: "green", + }, + key: 2, + svg: true, +}; +const stc4 = { + attrs: { + x: "150", + y: "125", + "font-size": "60", + "text-anchor": "middle", + fill: "white", + }, + key: 3, + svg: true, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element, t: api_text } = $api; return [ - api_element( - "svg", - { - attrs: { - version: "1.1", - baseProfile: "full", - width: "300", - height: "200", - xmlns: "http://www.w3.org/2000/svg", - }, - key: 0, - svg: true, - }, - [ - api_element( - "rect", - { - attrs: { - width: "100%", - height: "100%", - fill: "red", - }, - key: 1, - svg: true, - }, - [] - ), - api_element( - "circle", - { - attrs: { - cx: "150", - cy: "100", - r: "80", - fill: "green", - }, - key: 2, - svg: true, - }, - [] - ), - api_element( - "text", - { - attrs: { - x: "150", - y: "125", - "font-size": "60", - "text-anchor": "middle", - fill: "white", - }, - key: 3, - svg: true, - }, - [api_text("SVG")] - ), - ] - ), + api_element("svg", stc0, [ + api_element("rect", stc1, stc2), + api_element("circle", stc3, stc2), + api_element("text", stc4, [api_text("SVG")]), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-image/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-image/expected.js index 454fc46634..f0a4a50a96 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-image/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-image/expected.js @@ -1,36 +1,27 @@ import { registerTemplate } from "lwc"; +const stc0 = { + attrs: { + width: "200", + height: "200", + }, + key: 0, + svg: true, +}; +const stc1 = { + attrs: { + "xlink:href": "/foo.png", + x: "1", + y: "2", + height: "200", + width: "200", + }, + key: 1, + svg: true, +}; +const stc2 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "svg", - { - attrs: { - width: "200", - height: "200", - }, - key: 0, - svg: true, - }, - [ - api_element( - "image", - { - attrs: { - "xlink:href": "/foo.png", - x: "1", - y: "2", - height: "200", - width: "200", - }, - key: 1, - svg: true, - }, - [] - ), - ] - ), - ]; + return [api_element("svg", stc0, [api_element("image", stc1, stc2)])]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-svg/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-svg/expected.js index d49e21c8a5..61e13def37 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-svg/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/valid-svg/expected.js @@ -1,184 +1,119 @@ import { registerTemplate } from "lwc"; +const stc0 = { + key: 0, + svg: true, +}; +const stc1 = { + key: 1, + svg: true, +}; +const stc2 = []; +const stc3 = { + key: 2, + svg: true, +}; +const stc4 = { + key: 3, + svg: true, +}; +const stc5 = { + key: 4, + svg: true, +}; +const stc6 = { + key: 5, + svg: true, +}; +const stc7 = { + key: 6, + svg: true, +}; +const stc8 = { + key: 7, + svg: true, +}; +const stc9 = { + key: 8, + svg: true, +}; +const stc10 = { + key: 9, + svg: true, +}; +const stc11 = { + key: 10, + svg: true, +}; +const stc12 = { + key: 11, + svg: true, +}; +const stc13 = { + key: 12, + svg: true, +}; +const stc14 = { + key: 13, + svg: true, +}; +const stc15 = { + key: 14, + svg: true, +}; +const stc16 = { + key: 15, + svg: true, +}; +const stc17 = { + key: 16, + svg: true, +}; +const stc18 = { + key: 17, + svg: true, +}; +const stc19 = { + key: 18, + svg: true, +}; +const stc20 = { + key: 19, + svg: true, +}; +const stc21 = { + key: 20, + svg: true, +}; +const stc22 = { + key: 21, + svg: true, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "svg", - { - key: 0, - svg: true, - }, - [ - api_element( - "a", - { - key: 1, - svg: true, - }, - [] - ), - api_element( - "circle", - { - key: 2, - svg: true, - }, - [] - ), - api_element( - "defs", - { - key: 3, - svg: true, - }, - [] - ), - api_element( - "desc", - { - key: 4, - svg: true, - }, - [] - ), - api_element( - "ellipse", - { - key: 5, - svg: true, - }, - [] - ), - api_element( - "filter", - { - key: 6, - svg: true, - }, - [] - ), - api_element( - "g", - { - key: 7, - svg: true, - }, - [] - ), - api_element( - "line", - { - key: 8, - svg: true, - }, - [] - ), - api_element( - "marker", - { - key: 9, - svg: true, - }, - [] - ), - api_element( - "mask", - { - key: 10, - svg: true, - }, - [] - ), - api_element( - "path", - { - key: 11, - svg: true, - }, - [] - ), - api_element( - "pattern", - { - key: 12, - svg: true, - }, - [] - ), - api_element( - "polygon", - { - key: 13, - svg: true, - }, - [] - ), - api_element( - "polyline", - { - key: 14, - svg: true, - }, - [] - ), - api_element( - "rect", - { - key: 15, - svg: true, - }, - [] - ), - api_element( - "stop", - { - key: 16, - svg: true, - }, - [] - ), - api_element( - "symbol", - { - key: 17, - svg: true, - }, - [] - ), - api_element( - "text", - { - key: 18, - svg: true, - }, - [] - ), - api_element( - "title", - { - key: 19, - svg: true, - }, - [] - ), - api_element( - "tspan", - { - key: 20, - svg: true, - }, - [] - ), - api_element( - "use", - { - key: 21, - svg: true, - }, - [] - ), - ] - ), + api_element("svg", stc0, [ + api_element("a", stc1, stc2), + api_element("circle", stc3, stc2), + api_element("defs", stc4, stc2), + api_element("desc", stc5, stc2), + api_element("ellipse", stc6, stc2), + api_element("filter", stc7, stc2), + api_element("g", stc8, stc2), + api_element("line", stc9, stc2), + api_element("marker", stc10, stc2), + api_element("mask", stc11, stc2), + api_element("path", stc12, stc2), + api_element("pattern", stc13, stc2), + api_element("polygon", stc14, stc2), + api_element("polyline", stc15, stc2), + api_element("rect", stc16, stc2), + api_element("stop", stc17, stc2), + api_element("symbol", stc18, stc2), + api_element("text", stc19, stc2), + api_element("title", stc20, stc2), + api_element("tspan", stc21, stc2), + api_element("use", stc22, stc2), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-expression-value/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-expression-value/expected.js index 4b8c3246c1..56679b19d8 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-expression-value/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-expression-value/expected.js @@ -1,39 +1,37 @@ import { registerTemplate, sanitizeAttribute } from "lwc"; +const stc0 = { + classMap: { + "slds-icon": true, + }, + attrs: { + "aria-hidden": "true", + title: "when needed", + }, + key: 0, + svg: true, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { fid: api_scoped_frag_id, h: api_element } = $api; return [ - api_element( - "svg", - { - classMap: { - "slds-icon": true, - }, - attrs: { - "aria-hidden": "true", - title: "when needed", - }, - key: 0, - svg: true, - }, - [ - api_element( - "use", - { - attrs: { - "xlink:href": sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "xlink:href", - api_scoped_frag_id($cmp.getXLink) - ), - }, - key: 1, - svg: true, + api_element("svg", stc0, [ + api_element( + "use", + { + attrs: { + "xlink:href": sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "xlink:href", + api_scoped_frag_id($cmp.getXLink) + ), }, - [] - ), - ] - ), + key: 1, + svg: true, + }, + stc1 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-literal-value/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-literal-value/expected.js index 074d3ba380..b20751fed8 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-literal-value/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/xlink-with-literal-value/expected.js @@ -1,39 +1,37 @@ import { registerTemplate, sanitizeAttribute } from "lwc"; +const stc0 = { + classMap: { + "slds-icon": true, + }, + attrs: { + "aria-hidden": "true", + title: "when needed", + }, + key: 0, + svg: true, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "svg", - { - classMap: { - "slds-icon": true, - }, - attrs: { - "aria-hidden": "true", - title: "when needed", - }, - key: 0, - svg: true, - }, - [ - api_element( - "use", - { - attrs: { - "xlink:href": sanitizeAttribute( - "use", - "http://www.w3.org/2000/svg", - "xlink:href", - "/assets/icons/standard-sprite/svg/symbols.svg#case" - ), - }, - key: 1, - svg: true, + api_element("svg", stc0, [ + api_element( + "use", + { + attrs: { + "xlink:href": sanitizeAttribute( + "use", + "http://www.w3.org/2000/svg", + "xlink:href", + "/assets/icons/standard-sprite/svg/symbols.svg#case" + ), }, - [] - ), - ] - ), + key: 1, + svg: true, + }, + stc1 + ), + ]), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/codegen/formatters/function.ts b/packages/@lwc/template-compiler/src/codegen/formatters/function.ts index 5687107b96..1a11d08fd7 100644 --- a/packages/@lwc/template-compiler/src/codegen/formatters/function.ts +++ b/packages/@lwc/template-compiler/src/codegen/formatters/function.ts @@ -10,6 +10,7 @@ import { TEMPLATE_FUNCTION_NAME, TEMPLATE_MODULES_PARAMETER } from '../../shared import CodeGen from '../codegen'; import { identifierFromComponentName, generateTemplateMetadata } from '../helpers'; +import { optimizeStaticExpressions } from '../optimize'; /** * Generate a function body AST from a template ESTree AST. This function can then be instantiated @@ -46,11 +47,13 @@ export function format(templateFn: t.FunctionDeclaration, codeGen: CodeGen): t.P ]); }); + const optimizedTemplateDeclarations = optimizeStaticExpressions(templateFn); + const metadata = generateTemplateMetadata(codeGen); return t.program([ ...lookups, - templateFn, + ...optimizedTemplateDeclarations, ...metadata, t.returnStatement(t.identifier(TEMPLATE_FUNCTION_NAME)), ]); diff --git a/packages/@lwc/template-compiler/src/codegen/formatters/module.ts b/packages/@lwc/template-compiler/src/codegen/formatters/module.ts index c3a5595260..22c5b71d6b 100644 --- a/packages/@lwc/template-compiler/src/codegen/formatters/module.ts +++ b/packages/@lwc/template-compiler/src/codegen/formatters/module.ts @@ -14,6 +14,7 @@ import { import CodeGen from '../codegen'; import { identifierFromComponentName, generateTemplateMetadata } from '../helpers'; +import { optimizeStaticExpressions } from '../optimize'; function generateComponentImports(codeGen: CodeGen): t.ImportDeclaration[] { return Array.from(codeGen.referencedComponents).map((name) => { @@ -62,8 +63,10 @@ export function format(templateFn: t.FunctionDeclaration, codeGen: CodeGen): t.P const metadata = generateTemplateMetadata(codeGen); + const optimizedTemplateDeclarations = optimizeStaticExpressions(templateFn); + const templateBody = [ - templateFn, + ...optimizedTemplateDeclarations, t.exportDefaultDeclaration( t.callExpression(t.identifier(SECURE_REGISTER_TEMPLATE_METHOD_NAME), [ t.identifier(TEMPLATE_FUNCTION_NAME), diff --git a/packages/@lwc/template-compiler/src/codegen/optimize.ts b/packages/@lwc/template-compiler/src/codegen/optimize.ts new file mode 100644 index 0000000000..cbb7f16c4c --- /dev/null +++ b/packages/@lwc/template-compiler/src/codegen/optimize.ts @@ -0,0 +1,105 @@ +import * as astring from 'astring'; +import { walk } from 'estree-walker'; +import * as t from '../shared/estree'; + +/** + * Given a template function, extract all static objects/arrays (e.g. `{ key : 1 }`) + * and return them as a list of `const` declarations. Also return the modified function + * that is now referencing those declarations. + * + * Example input: + * + * ``` + * function tmpl() { + * return { + * foo: dynamic(), + * bar: { static: true }, + * baz: { really: { static: ['yep', 'totally', 'static' ] } } + * }; + * } + * ``` + * + * Example output: + * + * ``` + * const stc0 = { static: true }; + * const stc1 = { really: { static: ['yep', 'totally', 'static' ] } }; + * function tmpl() { + * return { + * foo: dynamic(), + * bar: stc0, + * baz: stc1 + * }; + * } + * ``` + */ +export function optimizeStaticExpressions( + templateFn: t.FunctionDeclaration +): Array { + const result: Array = []; + const keysToVariableNames = new Map(); + + let identifierCount = 0; + + // Return true if this node is an object/array that is fully static + function isStaticObjectOrArray(node: t.BaseNode): boolean { + if (t.isObjectExpression(node)) { + return node.properties.every((prop) => { + return ( + t.isProperty(prop) && + !prop.computed && + !prop.method && + !prop.shorthand && + (t.isLiteral(prop.value) || isStaticObjectOrArray(prop.value)) + ); + }); + } else if (t.isArrayExpression(node)) { + return node.elements.every((element) => { + return ( + element !== null && + t.isExpression(element) && + (t.isLiteral(element) || isStaticObjectOrArray(element)) + ); + }); + } + return false; + } + + function extractStaticVariable(node: t.BaseNode): t.BaseNode { + // This key generation can probably be improved using a hash code, but stringification is + // simplest for finding a unique identifier for an object/array expression + const key = astring.generate(node); + + // Check for duplicates to avoid re-declaring the same object/array multiple times + // Especially for the empty array (`[]`), which is very common in templates + if (!keysToVariableNames.has(key)) { + const variableName = `stc${identifierCount++}`; + // e.g. `const stc0 = { /* original object */ }; + const declaration = t.variableDeclaration('const', [ + t.variableDeclarator( + t.identifier(variableName), + node as t.ArrayExpression | t.ObjectExpression + ), + ]); + result.push(declaration); + keysToVariableNames.set(key, variableName); + } + + return t.identifier(keysToVariableNames.get(key)); + } + + walk(templateFn, { + enter(node) { + // For deeply-nested static object, we only want to extract the top-level node + if (isStaticObjectOrArray(node)) { + const newNode = extractStaticVariable(node); + this.replace(newNode); + this.skip(); + } + }, + }); + + result.push(templateFn); + + return result; +} diff --git a/packages/@lwc/template-compiler/src/shared/estree.ts b/packages/@lwc/template-compiler/src/shared/estree.ts index da822ca9f3..06c5f967b6 100644 --- a/packages/@lwc/template-compiler/src/shared/estree.ts +++ b/packages/@lwc/template-compiler/src/shared/estree.ts @@ -18,6 +18,18 @@ export function isArrayExpression(node: t.BaseNode): node is t.ArrayExpression { return node.type === 'ArrayExpression'; } +export function isObjectExpression(node: t.BaseNode): node is t.ObjectExpression { + return node.type === 'ObjectExpression'; +} + +export function isExpression(node: t.BaseNode): node is t.Expression { + return node.type === 'Expression'; +} + +export function isProperty(node: t.BaseNode): node is t.Property { + return node.type === 'Property'; +} + export function identifier(name: string, config?: Partial): t.Identifier { return { type: 'Identifier', From 9e9b3dfc4f7f911b4edf7b40df63bdb6c2ec7bef Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Wed, 1 Dec 2021 16:10:09 -0800 Subject: [PATCH 02/15] fix: fix license header --- packages/@lwc/template-compiler/src/codegen/optimize.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/@lwc/template-compiler/src/codegen/optimize.ts b/packages/@lwc/template-compiler/src/codegen/optimize.ts index cbb7f16c4c..7f98b8e58a 100644 --- a/packages/@lwc/template-compiler/src/codegen/optimize.ts +++ b/packages/@lwc/template-compiler/src/codegen/optimize.ts @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2018, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ import * as astring from 'astring'; import { walk } from 'estree-walker'; import * as t from '../shared/estree'; From 7bab41dc4db552bf7d64c690eaaeaa5248a33cad Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 09:06:42 -0800 Subject: [PATCH 03/15] fix: use map size --- packages/@lwc/template-compiler/src/codegen/optimize.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/@lwc/template-compiler/src/codegen/optimize.ts b/packages/@lwc/template-compiler/src/codegen/optimize.ts index 7f98b8e58a..8ec5394552 100644 --- a/packages/@lwc/template-compiler/src/codegen/optimize.ts +++ b/packages/@lwc/template-compiler/src/codegen/optimize.ts @@ -45,8 +45,6 @@ export function optimizeStaticExpressions( const result: Array = []; const keysToVariableNames = new Map(); - let identifierCount = 0; - // Return true if this node is an object/array that is fully static function isStaticObjectOrArray(node: t.BaseNode): boolean { if (t.isObjectExpression(node)) { @@ -79,7 +77,7 @@ export function optimizeStaticExpressions( // Check for duplicates to avoid re-declaring the same object/array multiple times // Especially for the empty array (`[]`), which is very common in templates if (!keysToVariableNames.has(key)) { - const variableName = `stc${identifierCount++}`; + const variableName = `stc${keysToVariableNames.size}`; // e.g. `const stc0 = { /* original object */ }; const declaration = t.variableDeclaration('const', [ t.variableDeclarator( From 0158233b61aa1fa8058905b250b2d7ecc76cdb3d Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 09:07:25 -0800 Subject: [PATCH 04/15] fix: update packages/@lwc/template-compiler/src/codegen/optimize.ts Co-authored-by: Pierre-Marie Dartus --- packages/@lwc/template-compiler/src/codegen/optimize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@lwc/template-compiler/src/codegen/optimize.ts b/packages/@lwc/template-compiler/src/codegen/optimize.ts index 8ec5394552..2c930be98a 100644 --- a/packages/@lwc/template-compiler/src/codegen/optimize.ts +++ b/packages/@lwc/template-compiler/src/codegen/optimize.ts @@ -69,7 +69,7 @@ export function optimizeStaticExpressions( return false; } - function extractStaticVariable(node: t.BaseNode): t.BaseNode { + function extractStaticVariable(node: t.Expression): t.Identifier { // This key generation can probably be improved using a hash code, but stringification is // simplest for finding a unique identifier for an object/array expression const key = astring.generate(node); From 6e4524f4f39e5b373dee1e9003366592b64baf1d Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 09:11:59 -0800 Subject: [PATCH 05/15] fix: remove t.isExpression check --- .../fixtures/attributes/style/expected.js | 109 +++++++----------- .../fixtures/base/style-important/expected.js | 25 ++-- .../fixtures/base/style-static/expected.js | 42 +++---- .../single-attribute/expected.js | 2 +- .../fixtures/svg/linear-gradient/expected.js | 49 +++----- .../template-compiler/src/codegen/optimize.ts | 6 +- .../template-compiler/src/shared/estree.ts | 4 - 7 files changed, 93 insertions(+), 144 deletions(-) diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js index 8586ec1fef..1d865a0b92 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/attributes/style/expected.js @@ -1,72 +1,51 @@ import { registerTemplate } from "lwc"; -const stc0 = []; +const stc0 = { + styleDecls: [["color", "blue", false]], + key: 0, +}; +const stc1 = []; +const stc2 = { + styleDecls: [["color", "blue", false]], + key: 1, +}; +const stc3 = { + styleDecls: [["color", "blue", false]], + key: 2, +}; +const stc4 = { + styleDecls: [["box-shadow", "10px 5px 5px black", false]], + key: 3, +}; +const stc5 = { + styleDecls: [ + ["font-size", "12px", false], + ["background", "blue", false], + ["color", "red", false], + ], + key: 4, +}; +const stc6 = { + styleDecls: [ + ["font-size", "12px", false], + ["background", "blue", false], + ["color", "red", false], + ], + key: 5, +}; +const stc7 = { + styleDecls: [["background-color", "rgba(255,0,0,0.3)", false]], + key: 6, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "div", - { - styleDecls: [["color", "blue", false]], - key: 0, - }, - stc0 - ), - api_element( - "div", - { - styleDecls: [["color", "blue", false]], - key: 1, - }, - stc0 - ), - api_element( - "div", - { - styleDecls: [["color", "blue", false]], - key: 2, - }, - stc0 - ), - api_element( - "div", - { - styleDecls: [["box-shadow", "10px 5px 5px black", false]], - key: 3, - }, - stc0 - ), - api_element( - "div", - { - styleDecls: [ - ["font-size", "12px", false], - ["background", "blue", false], - ["color", "red", false], - ], - key: 4, - }, - stc0 - ), - api_element( - "div", - { - styleDecls: [ - ["font-size", "12px", false], - ["background", "blue", false], - ["color", "red", false], - ], - key: 5, - }, - stc0 - ), - api_element( - "div", - { - styleDecls: [["background-color", "rgba(255,0,0,0.3)", false]], - key: 6, - }, - stc0 - ), + api_element("div", stc0, stc1), + api_element("div", stc2, stc1), + api_element("div", stc3, stc1), + api_element("div", stc4, stc1), + api_element("div", stc5, stc1), + api_element("div", stc6, stc1), + api_element("div", stc7, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js index dbd415fa45..ab0d4d165b 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-important/expected.js @@ -1,21 +1,16 @@ import { registerTemplate } from "lwc"; -const stc0 = []; +const stc0 = { + styleDecls: [ + ["background", "blue", true], + ["color", "red", false], + ["opacity", "0.5", true], + ], + key: 0, +}; +const stc1 = []; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; - return [ - api_element( - "div", - { - styleDecls: [ - ["background", "blue", true], - ["color", "red", false], - ["opacity", "0.5", true], - ], - key: 0, - }, - stc0 - ), - ]; + return [api_element("div", stc0, stc1)]; } export default registerTemplate(tmpl); tmpl.stylesheets = []; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js index b440d169db..e2a166b549 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/base/style-static/expected.js @@ -1,31 +1,25 @@ import { registerTemplate } from "lwc"; -const stc0 = []; +const stc0 = { + styleDecls: [ + ["font-size", "12px", false], + ["color", "red", false], + ["margin", "10px 5px 10px", false], + ], + key: 0, +}; +const stc1 = []; +const stc2 = { + styleDecls: [ + ["--my-color", "blue", false], + ["color", "var(--my-color)", false], + ], + key: 1, +}; function tmpl($api, $cmp, $slotset, $ctx) { const { h: api_element } = $api; return [ - api_element( - "section", - { - styleDecls: [ - ["font-size", "12px", false], - ["color", "red", false], - ["margin", "10px 5px 10px", false], - ], - key: 0, - }, - stc0 - ), - api_element( - "section", - { - styleDecls: [ - ["--my-color", "blue", false], - ["color", "var(--my-color)", false], - ], - key: 1, - }, - stc0 - ), + api_element("section", stc0, stc1), + api_element("section", stc2, stc1), ]; } export default registerTemplate(tmpl); diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js index f492d00435..5f99b1e8e2 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js @@ -1,5 +1,5 @@ import { registerTemplate } from "lwc"; -const stc0 = []; +const stc0 = [[]]; function tmpl($api, $cmp, $slotset, $ctx) { const {} = $api; return stc0; diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js index 764ea0edb5..ca9f694bb1 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/svg/linear-gradient/expected.js @@ -12,11 +12,27 @@ const stc1 = { svg: true, }; const stc2 = { - offset: "0%", + styleDecls: [ + ["stop-color", "rgb(255,255,0)", false], + ["stop-opacity", "1", false], + ], + attrs: { + offset: "0%", + }, + key: 3, + svg: true, }; const stc3 = []; const stc4 = { - offset: "100%", + styleDecls: [ + ["stop-color", "rgb(255,0,0)", false], + ["stop-opacity", "1", false], + ], + attrs: { + offset: "100%", + }, + key: 4, + svg: true, }; const stc5 = { attrs: { @@ -47,34 +63,7 @@ function tmpl($api, $cmp, $slotset, $ctx) { key: 2, svg: true, }, - [ - api_element( - "stop", - { - styleDecls: [ - ["stop-color", "rgb(255,255,0)", false], - ["stop-opacity", "1", false], - ], - attrs: stc2, - key: 3, - svg: true, - }, - stc3 - ), - api_element( - "stop", - { - styleDecls: [ - ["stop-color", "rgb(255,0,0)", false], - ["stop-opacity", "1", false], - ], - attrs: stc4, - key: 4, - svg: true, - }, - stc3 - ), - ] + [api_element("stop", stc2, stc3), api_element("stop", stc4, stc3)] ), ]), api_element("ellipse", stc5, stc3), diff --git a/packages/@lwc/template-compiler/src/codegen/optimize.ts b/packages/@lwc/template-compiler/src/codegen/optimize.ts index 2c930be98a..7aea7fe579 100644 --- a/packages/@lwc/template-compiler/src/codegen/optimize.ts +++ b/packages/@lwc/template-compiler/src/codegen/optimize.ts @@ -59,11 +59,7 @@ export function optimizeStaticExpressions( }); } else if (t.isArrayExpression(node)) { return node.elements.every((element) => { - return ( - element !== null && - t.isExpression(element) && - (t.isLiteral(element) || isStaticObjectOrArray(element)) - ); + return element !== null && (t.isLiteral(element) || isStaticObjectOrArray(element)); }); } return false; diff --git a/packages/@lwc/template-compiler/src/shared/estree.ts b/packages/@lwc/template-compiler/src/shared/estree.ts index 06c5f967b6..7631185057 100644 --- a/packages/@lwc/template-compiler/src/shared/estree.ts +++ b/packages/@lwc/template-compiler/src/shared/estree.ts @@ -22,10 +22,6 @@ export function isObjectExpression(node: t.BaseNode): node is t.ObjectExpression return node.type === 'ObjectExpression'; } -export function isExpression(node: t.BaseNode): node is t.Expression { - return node.type === 'Expression'; -} - export function isProperty(node: t.BaseNode): node is t.Property { return node.type === 'Property'; } From 12683ae01b57927a8c3af3c2fbf7ebd6ed46cc26 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 09:15:50 -0800 Subject: [PATCH 06/15] fix: fix typescript --- packages/@lwc/template-compiler/src/codegen/optimize.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@lwc/template-compiler/src/codegen/optimize.ts b/packages/@lwc/template-compiler/src/codegen/optimize.ts index 7aea7fe579..f1b3e3f625 100644 --- a/packages/@lwc/template-compiler/src/codegen/optimize.ts +++ b/packages/@lwc/template-compiler/src/codegen/optimize.ts @@ -46,7 +46,9 @@ export function optimizeStaticExpressions( const keysToVariableNames = new Map(); // Return true if this node is an object/array that is fully static - function isStaticObjectOrArray(node: t.BaseNode): boolean { + function isStaticObjectOrArray( + node: t.BaseNode + ): node is t.ObjectExpression | t.ArrayExpression { if (t.isObjectExpression(node)) { return node.properties.every((prop) => { return ( From 1fa426280dc7601bcac9b275777f285dded64f9b Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 11:23:00 -0800 Subject: [PATCH 07/15] fix: fix vnode shared-object issue --- packages/@lwc/engine-core/src/framework/api.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/@lwc/engine-core/src/framework/api.ts b/packages/@lwc/engine-core/src/framework/api.ts index 8073283d4d..4d67c5ac5e 100644 --- a/packages/@lwc/engine-core/src/framework/api.ts +++ b/packages/@lwc/engine-core/src/framework/api.ts @@ -791,8 +791,11 @@ function dc( // the new vnode key is a mix of idx and compiler key, this is required by the diffing algo // to identify different constructors as vnodes with different keys to avoid reusing the // element used for previous constructors. - data.key = `dc:${idx}:${data.key}`; - return c(sel, Ctor, data, children); + // Because this `data` object may be shared across vnodes due to optimizations (hoisting), + // we need to create a shallow clone here. + const newData = { ...data }; + newData.key = `dc:${idx}:${data.key}`; + return c(sel, Ctor, newData, children); } /** From 29fdd8e44edbfc79cf4a0fe89d98fa5ebfadfdf7 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 11:40:00 -0800 Subject: [PATCH 08/15] fix: add typescript readonly guard --- packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts | 3 ++- packages/@lwc/engine-core/src/framework/api.ts | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts index 242d47d259..4eee0596ec 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts @@ -75,7 +75,8 @@ export interface VNodeData { } export interface VElementData extends VNodeData { - key: Key; + // readonly because VElementData may be shared across VNodes due to hoisting optimizations + readonly key: Key; } export interface Hooks { diff --git a/packages/@lwc/engine-core/src/framework/api.ts b/packages/@lwc/engine-core/src/framework/api.ts index 4d67c5ac5e..00d7fcc32c 100644 --- a/packages/@lwc/engine-core/src/framework/api.ts +++ b/packages/@lwc/engine-core/src/framework/api.ts @@ -791,11 +791,8 @@ function dc( // the new vnode key is a mix of idx and compiler key, this is required by the diffing algo // to identify different constructors as vnodes with different keys to avoid reusing the // element used for previous constructors. - // Because this `data` object may be shared across vnodes due to optimizations (hoisting), - // we need to create a shallow clone here. - const newData = { ...data }; - newData.key = `dc:${idx}:${data.key}`; - return c(sel, Ctor, newData, children); + data = { key: `dc:${idx}:${data.key}` }; + return c(sel, Ctor, data, children); } /** From 1e1d73235ff0a92280664b716cc6ca537c232e10 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 12:27:00 -0800 Subject: [PATCH 09/15] fix: fix hydration, add more typescript guards --- .../src/3rdparty/snabbdom/types.ts | 19 +++++++++---------- .../@lwc/engine-core/src/framework/api.ts | 6 ++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts index 4eee0596ec..99e6042de7 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts @@ -63,19 +63,18 @@ export interface VComment extends VNode { } export interface VNodeData { - props?: Record; - attrs?: Record; - className?: string; - style?: string; - classMap?: Record; - styleDecls?: Array<[string, string, boolean]>; - context?: Record>; - on?: Record; - svg?: boolean; + readonly props?: Record; + readonly attrs?: Record; + readonly className?: string; + readonly style?: string; + readonly classMap?: Record; + readonly styleDecls?: Array<[string, string, boolean]>; + readonly context?: Record>; + readonly on?: Record; + readonly svg?: boolean; } export interface VElementData extends VNodeData { - // readonly because VElementData may be shared across VNodes due to hoisting optimizations readonly key: Key; } diff --git a/packages/@lwc/engine-core/src/framework/api.ts b/packages/@lwc/engine-core/src/framework/api.ts index 00d7fcc32c..c941fdc8e5 100644 --- a/packages/@lwc/engine-core/src/framework/api.ts +++ b/packages/@lwc/engine-core/src/framework/api.ts @@ -791,8 +791,10 @@ function dc( // the new vnode key is a mix of idx and compiler key, this is required by the diffing algo // to identify different constructors as vnodes with different keys to avoid reusing the // element used for previous constructors. - data = { key: `dc:${idx}:${data.key}` }; - return c(sel, Ctor, data, children); + // Shallow clone is necessary here becuase VElementData may be shared across VNodes due to + // hoisting optimization. + const newData = { ...data, key: `dc:${idx}:${data.key}` }; + return c(sel, Ctor, newData, children); } /** From 35e67ce21c3aa18ac40a68d53a82eb6b514325c1 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 13:29:37 -0800 Subject: [PATCH 10/15] fix: mark more props as readonly --- .../@lwc/engine-core/src/3rdparty/snabbdom/types.ts | 12 +++++++----- packages/@lwc/engine-core/src/framework/api.ts | 10 +++++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts index 99e6042de7..7f1561c57d 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts @@ -63,13 +63,15 @@ export interface VComment extends VNode { } export interface VNodeData { - readonly props?: Record; - readonly attrs?: Record; + // All props are readonly because VElementData may be shared across VNodes + // due to hoisting optimizations + readonly props?: Readonly>; + readonly attrs?: Readonly>; readonly className?: string; readonly style?: string; - readonly classMap?: Record; - readonly styleDecls?: Array<[string, string, boolean]>; - readonly context?: Record>; + readonly classMap?: Readonly>; + readonly styleDecls?: Readonly>; + readonly context?: Readonly>>; readonly on?: Record; readonly svg?: boolean; } diff --git a/packages/@lwc/engine-core/src/framework/api.ts b/packages/@lwc/engine-core/src/framework/api.ts index c941fdc8e5..3d23847bef 100644 --- a/packages/@lwc/engine-core/src/framework/api.ts +++ b/packages/@lwc/engine-core/src/framework/api.ts @@ -203,8 +203,16 @@ const ElementHook: Hooks = { // remove the innerHTML from props so it reuses the existing dom elements. const { props } = vnode.data; if (!isUndefined(props) && !isUndefined(props.innerHTML)) { + // Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization if (elm.innerHTML === props.innerHTML) { - delete props.innerHTML; + const newData = { + ...vnode.data, + props: { + ...vnode.data.props, + innerHTML: undefined, + }, + }; + vnode.data = newData; } else { logWarn( `Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, From 409cdee67abe0017479d0bbc9e3e62cea800a98b Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 13:31:16 -0800 Subject: [PATCH 11/15] fix: mark another prop as readonly --- packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts index 7f1561c57d..d2c45b7602 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts @@ -72,7 +72,7 @@ export interface VNodeData { readonly classMap?: Readonly>; readonly styleDecls?: Readonly>; readonly context?: Readonly>>; - readonly on?: Record; + readonly on?: Readonly>; readonly svg?: boolean; } From c48f17eedd3cd13ce1c9962c10a96e8c3d34e107 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 2 Dec 2021 14:04:03 -0800 Subject: [PATCH 12/15] fix: actually fix innerHTML --- packages/@lwc/engine-core/src/framework/api.ts | 12 ++++-------- packages/@lwc/engine-core/src/framework/utils.ts | 11 +++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/@lwc/engine-core/src/framework/api.ts b/packages/@lwc/engine-core/src/framework/api.ts index 3d23847bef..024fcd3822 100644 --- a/packages/@lwc/engine-core/src/framework/api.ts +++ b/packages/@lwc/engine-core/src/framework/api.ts @@ -26,7 +26,7 @@ import { import { logError, logWarn } from '../shared/logger'; import { invokeEventListener } from './invoker'; import { getVMBeingRendered } from './template'; -import { EmptyArray, EmptyObject } from './utils'; +import { cloneAndOmitKey, EmptyArray, EmptyObject } from './utils'; import { appendVM, getAssociatedVMIfPresent, @@ -203,16 +203,12 @@ const ElementHook: Hooks = { // remove the innerHTML from props so it reuses the existing dom elements. const { props } = vnode.data; if (!isUndefined(props) && !isUndefined(props.innerHTML)) { - // Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization if (elm.innerHTML === props.innerHTML) { - const newData = { + // Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization + vnode.data = { ...vnode.data, - props: { - ...vnode.data.props, - innerHTML: undefined, - }, + props: cloneAndOmitKey(props, 'innerHTML'), }; - vnode.data = newData; } else { logWarn( `Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, diff --git a/packages/@lwc/engine-core/src/framework/utils.ts b/packages/@lwc/engine-core/src/framework/utils.ts index c70757139f..6f6861c373 100644 --- a/packages/@lwc/engine-core/src/framework/utils.ts +++ b/packages/@lwc/engine-core/src/framework/utils.ts @@ -74,3 +74,14 @@ export function parseStyleText(cssText: string): { [name: string]: string } { return styleMap; } + +// Make a shallow copy of an object but omit the given key +export function cloneAndOmitKey(object: { [key: string]: any }, keyToOmit: string) { + const result: { [key: string]: any } = {}; + for (const key of Object.keys(object)) { + if (key !== keyToOmit) { + result[key] = object[key]; + } + } + return result; +} From c6208193b8661d6d15fd2bbf64fb003e79abdc0a Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Mon, 6 Dec 2021 13:12:05 -0800 Subject: [PATCH 13/15] fix: mark children as read-only --- .../src/3rdparty/snabbdom/snabbdom.ts | 28 +++++++++++++++---- .../src/3rdparty/snabbdom/types.ts | 10 +++---- .../@lwc/engine-core/src/framework/api.ts | 10 +++---- .../@lwc/engine-core/src/framework/hooks.ts | 12 +++++--- packages/@lwc/engine-core/src/framework/vm.ts | 8 +++--- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts index fc72a2d962..5bdf44f069 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts @@ -31,7 +31,11 @@ function isVNode(vnode: any): vnode is VNode { return vnode != null; } -function createKeyToOldIdx(children: VNodes, beginIdx: number, endIdx: number): KeyToIndexMap { +function createKeyToOldIdx( + children: Readonly, + beginIdx: number, + endIdx: number +): KeyToIndexMap { const map: KeyToIndexMap = {}; let j: number, key: Key | undefined, ch; // TODO [#1637]: simplify this by assuming that all vnodes has keys @@ -50,7 +54,7 @@ function createKeyToOldIdx(children: VNodes, beginIdx: number, endIdx: number): function addVnodes( parentElm: Node, before: Node | null, - vnodes: VNodes, + vnodes: Readonly, startIdx: number, endIdx: number ) { @@ -63,7 +67,12 @@ function addVnodes( } } -function removeVnodes(parentElm: Node, vnodes: VNodes, startIdx: number, endIdx: number): void { +function removeVnodes( + parentElm: Node, + vnodes: Readonly, + startIdx: number, + endIdx: number +): void { for (; startIdx <= endIdx; ++startIdx) { const ch = vnodes[startIdx]; // text nodes do not have logic associated to them @@ -73,7 +82,11 @@ function removeVnodes(parentElm: Node, vnodes: VNodes, startIdx: number, endIdx: } } -export function updateDynamicChildren(parentElm: Node, oldCh: VNodes, newCh: VNodes) { +export function updateDynamicChildren( + parentElm: Node, + oldCh: Readonly, + newCh: Readonly +) { let oldStartIdx = 0; let newStartIdx = 0; let oldEndIdx = oldCh.length - 1; @@ -139,7 +152,6 @@ export function updateDynamicChildren(parentElm: Node, oldCh: VNodes, newCh: VNo newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm!); } else { patchVnode(elmToMove, newStartVnode); - oldCh[idxInOld] = undefined as any; newStartVnode.hook.move(elmToMove, parentElm, oldStartVnode.elm!); } } @@ -164,7 +176,11 @@ export function updateDynamicChildren(parentElm: Node, oldCh: VNodes, newCh: VNo } } -export function updateStaticChildren(parentElm: Node, oldCh: VNodes, newCh: VNodes) { +export function updateStaticChildren( + parentElm: Node, + oldCh: Readonly, + newCh: Readonly +) { const oldChLength = oldCh.length; const newChLength = newCh.length; diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts index d2c45b7602..dc948dd8ce 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/types.ts @@ -21,8 +21,8 @@ export type VNodes = Array; export interface VNode { sel: string | undefined; - data: VNodeData; - children: VNodes | undefined; + data: Readonly; + children: Readonly | undefined; elm: Node | undefined; parentElm?: Element; text: string | undefined; @@ -33,8 +33,8 @@ export interface VNode { export interface VElement extends VNode { sel: string; - data: VElementData; - children: VNodes; + data: Readonly; + children: Readonly; elm: Element | undefined; text: undefined; key: Key; @@ -44,7 +44,7 @@ export interface VCustomElement extends VElement { mode: 'closed' | 'open'; ctor: any; // copy of the last allocated children. - aChildren?: VNodes; + aChildren?: Readonly; } export interface VText extends VNode { diff --git a/packages/@lwc/engine-core/src/framework/api.ts b/packages/@lwc/engine-core/src/framework/api.ts index 024fcd3822..d3585197cc 100644 --- a/packages/@lwc/engine-core/src/framework/api.ts +++ b/packages/@lwc/engine-core/src/framework/api.ts @@ -353,7 +353,7 @@ function addVNodeToChildLWC(vnode: VCustomElement) { } // [h]tml node -function h(sel: string, data: VElementData, children: VNodes): VElement { +function h(sel: string, data: Readonly, children: Readonly): VElement { const vmBeingRendered = getVMBeingRendered()!; if (process.env.NODE_ENV !== 'production') { assert.isTrue(isString(sel), `h() 1st argument sel must be a string.`); @@ -432,10 +432,10 @@ function ti(value: any): number { // [s]lot element node function s( slotName: string, - data: VElementData, - children: VNodes, + data: Readonly, + children: Readonly, slotset: SlotSet | undefined -): VElement | VNodes { +): VElement | Readonly { if (process.env.NODE_ENV !== 'production') { assert.isTrue(isString(slotName), `s() 1st argument slotName must be a string.`); assert.isTrue(isObject(data), `s() 2nd argument data must be an object.`); @@ -814,7 +814,7 @@ function dc( * - children that are produced by iteration * */ -function sc(vnodes: VNodes): VNodes { +function sc(vnodes: Readonly): Readonly { if (process.env.NODE_ENV !== 'production') { assert.isTrue(isArray(vnodes), 'sc() api can only work with arrays.'); } diff --git a/packages/@lwc/engine-core/src/framework/hooks.ts b/packages/@lwc/engine-core/src/framework/hooks.ts index 5388cdf7c9..732dfecec6 100644 --- a/packages/@lwc/engine-core/src/framework/hooks.ts +++ b/packages/@lwc/engine-core/src/framework/hooks.ts @@ -374,7 +374,11 @@ function throwHydrationError() { assert.fail('Server rendered elements do not match client side generated elements'); } -export function hydrateChildrenHook(elmChildren: NodeListOf, children: VNodes, vm?: VM) { +export function hydrateChildrenHook( + elmChildren: Readonly>, + children: Readonly, + vm?: VM +) { if (process.env.NODE_ENV !== 'production') { const filteredVNodes = ArrayFilter.call(children, (vnode) => !!vnode); @@ -448,14 +452,14 @@ export function removeElmHook(vnode: VElement) { } // Using a WeakMap instead of a WeakSet because this one works in IE11 :( -const FromIteration: WeakMap = new WeakMap(); +const FromIteration: WeakMap, 1> = new WeakMap(); // dynamic children means it was generated by an iteration // in a template, and will require a more complex diffing algo. -export function markAsDynamicChildren(children: VNodes) { +export function markAsDynamicChildren(children: Readonly) { FromIteration.set(children, 1); } -export function hasDynamicChildren(children: VNodes): boolean { +export function hasDynamicChildren(children: Readonly): boolean { return FromIteration.has(children); } diff --git a/packages/@lwc/engine-core/src/framework/vm.ts b/packages/@lwc/engine-core/src/framework/vm.ts index 6bef3c62a4..3f9f4929df 100644 --- a/packages/@lwc/engine-core/src/framework/vm.ts +++ b/packages/@lwc/engine-core/src/framework/vm.ts @@ -117,9 +117,9 @@ export interface VM { /** The component connection state. */ state: VMState; /** The list of VNodes associated with the shadow tree. */ - children: VNodes; + children: Readonly; /** The list of adopted children VNodes. */ - aChildren: VNodes; + aChildren: Readonly; /** The list of custom elements VNodes currently rendered in the shadow tree. We keep track of * those elements to efficiently unmount them when the parent component is disconnected without * having to traverse the VNode tree. */ @@ -634,7 +634,7 @@ function runLightChildNodesDisconnectedCallback(vm: VM) { * custom element itself will trigger the removal of anything slotted or anything * defined on its shadow. */ -function recursivelyDisconnectChildren(vnodes: VNodes) { +function recursivelyDisconnectChildren(vnodes: Readonly) { for (let i = 0, len = vnodes.length; i < len; i += 1) { const vnode: VCustomElement | VNode | null = vnodes[i]; if (!isNull(vnode) && isArray(vnode.children) && !isUndefined(vnode.elm)) { @@ -699,7 +699,7 @@ function getErrorBoundaryVM(vm: VM): VM | undefined { // slow path routine // NOTE: we should probably more this routine to the synthetic shadow folder // and get the allocation to be cached by in the elm instead of in the VM -export function allocateInSlot(vm: VM, children: VNodes) { +export function allocateInSlot(vm: VM, children: Readonly) { const { cmpSlots: oldSlots } = vm; const cmpSlots = (vm.cmpSlots = create(null)); for (let i = 0, len = children.length; i < len; i += 1) { From e8dac64d2fa84aa8162a0e0303297e17f3b9b09e Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 9 Dec 2021 13:31:45 -0800 Subject: [PATCH 14/15] fix: clone the oldCh array --- packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts b/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts index 5bdf44f069..93ab0e92d4 100644 --- a/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts +++ b/packages/@lwc/engine-core/src/3rdparty/snabbdom/snabbdom.ts @@ -152,6 +152,12 @@ export function updateDynamicChildren( newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm!); } else { patchVnode(elmToMove, newStartVnode); + // Delete the old child, but copy the array since it is read-only. + // The `oldCh` will be GC'ed after `updateDynamicChildren` is complete, + // so we only care about the `oldCh` object inside this function. + const oldChClone = [...oldCh]; + oldChClone[idxInOld] = undefined as any; + oldCh = oldChClone; newStartVnode.hook.move(elmToMove, parentElm, oldStartVnode.elm!); } } From 3e2ce7898d7a0fe2c0d99b77b4c0524d4ca478e0 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Mon, 3 Jan 2022 15:59:22 -0800 Subject: [PATCH 15/15] test: fix snapshot --- .../invalid-template-attribute/single-attribute/expected.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js index 5f99b1e8e2..f492d00435 100644 --- a/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js +++ b/packages/@lwc/template-compiler/src/__tests__/fixtures/parsing-errors/invalid-template-attribute/single-attribute/expected.js @@ -1,5 +1,5 @@ import { registerTemplate } from "lwc"; -const stc0 = [[]]; +const stc0 = []; function tmpl($api, $cmp, $slotset, $ctx) { const {} = $api; return stc0;