From ee2edae09f6e080ccc92703864a463e31b4bb3b3 Mon Sep 17 00:00:00 2001 From: jhefferman-sfdc <83669775+jhefferman-sfdc@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:48:59 -0700 Subject: [PATCH] fix(ssr): correctly render foreign namespace element closing tags (#4992) * fix: correctly render foreign element closing tags * fix: properly handle scoped class for void and foreign elements * fix: address review comments * fix: remove math example for now * fix: ignore UNKNOWN_HTML_TAG_IN_TEMPLATE warning to allow for MathML test * fix: update tag warning suppression to reference issue * fix: simpler MathML example --- .../src/__tests__/fixtures.spec.ts | 4 +- .../fixtures/render-correct-tags/error.txt | 0 .../render-correct-tags/expected.html | 39 +++++++++++++++++++ .../fixtures/render-correct-tags/index.js | 3 ++ .../modules/x/elements/elements.html | 30 ++++++++++++++ .../modules/x/elements/elements.js | 5 +++ .../modules/x/elements/elements.scoped.css | 3 ++ .../src/__tests__/utils/expected-failures.ts | 2 - .../compile-template/transformers/element.ts | 14 +++---- 9 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/error.txt create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/expected.html create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/index.js create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.html create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.js create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.scoped.css diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts b/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts index 3c542787c5..0889ac7a4a 100755 --- a/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts +++ b/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts @@ -80,7 +80,9 @@ async function compileFixture({ // IGNORED_SLOT_ATTRIBUTE_IN_CHILD is fine; it is used in some of these tests message.includes('LWC1201') || message.includes('-h-t-m-l') || - code === 'CIRCULAR_DEPENDENCY'; + code === 'CIRCULAR_DEPENDENCY' || + // TODO [#5010]: template-compiler -> index -> validateElement generates UNKNOWN_HTML_TAG_IN_TEMPLATE for MathML elements + message.includes('LWC1123'); if (!shouldIgnoreWarning) { throw new Error(message); } diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/error.txt b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/error.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/expected.html new file mode 100644 index 0000000000..862326ccfa --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/expected.html @@ -0,0 +1,39 @@ + + + \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/index.js b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/index.js new file mode 100644 index 0000000000..99eaa6cf88 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/index.js @@ -0,0 +1,3 @@ +export const tagName = 'x-elements'; +export { default } from 'x/elements'; +export * from 'x/elements'; diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.html b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.html new file mode 100644 index 0000000000..00c96652f4 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.html @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.js b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.js new file mode 100644 index 0000000000..c9952ab5c6 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.js @@ -0,0 +1,5 @@ +import { LightningElement, api } from 'lwc'; + +export default class extends LightningElement { + @api foreignNamespaceInnerHtml = ''; +} diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.scoped.css b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.scoped.css new file mode 100644 index 0000000000..dd8d0c84a6 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/render-correct-tags/modules/x/elements/elements.scoped.css @@ -0,0 +1,3 @@ +:host { + background: blue; +} diff --git a/packages/@lwc/ssr-compiler/src/__tests__/utils/expected-failures.ts b/packages/@lwc/ssr-compiler/src/__tests__/utils/expected-failures.ts index f0c45d0a3d..6902462327 100644 --- a/packages/@lwc/ssr-compiler/src/__tests__/utils/expected-failures.ts +++ b/packages/@lwc/ssr-compiler/src/__tests__/utils/expected-failures.ts @@ -14,7 +14,6 @@ export const expectedFailures = new Set([ 'attribute-component-global-html/index.js', 'attribute-global-html/as-component-prop/undeclared/index.js', 'attribute-global-html/as-component-prop/without-@api/index.js', - 'attribute-namespace/index.js', 'attribute-style/basic/index.js', 'attribute-style/dynamic/index.js', 'exports/component-as-default/index.js', @@ -32,7 +31,6 @@ export const expectedFailures = new Set([ 'superclass/render-in-superclass/no-template-in-subclass/index.js', 'superclass/render-in-superclass/unused-default-in-subclass/index.js', 'superclass/render-in-superclass/unused-default-in-superclass/index.js', - 'svgs/index.js', 'wire/errors/throws-on-computed-key/index.js', 'wire/errors/throws-when-colliding-prop-then-method/index.js', 'wire/errors/throws-when-computed-prop-is-expression/index.js', diff --git a/packages/@lwc/ssr-compiler/src/compile-template/transformers/element.ts b/packages/@lwc/ssr-compiler/src/compile-template/transformers/element.ts index 7c39a30d1a..b41fd77360 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/transformers/element.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/transformers/element.ts @@ -227,10 +227,6 @@ export const Element: Transformer = fu return result; }); - if (isVoidElement(node.name, HTML_NAMESPACE)) { - return [bYield(b.literal(`<${node.name}`)), ...yieldAttrsAndProps, bYield(b.literal(`>`))]; - } - let childContent: EsStatement[]; // An element can have children or lwc:inner-html, but not both // If it has both, the template compiler will throw an error before reaching here @@ -246,13 +242,17 @@ export const Element: Transformer = fu childContent = []; } + const isForeignSelfClosingElement = + node.namespace !== HTML_NAMESPACE && childContent.length === 0; + const isSelfClosingElement = + isVoidElement(node.name, HTML_NAMESPACE) || isForeignSelfClosingElement; + return [ bYield(b.literal(`<${node.name}`)), // If we haven't already prefixed the scope token to an existing class, add an explicit class here ...(hasClassAttribute ? [] : [bConditionallyYieldScopeTokenClass()]), ...yieldAttrsAndProps, - bYield(b.literal(`>`)), - ...childContent, - bYield(b.literal(``)), + bYield(b.literal(isForeignSelfClosingElement ? `/>` : `>`)), + ...(isSelfClosingElement ? [] : [...childContent, bYield(b.literal(``))]), ].filter(Boolean); };